From d0011f3318426382237e30c68254c4fe7eb03fce Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Tue, 7 Mar 2006 21:26:37 +0000 Subject: [PATCH] Compositing workflow goodie; each 'render result' node now has a button option to re-render that specific node. Also works for nodes using other scenes. --- .../blenkernel/intern/node_composite.c | 15 ++--- .../render/extern/include/RE_pipeline.h | 12 ++-- .../blender/render/intern/source/pipeline.c | 52 +++++++++++----- source/blender/src/buttons_scene.c | 1 + source/blender/src/drawimage.c | 1 + source/blender/src/drawnode.c | 11 +++- source/blender/src/editnode.c | 60 +++++++++++++++++-- source/blender/src/renderwin.c | 37 ++++++------ source/blender/src/writeimage.c | 4 +- 9 files changed, 136 insertions(+), 57 deletions(-) diff --git a/source/blender/blenkernel/intern/node_composite.c b/source/blender/blenkernel/intern/node_composite.c index 9b0acebbc88..1eebe1c2510 100644 --- a/source/blender/blenkernel/intern/node_composite.c +++ b/source/blender/blenkernel/intern/node_composite.c @@ -599,7 +599,7 @@ static void node_composit_exec_composite(void *data, bNode *node, bNodeStack **i if(node->flag & NODE_DO_OUTPUT) { /* only one works on out */ RenderData *rd= data; if(rd->scemode & R_DOCOMP) { - RenderResult *rr= RE_GetResult(RE_GetRender("Render")); + RenderResult *rr= RE_GetResult(RE_GetRender(G.scene->id.name)); if(rr) { CompBuf *outbuf, *zbuf=NULL; @@ -917,16 +917,16 @@ static CompBuf *compbuf_from_pass(RenderData *rd, RenderLayer *rl, int rectx, in static void node_composit_exec_rresult(void *data, bNode *node, bNodeStack **in, bNodeStack **out) { + Scene *sce= node->id?(Scene *)node->id:G.scene; RenderData *rd= data; RenderResult *rr; - if(node->id && node->id!=&G.scene->id) - rr= RE_GetResult(RE_GetRender(node->id->name+2)); - else - rr= RE_GetResult(RE_GetRender("Render")); + rr= RE_GetResult(RE_GetRender(sce->id.name)); if(rr) { - RenderLayer *rl= BLI_findlink(&rr->layers, node->custom1); + SceneRenderLayer *srl= BLI_findlink(&sce->r.layers, node->custom1); + RenderLayer *rl= RE_GetRenderLayer(rr, srl->name); + if(rl) { CompBuf *stackbuf; @@ -969,10 +969,11 @@ static void node_composit_exec_rresult(void *data, bNode *node, bNodeStack **in, } /* custom1 = render layer in use */ +/* custom2 = re-render tag */ static bNodeType cmp_node_rresult= { /* type code */ CMP_NODE_R_RESULT, /* name */ "Render Result", - /* width+range */ 120, 80, 300, + /* width+range */ 150, 100, 300, /* class+opts */ NODE_CLASS_INPUT, NODE_PREVIEW|NODE_OPTIONS, /* input sock */ NULL, /* output sock */ cmp_node_rresult_out, diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h index 9412c4cb6a8..af39bd8dd1c 100644 --- a/source/blender/render/extern/include/RE_pipeline.h +++ b/source/blender/render/extern/include/RE_pipeline.h @@ -128,11 +128,12 @@ void RE_FreeRender (struct Render *re); void RE_FreeAllRender (void); /* get results and statistics */ -RenderResult *RE_GetResult(struct Render *re); -void RE_GetResultImage(struct Render *re, RenderResult *rr); -RenderStats *RE_GetStats(struct Render *re); +struct RenderResult *RE_GetResult(struct Render *re); +void RE_GetResultImage(struct Render *re, struct RenderResult *rr); +struct RenderStats *RE_GetStats(struct Render *re); void RE_ResultGet32(struct Render *re, unsigned int *rect); -float *RE_RenderLayerGetPass(RenderLayer *rl, int passtype); +struct RenderLayer *RE_GetRenderLayer(struct RenderResult *rr, const char *name); +float *RE_RenderLayerGetPass(struct RenderLayer *rl, int passtype); /* obligatory initialize call, disprect is optional */ void RE_InitState (struct Render *re, struct RenderData *rd, int winx, int winy, rcti *disprect); @@ -162,6 +163,9 @@ void RE_TileProcessor(struct Render *re, int firsttile); void RE_BlenderFrame(struct Render *re, struct Scene *scene, int frame); void RE_BlenderAnim(struct Render *re, struct Scene *scene, int sfra, int efra); +/* render a specific scene, with image size and disprect of Render *re */ +/* currently in use to render Composite Nodes */ +void RE_RenderScene(struct Render *re, struct Scene *sce, int cfra); /* display and event callbacks */ void RE_display_init_cb (struct Render *re, void (*f)(RenderResult *rr)); diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 71f52c7e50e..bb5aa13e36f 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -191,20 +191,25 @@ static void pop_render_result(Render *re) if(re->pushedresult) { if(re->pushedresult->rectx==re->result->rectx && re->pushedresult->recty==re->result->recty) { /* find which layer in pushedresult should be replaced */ - RenderLayer *rlpush= BLI_findlink(&re->pushedresult->layers, re->r.actlay); + SceneRenderLayer *srl; + RenderLayer *rlpush; RenderLayer *rl= re->result->layers.first; + int nr; - if(rlpush && rl) { - /* remove rendered layer */ - BLI_remlink(&re->result->layers, rl); - - /* insert it in the pushed result, and remove its counterpart */ - BLI_insertlinkbefore(&re->pushedresult->layers, rlpush, rl); - BLI_remlink(&re->pushedresult->layers, rlpush); - - /* add old layer in result, and swap results */ - BLI_addtail(&re->result->layers, rlpush); - SWAP(RenderResult *, re->result, re->pushedresult); + /* render result should be empty after this */ + BLI_remlink(&re->result->layers, rl); + + /* reconstruct render result layers */ + for(nr=0, srl= re->scene->r.layers.first; srl; srl= srl->next, nr++) { + if(nr==re->r.actlay) + BLI_addtail(&re->result->layers, rl); + else { + rlpush= RE_GetRenderLayer(re->pushedresult, srl->name); + if(rlpush) { + BLI_remlink(&re->pushedresult->layers, rlpush); + BLI_addtail(&re->result->layers, rlpush); + } + } } } @@ -310,6 +315,17 @@ float *RE_RenderLayerGetPass(RenderLayer *rl, int passtype) return NULL; } +RenderLayer *RE_GetRenderLayer(RenderResult *rr, const char *name) +{ + RenderLayer *rl; + + if(rr==NULL) return NULL; + + for(rl= rr->layers.first; rl; rl= rl->next) + if(strncmp(rl->name, name, RE_MAXNAME)==0) + return rl; + return NULL; +} /* called by main render as well for parts */ /* will read info from Render *re to define layers */ @@ -1175,9 +1191,12 @@ static void do_render_fields(Render *re) } -static void do_render_scene_node(Render *re, Scene *sce, int cfra) +/* within context of current Render *re, render another scene. + it uses current render image size and disprect, but doesn't execute composite +*/ +void RE_RenderScene(Render *re, Scene *sce, int cfra) { - Render *resc= RE_NewRender(sce->id.name+2); + Render *resc= RE_NewRender(sce->id.name); sce->r.cfra= cfra; @@ -1236,7 +1255,7 @@ static void ntree_render_scenes(Render *re) if(node->type==CMP_NODE_R_RESULT) { if(node->id && node->id != (ID *)re->scene) { if(node->id->flag & LIB_DOIT) { - do_render_scene_node(re, (Scene *)node->id, cfra); + RE_RenderScene(re, (Scene *)node->id, cfra); node->id->flag &= ~LIB_DOIT; } } @@ -1314,7 +1333,8 @@ static void do_render_final(Render *re) if(re->r.scemode & R_DOCOMP) { /* checks if there are render-result nodes that need scene */ - ntree_render_scenes(re); + if((re->r.scemode & R_SINGLE_LAYER)==0) + ntree_render_scenes(re); if(!re->test_break()) { ntree->stats_draw= render_composit_stats; diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c index 7760d8390c3..778a0aa88d6 100644 --- a/source/blender/src/buttons_scene.c +++ b/source/blender/src/buttons_scene.c @@ -1777,6 +1777,7 @@ static void rename_scene_layer_func(void *srl_v, void *unused_v) } } } + allqueue(REDRAWBUTSSCENE, 0); allqueue(REDRAWNODE, 0); } diff --git a/source/blender/src/drawimage.c b/source/blender/src/drawimage.c index 8dd2a624afc..9826481284d 100644 --- a/source/blender/src/drawimage.c +++ b/source/blender/src/drawimage.c @@ -1325,6 +1325,7 @@ static void sima_draw_zbuffloat_pixels(float x1, float y1, int rectx, int recty, else { bias= 0.1f; scale= 0.01f; + clipend= 100.0f; } rectf= MEM_mallocN(rectx*recty*4, "temp"); diff --git a/source/blender/src/drawnode.c b/source/blender/src/drawnode.c index cb57f1c889f..58e08c3f87c 100644 --- a/source/blender/src/drawnode.c +++ b/source/blender/src/drawnode.c @@ -817,15 +817,20 @@ static int node_composit_buts_renderresult(uiBlock *block, bNodeTree *ntree, bNo strp= scene_layer_menu(node->id?(Scene *)node->id:G.scene); if(node->id) bt= uiDefIconTextButS(block, MENU, B_NODE_EXEC+node->nr, ICON_SCENE_DEHLT, strp, - butr->xmin+20, butr->ymin, (butr->xmax-butr->xmin)-20, 19, + butr->xmin+20, butr->ymin, (butr->xmax-butr->xmin)-40, 19, &node->custom1, 0, 0, 0, 0, "Choose Render Layer"); else bt= uiDefButS(block, MENU, B_NODE_EXEC+node->nr, strp, - butr->xmin+20, butr->ymin, (butr->xmax-butr->xmin)-20, 19, + butr->xmin+20, butr->ymin, (butr->xmax-butr->xmin)-40, 19, &node->custom1, 0, 0, 0, 0, "Choose Render Layer"); - uiButSetFunc(bt, set_render_result_title, node, NULL); MEM_freeN(strp); + + /* re-render */ + bt= uiDefIconButS(block, TOG, B_NODE_EXEC+node->nr, ICON_SCENE, + butr->xmax-20, butr->ymin, 20, 19, + &node->custom2, 0, 0, 0, 0, "Re-render this Layer"); + } return 19; } diff --git a/source/blender/src/editnode.c b/source/blender/src/editnode.c index 91359e5d158..2b42faec607 100644 --- a/source/blender/src/editnode.c +++ b/source/blender/src/editnode.c @@ -51,6 +51,7 @@ #include "BKE_main.h" #include "BKE_node.h" #include "BKE_material.h" +#include "BKE_scene.h" #include "BKE_utildefines.h" #include "BIF_editview.h" @@ -76,6 +77,8 @@ #include "BDR_editobject.h" +#include "RE_pipeline.h" + #include "blendef.h" #include "butspace.h" #include "PIL_time.h" @@ -147,16 +150,15 @@ static void snode_handle_recalc(SpaceNode *snode) ntreeCompositExecTree(snode->nodetree, &G.scene->r, 1); /* 1 is do_previews */ + snode->nodetree->timecursor= NULL; 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; - waitcursor(0); } } } @@ -209,6 +211,47 @@ static bNode *snode_get_editgroup(SpaceNode *snode) return gnode; } +/* node has to be of type render result */ +/* is a bit clumsy copying renderdata here... scene nodes use render size of current render */ +static void composite_node_render(SpaceNode *snode, bNode *node) +{ + RenderData rd; + Scene *scene= NULL; + int scemode, actlay; + + /* the button press won't show up otherwise, button hilites disabled */ + force_draw(0); + + if(node->id && node->id!=(ID *)G.scene) { + scene= G.scene; + set_scene_bg((Scene *)node->id); + rd= G.scene->r; + G.scene->r.xsch= scene->r.xsch; + G.scene->r.ysch= scene->r.ysch; + G.scene->r.size= scene->r.size; + G.scene->r.mode &= ~(R_BORDER|R_DOCOMP); + G.scene->r.mode |= scene->r.mode & R_BORDER; + G.scene->r.border= scene->r.border; + } + + scemode= G.scene->r.scemode; + actlay= G.scene->r.actlay; + + G.scene->r.scemode |= R_SINGLE_LAYER; + G.scene->r.actlay= node->custom1; + + BIF_do_render(0); + + G.scene->r.scemode= scemode; + G.scene->r.actlay= actlay; + + node->custom2= 0; + + if(scene) { + G.scene->r= rd; + set_scene_bg(scene); + } +} static void composit_node_event(SpaceNode *snode, short event) { @@ -238,9 +281,14 @@ static void composit_node_event(SpaceNode *snode, short event) bNode *node= BLI_findlink(&snode->edittree->nodes, event-B_NODE_EXEC); if(node) { NodeTagChanged(snode->edittree, node); - node= snode_get_editgroup(snode); - if(node) - NodeTagIDChanged(snode->nodetree, node->id); + /* not the best implementation of the world... but we need it to work now :) */ + if(node->type==CMP_NODE_R_RESULT && node->custom2) + composite_node_render(snode, node); + else { + node= snode_get_editgroup(snode); + if(node) + NodeTagIDChanged(snode->nodetree, node->id); + } snode_handle_recalc(snode); } } diff --git a/source/blender/src/renderwin.c b/source/blender/src/renderwin.c index 56fb2374ef9..7ba91350327 100644 --- a/source/blender/src/renderwin.c +++ b/source/blender/src/renderwin.c @@ -337,7 +337,7 @@ static void renderwin_draw(RenderWin *rw, int just_clear) rres.rectf= rw->rectsparef; } else - RE_GetResultImage(RE_GetRender("Render"), &rres); + RE_GetResultImage(RE_GetRender(G.scene->id.name), &rres); if(rres.rectf) { @@ -395,7 +395,7 @@ static void renderwin_mouse_moved(RenderWin *rw) { RenderResult rres; - RE_GetResultImage(RE_GetRender("Render"), &rres); + RE_GetResultImage(RE_GetRender(G.scene->id.name), &rres); if (rw->flags & RW_FLAGS_PIXEL_EXAMINING) { int imgco[2], ofs=0; @@ -564,20 +564,20 @@ static void renderwin_handler(Window *win, void *user_data, short evt, short val renderwin_reset_view(rw); } else if (evt==F3KEY) { -// if(R.flag==0) { -// mainwindow_raise(); -// mainwindow_make_active(); -// rw->active= 0; -// areawinset(find_biggest_area()->win); -// BIF_save_rendered_image_fs(); -// } + if(G.rendering==0) { + mainwindow_raise(); + mainwindow_make_active(); + rw->active= 0; + areawinset(find_biggest_area()->win); + BIF_save_rendered_image_fs(0); + } } else if (evt==F11KEY) { BIF_toggle_render_display(); } else if (evt==F12KEY) { - /* if it's rendering, this flag is set */ -// if(R.flag==0) BIF_do_render(0); + if(G.rendering==0) + BIF_do_render(0); } } } @@ -991,7 +991,7 @@ static void end_test_break_callback() static void do_render(int anim) { - Render *re= RE_NewRender("Render"); + Render *re= RE_NewRender(G.scene->id.name); unsigned int lay= G.scene->lay; int scemode= G.scene->r.scemode; @@ -1009,7 +1009,6 @@ static void do_render(int anim) RE_stats_draw_cb(re, printrenderinfo_cb); if(render_win) window_set_cursor(render_win->win, CURSOR_WAIT); - waitcursor(1); if(G.obedit) exit_editmode(0); /* 0 = no free data */ @@ -1033,7 +1032,7 @@ static void do_render(int anim) G.scene->r.scemode= scemode; if(render_win) window_set_cursor(render_win->win, CURSOR_STD); - + free_filesel_spec(G.scene->r.pic); G.afbreek= 0; @@ -1052,7 +1051,7 @@ static void do_render(int anim) scene_update_for_newframe(G.scene, G.scene->lay); // no redraw needed, this restores to view as we left it - waitcursor(0); // waitcursor checks rendering R.flag... + waitcursor(0); } #if 0 @@ -1102,7 +1101,7 @@ static void renderwin_store_spare(void) if(render_win->rectsparef) MEM_freeN(render_win->rectsparef); render_win->rectsparef= NULL; - RE_GetResultImage(RE_GetRender("Render"), &rres); + RE_GetResultImage(RE_GetRender(G.scene->id.name), &rres); if(rres.rect32) render_win->rectspare= MEM_dupallocN(rres.rect32); @@ -1157,7 +1156,7 @@ void BIF_do_render(int anim) /* the RE_Render is only used to make sure we got the picture in the result */ void BIF_do_ogl_render(View3D *v3d, int anim) { - Render *re= RE_NewRender("Render"); + Render *re= RE_NewRender(G.scene->id.name); RenderResult *rr; int winx, winy; @@ -1229,7 +1228,7 @@ void BIF_swap_render_rects(void) render_win->storespare= 1; render_win->showspare ^= 1; - RE_GetResultImage(RE_GetRender("Render"), &rres); + RE_GetResultImage(RE_GetRender(G.scene->id.name), &rres); if(render_win->sparex!=rres.rectx || render_win->sparey!=rres.recty) { if(render_win->rectspare) MEM_freeN(render_win->rectspare); @@ -1280,7 +1279,7 @@ void BIF_toggle_render_display(void) } } else { - RenderResult *rr= RE_GetResult(RE_GetRender("Render")); + RenderResult *rr= RE_GetResult(RE_GetRender(G.scene->id.name)); if(rr) renderwin_init_display_cb(rr); } } diff --git a/source/blender/src/writeimage.c b/source/blender/src/writeimage.c index ae0717f6726..547e12a8a73 100644 --- a/source/blender/src/writeimage.c +++ b/source/blender/src/writeimage.c @@ -110,7 +110,7 @@ static void save_rendered_image_cb_real(char *name, int zbuf) RenderResult rres; ImBuf *ibuf; - RE_GetResultImage(RE_GetRender("Render"), &rres); + RE_GetResultImage(RE_GetRender(G.scene->id.name), &rres); waitcursor(1); /* from screen.c */ @@ -207,7 +207,7 @@ void save_image_filesel_str(char *str) /* calls fileselect if zbuf is set we are rendering the zbuffer */ void BIF_save_rendered_image_fs(int zbuf) { - RenderResult *rr= RE_GetResult(RE_GetRender("Render")); + RenderResult *rr= RE_GetResult(RE_GetRender(G.scene->id.name)); if(!rr) { error("No image rendered");