Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTon Roosendaal <ton@blender.org>2006-01-28 18:21:04 +0300
committerTon Roosendaal <ton@blender.org>2006-01-28 18:21:04 +0300
commit45c7b2c5c2bc20296a581e1b6a1cb3908f11732f (patch)
tree3c84b86ee52f12f5ae967791182ce71e003abee4 /source/blender/blenkernel
parent80bd3a1e9897044334d3384be27b52efc6541fef (diff)
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
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_node.h8
-rw-r--r--source/blender/blenkernel/intern/node.c197
-rw-r--r--source/blender/blenkernel/intern/node_composit.c39
-rw-r--r--source/blender/blenkernel/intern/scene.c3
4 files changed, 202 insertions, 45 deletions
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 622236a6264..f289de038d6 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -41,6 +41,7 @@ struct bNodeStack;
struct uiBlock;
struct rctf;
struct ListBase;
+struct RenderData;
#define SOCK_IN 1
#define SOCK_OUT 2
@@ -101,6 +102,7 @@ void ntreeSolveOrder(struct bNodeTree *ntree);
void ntreeBeginExecTree(struct bNodeTree *ntree);
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 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);
void nodeClearActiveID(struct bNodeTree *ntree, short idtype);
+void NodeTagChanged(struct bNodeTree *ntree, struct bNode *node);
+
/* ************** Groups ****************** */
struct bNode *nodeMakeGroupFromSelected(struct bNodeTree *ntree);
@@ -218,9 +222,9 @@ extern bNodeType *node_all_composit[];
/* API */
struct CompBuf;
-struct RenderData;
-void ntreeCompositExecTree(struct bNodeTree *ntree, struct RenderData *rd, int do_previews);
int ntreeCompositNeedsRender(struct bNodeTree *ntree);
+void ntreeCompositTagRender(struct bNodeTree *ntree);
+
void free_compbuf(struct CompBuf *cbuf); /* internal...*/
#endif
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index a1f0c4095e2..3e99f83a8f6 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -38,6 +38,7 @@
#include "BKE_blender.h"
#include "BKE_colortools.h"
#include "BKE_global.h"
+#include "BKE_image.h"
#include "BKE_library.h"
#include "BKE_main.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)
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;
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->ns.data= NULL;
+ }
if(nnode->id)
nnode->id->us++;
@@ -850,8 +853,10 @@ static void node_unlink_node(bNodeTree *ntree, bNode *node)
for(link= ntree->links.first; link; link= next) {
next= link->next;
- if(link->fromnode==node)
+ if(link->fromnode==node) {
lb= &node->outputs;
+ NodeTagChanged(ntree, link->tonode);
+ }
else if(link->tonode==node)
lb= &node->inputs;
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)
{
node_unlink_node(ntree, node);
@@ -877,6 +892,8 @@ void nodeFreeNode(bNodeTree *ntree, bNode *node)
if(node->id)
node->id->us--;
+ if(ntree->type==NTREE_COMPOSIT)
+ composit_free_sockets(node);
BLI_freelistN(&node->inputs);
BLI_freelistN(&node->outputs);
@@ -1207,6 +1224,22 @@ void ntreeSolveOrder(bNodeTree *ntree)
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 *********** */
/* if node->preview, then we assume the rect to exist */
@@ -1362,6 +1395,54 @@ static int ntree_begin_exec_tree(bNodeTree *ntree)
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 */
/* only root tree gets the stack, to enable instances to have own stack entries */
/* 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 */
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) {
bNodeSocket *sock;
for(sock= node->inputs.first; sock; sock= sock->next) {
@@ -1395,8 +1477,10 @@ void ntreeBeginExecTree(bNodeTree *ntree)
}
}
}
-
- ntree->stack1= MEM_dupallocN(ntree->stack);
+ if(ntree->type==NTREE_COMPOSIT)
+ composit_begin_exec(ntree);
+ else
+ ntree->stack1= MEM_dupallocN(ntree->stack);
}
ntree->init |= NTREE_EXEC_INIT;
@@ -1407,25 +1491,17 @@ void ntreeEndExecTree(bNodeTree *ntree)
if(ntree->init & NTREE_EXEC_INIT) {
- if(ntree->stack) {
-
- /* another callback candidate! */
- if(ntree->type==NTREE_COMPOSIT) {
- bNodeStack *ns;
- 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);
- }
+ /* another callback candidate! */
+ if(ntree->type==NTREE_COMPOSIT)
+ composit_end_exec(ntree);
+
+ if(ntree->stack)
MEM_freeN(ntree->stack);
- ntree->stack= NULL;
+ ntree->stack= NULL;
+
+ if(ntree->stack1)
MEM_freeN(ntree->stack1);
- ntree->stack1= NULL;
- }
+ ntree->stack1= NULL;
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();
+
+}
+
diff --git a/source/blender/blenkernel/intern/node_composit.c b/source/blender/blenkernel/intern/node_composit.c
index 93e5bb8a902..bcb3e9e600d 100644
--- a/source/blender/blenkernel/intern/node_composit.c
+++ b/source/blender/blenkernel/intern/node_composit.c
@@ -81,9 +81,9 @@ static CompBuf *alloc_compbuf(int sizex, int sizey, int type, int alloc)
cbuf->type= type;
if(alloc) {
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
- 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->disprect.xmin= 0;
@@ -101,6 +101,14 @@ void free_compbuf(CompBuf *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
/* 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)
@@ -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->rect= ima->ibuf->rect_float;
-
+
/* when no alpha, we can simply copy */
if(in[1]->data==NULL)
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)
{
RenderResult *rr= RE_GetResult(RE_GetRender("Render"));
+
if(rr) {
RenderLayer *rl= BLI_findlink(&rr->layers, node->custom1);
if(rl) {
@@ -1815,7 +1824,7 @@ bNodeType *node_all_composit[]= {
NULL
};
-/* ******************* execute and parse ************ */
+/* ******************* parse ************ */
/* helper call to detect if theres a render-result node */
int ntreeCompositNeedsRender(bNodeTree *ntree)
@@ -1831,23 +1840,15 @@ int ntreeCompositNeedsRender(bNodeTree *ntree)
return 0;
}
-/* note; if called without preview, and previews exist, they get updated */
-/* render calls it without previews, works nicer for bg render */
-void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
+void ntreeCompositTagRender(bNodeTree *ntree)
{
- if(ntree==NULL) return;
-
- if(do_preview)
- ntreeInitPreview(ntree, 0, 0);
-
- ntreeBeginExecTree(ntree);
-
- /* allocate composit data? */
-
- ntreeExecTree(ntree, rd, 0); /* threads */
+ bNode *node;
- ntreeEndExecTree(ntree);
+ if(ntree==NULL) return;
- free_unused_animimages();
+ for(node= ntree->nodes.first; node; node= node->next) {
+ if(node->type==CMP_NODE_R_RESULT)
+ NodeTagChanged(ntree, node);
+ }
}
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 1a42c299335..492c1b1c264 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -494,7 +494,8 @@ void scene_add_render_layer(Scene *sce)
srl= MEM_callocN(sizeof(SceneRenderLayer), "new render layer");
sprintf(srl->name, "%d RenderLayer", tot);
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->layflag= 0x7FFF; /* solid ztra halo strand */
srl->passflag= SCE_PASS_COMBINED|SCE_PASS_Z;