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.
This commit is contained in:
Ton Roosendaal 2006-03-07 21:26:37 +00:00
parent 48f6e94036
commit d0011f3318
9 changed files with 136 additions and 57 deletions

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

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

@ -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);
/* render result should be empty after this */
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);
/* 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;

@ -1777,6 +1777,7 @@ static void rename_scene_layer_func(void *srl_v, void *unused_v)
}
}
}
allqueue(REDRAWBUTSSCENE, 0);
allqueue(REDRAWNODE, 0);
}

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

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

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

@ -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 */
@ -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);
}
}

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