From 06e6011ae97f58b718f7d2ca45fd03814a345078 Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Wed, 6 Jan 2010 00:09:07 +0000 Subject: [PATCH] Restored Compositor 're-render single layer' functionality (buttons on renderlayer comp nodes). This works with operator properties - if you pass the name of a scene and renderlayer to the screen.render operator, it will render that layer as a single layer re-render. --- source/blender/blenkernel/intern/sequencer.c | 2 +- .../blender/editors/render/render_preview.c | 4 +- source/blender/editors/screen/screen_ops.c | 29 +++- source/blender/editors/space_node/drawnode.c | 25 +++- source/blender/editors/space_node/node_edit.c | 43 ------ source/blender/makesrna/intern/rna_nodetree.c | 6 - .../render/extern/include/RE_pipeline.h | 5 +- .../render/intern/source/convertblender.c | 2 +- source/blender/render/intern/source/envmap.c | 2 +- .../blender/render/intern/source/pipeline.c | 139 +++++++++--------- 10 files changed, 125 insertions(+), 132 deletions(-) diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 767834159b2..771fd6a109b 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -2094,7 +2094,7 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int doseq= scene->r.scemode & R_DOSEQ; scene->r.scemode &= ~R_DOSEQ; - RE_BlenderFrame(re, sce, + RE_BlenderFrame(re, sce, NULL, seq->sfra+se->nr+seq->anim_startofs); if(rendering) diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 74e1cca5579..03fe772c09b 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -717,7 +717,7 @@ void BIF_view3d_previewrender(Scene *scene, ScrArea *sa) rdata.layers.first= rdata.layers.last= NULL; rdata.renderer= R_INTERN; - RE_InitState(re, NULL, &rdata, sa->winx, sa->winy, &ri->disprect); + RE_InitState(re, NULL, &rdata, NULL, sa->winx, sa->winy, &ri->disprect); if(orth) RE_SetOrtho(re, &viewplane, clipsta, clipend); @@ -923,7 +923,7 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs else sizex= sp->sizex; /* allocates or re-uses render result */ - RE_InitState(re, NULL, &sce->r, sizex, sp->sizey, NULL); + RE_InitState(re, NULL, &sce->r, NULL, sizex, sp->sizey, NULL); /* callbacs are cleared on GetRender() */ if(sp->pr_method==PR_BUTS_RENDER) { diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 29d202e8631..1e49f6502c7 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -2812,7 +2812,7 @@ static int screen_render_exec(bContext *C, wmOperator *op) if(RNA_boolean_get(op->ptr, "animation")) RE_BlenderAnim(re, scene, scene->r.sfra, scene->r.efra, scene->r.frame_step, op->reports); else - RE_BlenderFrame(re, scene, scene->r.cfra); + RE_BlenderFrame(re, scene, NULL, scene->r.cfra); // no redraw needed, we leave state as we entered it ED_update_for_newframe(C, 1); @@ -2826,6 +2826,7 @@ typedef struct RenderJob { Scene *scene; Render *re; wmWindow *win; + SceneRenderLayer *srl; int anim; Image *image; ImageUser iuser; @@ -3038,7 +3039,7 @@ static void render_startjob(void *rjv, short *stop, short *do_update) if(rj->anim) RE_BlenderAnim(rj->re, rj->scene, rj->scene->r.sfra, rj->scene->r.efra, rj->scene->r.frame_step, rj->reports); else - RE_BlenderFrame(rj->re, rj->scene, rj->scene->r.cfra); + RE_BlenderFrame(rj->re, rj->scene, rj->srl, rj->scene->r.cfra); } /* called by render, check job 'stop' value or the global */ @@ -3074,6 +3075,7 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event) { /* new render clears all callbacks */ Scene *scene= CTX_data_scene(C); + SceneRenderLayer *srl=NULL; Render *re; wmJob *steve; RenderJob *rj; @@ -3102,10 +3104,29 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event) /* ensure at least 1 area shows result */ screen_set_image_output(C, event->x, event->y); + /* single layer re-render */ + if(RNA_property_is_set(op->ptr, "layer")) { + SceneRenderLayer *rl; + Scene *scn; + char scene_name[19], rl_name[RE_MAXNAME]; + + RNA_string_get(op->ptr, "layer", rl_name); + RNA_string_get(op->ptr, "scene", scene_name); + + scn = (Scene *)BLI_findstring(&CTX_data_main(C)->scene, scene_name, offsetof(ID, name) + 2); + rl = (SceneRenderLayer *)BLI_findstring(&scene->r.layers, rl_name, offsetof(SceneRenderLayer, name)); + + if (scn && rl) { + scene = scn; + srl = rl; + } + } + /* job custom data */ rj= MEM_callocN(sizeof(RenderJob), "render job"); rj->scene= scene; rj->win= CTX_wm_window(C); + rj->srl = srl; rj->anim= RNA_boolean_get(op->ptr, "animation"); rj->iuser.scene= scene; rj->iuser.ok= 1; @@ -3167,6 +3188,8 @@ static void SCREEN_OT_render(wmOperatorType *ot) ot->poll= ED_operator_screenactive; RNA_def_boolean(ot->srna, "animation", 0, "Animation", ""); + RNA_def_string(ot->srna, "layer", "", RE_MAXNAME, "Render Layer", "Single render layer to re-render"); + RNA_def_string(ot->srna, "scene", "", 19, "Scene", "Re-render single layer in this scene"); } /* ****************************** opengl render *************************** */ @@ -3289,7 +3312,7 @@ static int screen_opengl_render_init(bContext *C, wmOperator *op) /* create render and render result */ oglrender->re= RE_NewRender(scene->id.name); - RE_InitState(oglrender->re, NULL, &scene->r, sizex, sizey, NULL); + RE_InitState(oglrender->re, NULL, &scene->r, NULL, sizex, sizey, NULL); rr= RE_AcquireResultWrite(oglrender->re); if(rr->rectf==NULL) diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 4c634c20440..4f6b43337db 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -545,16 +545,33 @@ static void node_composit_buts_image(uiLayout *layout, bContext *C, PointerRNA * static void node_composit_buts_renderlayers(uiLayout *layout, bContext *C, PointerRNA *ptr) { bNode *node= ptr->data; - uiLayout *col; - + uiLayout *col, *row; + PointerRNA op_ptr; + PointerRNA scn_ptr; + PropertyRNA *prop; + const char *layer_name; + char scene_name[19]; + uiTemplateID(layout, C, ptr, "scene", NULL, NULL, NULL); if(!node->id) return; col= uiLayoutColumn(layout, 0); - uiItemR(col, "", 0, ptr, "layer", 0); + row = uiLayoutRow(col, 0); + uiItemR(row, "", 0, ptr, "layer", 0); - /* XXX Missing 're-render this layer' button - needs completely new implementation */ + prop = RNA_struct_find_property(ptr, "layer"); + if (!(RNA_property_enum_identifier(C, ptr, prop, RNA_property_enum_get(ptr, prop), &layer_name))) + return; + + scn_ptr = RNA_pointer_get(ptr, "scene"); + RNA_string_get(&scn_ptr, "name", scene_name); + + WM_operator_properties_create(&op_ptr, "SCREEN_OT_render"); + RNA_string_set(&op_ptr, "layer", layer_name); + RNA_string_set(&op_ptr, "scene", scene_name); + uiItemFullO(row, "", ICON_RENDER_STILL, "SCREEN_OT_render", op_ptr.data, WM_OP_INVOKE_DEFAULT, 0); + } diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index 05926782a0d..7f291539fcb 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -345,49 +345,6 @@ bNode *node_tree_get_editgroup(bNodeTree *nodetree) #if 0 -/* node has to be of type 'render layers' */ -/* 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; - G.scene->r.cfra= scene->r.cfra; - } - - scemode= G.scene->r.scemode; - actlay= G.scene->r.actlay; - - G.scene->r.scemode |= R_SINGLE_LAYER|R_COMP_RERENDER; - 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) { diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index d1e73d6add3..9922f099cd5 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -1077,12 +1077,6 @@ static void def_cmp_render_layers(StructRNA *srna) RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_Node_scene_layer_itemf"); RNA_def_property_ui_text(prop, "Layer", ""); RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); - - /* TODO: comments indicate this might be a hack */ - prop = RNA_def_property(srna, "re_render", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "custom2", 1); - RNA_def_property_ui_text(prop, "Re-render", ""); - RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); } static void def_cmp_output_file(StructRNA *srna) diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h index 76e3e002513..a90220b9c1b 100644 --- a/source/blender/render/extern/include/RE_pipeline.h +++ b/source/blender/render/extern/include/RE_pipeline.h @@ -46,6 +46,7 @@ struct RenderEngineType; struct RenderResult; struct ReportList; struct Scene; +struct SceneRenderLayer; /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* this include is what is exposed of render to outside world */ @@ -169,7 +170,7 @@ 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 Render *source, struct RenderData *rd, int winx, int winy, rcti *disprect); +void RE_InitState (struct Render *re, struct Render *source, struct RenderData *rd, struct SceneRenderLayer *srl, int winx, int winy, rcti *disprect); /* use this to change disprect of active render */ void RE_SetDispRect (struct Render *re, rcti *disprect); @@ -200,7 +201,7 @@ void RE_init_threadcount(Render *re); void RE_TileProcessor(struct Render *re, int firsttile, int threaded); /* only RE_NewRender() needed, main Blender render calls */ -void RE_BlenderFrame(struct Render *re, struct Scene *scene, int frame); +void RE_BlenderFrame(struct Render *re, struct Scene *scene, struct SceneRenderLayer *srl, int frame); void RE_BlenderAnim(struct Render *re, struct Scene *scene, int sfra, int efra, int tfra, struct ReportList *reports); void RE_ReadRenderResult(struct Scene *scene, struct Scene *scenode); diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 899ddbe4fb4..63782223c33 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -5605,7 +5605,7 @@ void RE_make_sticky(Scene *scene, View3D *v3d) } re= RE_NewRender("_make sticky_"); - RE_InitState(re, NULL, &scene->r, scene->r.xsch, scene->r.ysch, NULL); + RE_InitState(re, NULL, &scene->r, NULL, scene->r.xsch, scene->r.ysch, NULL); /* use renderdata and camera to set viewplane */ RE_SetCamera(re, scene->camera); diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c index 323eb6a9500..7ba860955b3 100644 --- a/source/blender/render/intern/source/envmap.c +++ b/source/blender/render/intern/source/envmap.c @@ -127,7 +127,7 @@ static Render *envmap_render_copy(Render *re, EnvMap *env) envre->r.size= 100; envre->r.yasp= envre->r.xasp= 1; - RE_InitState(envre, NULL, &envre->r, cuberes, cuberes, NULL); + RE_InitState(envre, NULL, &envre->r, NULL, cuberes, cuberes, NULL); envre->scene= re->scene; /* unsure about this... */ /* view stuff in env render */ diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index e2b290f655b..ff1f6541f06 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -1114,13 +1114,6 @@ Render *RE_NewRender(const char *name) BLI_rw_mutex_init(&re->resultmutex); } - /* prevent UI to draw old results */ - BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); - RE_FreeRenderResult(re->result); - re->result= NULL; - re->result_ok= 0; - BLI_rw_mutex_unlock(&re->resultmutex); - /* set default empty callbacks */ re->display_init= result_nothing; re->display_clear= result_nothing; @@ -1169,7 +1162,7 @@ void RE_FreeAllRender(void) /* what doesn't change during entire render sequence */ /* disprect is optional, if NULL it assumes full window render */ -void RE_InitState(Render *re, Render *source, RenderData *rd, int winx, int winy, rcti *disprect) +void RE_InitState(Render *re, Render *source, RenderData *rd, SceneRenderLayer *srl, int winx, int winy, rcti *disprect) { re->ok= TRUE; /* maybe flag */ @@ -1195,62 +1188,70 @@ void RE_InitState(Render *re, Render *source, RenderData *rd, int winx, int winy (re->rectx < 16 || re->recty < 16) )) { re->error(re->erh, "Image too small"); re->ok= 0; + return; + } + +#ifdef WITH_OPENEXR + if(re->r.scemode & R_FULL_SAMPLE) + re->r.scemode |= R_EXR_TILE_FILE; /* enable automatic */ +#else + /* can't do this without openexr support */ + re->r.scemode &= ~(R_EXR_TILE_FILE|R_FULL_SAMPLE); +#endif + + /* fullsample wants uniform osa levels */ + if(source && (re->r.scemode & R_FULL_SAMPLE)) { + /* but, if source has no full sample we disable it */ + if((source->r.scemode & R_FULL_SAMPLE)==0) + re->r.scemode &= ~R_FULL_SAMPLE; + else + re->r.osa= re->osa= source->osa; } else { -#ifdef WITH_OPENEXR - if(re->r.scemode & R_FULL_SAMPLE) - re->r.scemode |= R_EXR_TILE_FILE; /* enable automatic */ -#else - /* can't do this without openexr support */ - re->r.scemode &= ~(R_EXR_TILE_FILE|R_FULL_SAMPLE); -#endif - - /* fullsample wants uniform osa levels */ - if(source && (re->r.scemode & R_FULL_SAMPLE)) { - /* but, if source has no full sample we disable it */ - if((source->r.scemode & R_FULL_SAMPLE)==0) - re->r.scemode &= ~R_FULL_SAMPLE; - else - re->r.osa= re->osa= source->osa; + /* check state variables, osa? */ + if(re->r.mode & (R_OSA)) { + re->osa= re->r.osa; + if(re->osa>16) re->osa= 16; } - else { - /* check state variables, osa? */ - if(re->r.mode & (R_OSA)) { - re->osa= re->r.osa; - if(re->osa>16) re->osa= 16; - } - else re->osa= 0; - } - - /* always call, checks for gamma, gamma tables and jitter too */ - make_sample_tables(re); - - /* if preview render, we try to keep old result */ - BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); - - if(re->r.scemode & R_PREVIEWBUTS) { - if(re->result && re->result->rectx==re->rectx && re->result->recty==re->recty); - else { - RE_FreeRenderResult(re->result); - re->result= NULL; - } - } - else { - - /* make empty render result, so display callbacks can initialize */ - RE_FreeRenderResult(re->result); - re->result= MEM_callocN(sizeof(RenderResult), "new render result"); - re->result->rectx= re->rectx; - re->result->recty= re->recty; - } - - BLI_rw_mutex_unlock(&re->resultmutex); - - /* we clip faces with a minimum of 2 pixel boundary outside of image border. see zbuf.c */ - re->clipcrop= 1.0f + 2.0f/(float)(re->winx>re->winy?re->winy:re->winx); - - RE_init_threadcount(re); + else re->osa= 0; } + + if (srl) { + int index = BLI_findindex(&re->r.layers, srl); + if (index != -1) { + re->r.actlay = index; + re->r.scemode |= (R_SINGLE_LAYER|R_COMP_RERENDER); + } + } + + /* always call, checks for gamma, gamma tables and jitter too */ + make_sample_tables(re); + + /* if preview render, we try to keep old result */ + BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); + + if(re->r.scemode & R_PREVIEWBUTS) { + if(re->result && re->result->rectx==re->rectx && re->result->recty==re->recty); + else { + RE_FreeRenderResult(re->result); + re->result= NULL; + } + } + else { + + /* make empty render result, so display callbacks can initialize */ + RE_FreeRenderResult(re->result); + re->result= MEM_callocN(sizeof(RenderResult), "new render result"); + re->result->rectx= re->rectx; + re->result->recty= re->recty; + } + + BLI_rw_mutex_unlock(&re->resultmutex); + + /* we clip faces with a minimum of 2 pixel boundary outside of image border. see zbuf.c */ + re->clipcrop= 1.0f + 2.0f/(float)(re->winx>re->winy?re->winy:re->winx); + + RE_init_threadcount(re); } /* part of external api, not called for regular render pipeline */ @@ -2156,7 +2157,7 @@ static void render_scene(Render *re, Scene *sce, int cfra) } /* initial setup */ - RE_InitState(resc, re, &sce->r, winx, winy, &re->disprect); + RE_InitState(resc, re, &sce->r, NULL, winx, winy, &re->disprect); /* still unsure entity this... */ resc->scene= sce; @@ -2668,7 +2669,7 @@ static void update_physics_cache(Render *re, Scene *scene, int anim_init) BKE_ptcache_make_cache(&baker); } /* evaluating scene options for general Blender render */ -static int render_initialize_from_scene(Render *re, Scene *scene, int anim, int anim_init) +static int render_initialize_from_scene(Render *re, Scene *scene, SceneRenderLayer *srl, int anim, int anim_init) { int winx, winy; rcti disprect; @@ -2715,10 +2716,10 @@ static int render_initialize_from_scene(Render *re, Scene *scene, int anim, int update_physics_cache(re, scene, anim_init); } - if(scene->r.scemode & R_SINGLE_LAYER) + if(srl || scene->r.scemode & R_SINGLE_LAYER) push_render_result(re); - RE_InitState(re, NULL, &scene->r, winx, winy, &disprect); + RE_InitState(re, NULL, &scene->r, srl, winx, winy, &disprect); if(!re->ok) /* if an error was printed, abort */ return 0; @@ -2735,7 +2736,7 @@ static int render_initialize_from_scene(Render *re, Scene *scene, int anim, int } /* general Blender frame render call */ -void RE_BlenderFrame(Render *re, Scene *scene, int frame) +void RE_BlenderFrame(Render *re, Scene *scene, SceneRenderLayer *srl, int frame) { /* ugly global still... is to prevent preview events and signal subsurfs etc to make full resol */ G.rendering= 1; @@ -2743,7 +2744,7 @@ void RE_BlenderFrame(Render *re, Scene *scene, int frame) scene->r.cfra= frame; - if(render_initialize_from_scene(re, scene, 0, 0)) { + if(render_initialize_from_scene(re, scene, srl, 0, 0)) { do_render_all_options(re); } @@ -2838,7 +2839,7 @@ void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra, int tfra, Repo int nfra; /* do not fully call for each frame, it initializes & pops output window */ - if(!render_initialize_from_scene(re, scene, 0, 1)) + if(!render_initialize_from_scene(re, scene, NULL, 0, 1)) return; /* ugly global still... is to prevent renderwin events and signal subsurfs etc to make full resol */ @@ -2872,7 +2873,7 @@ void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra, int tfra, Repo char name[FILE_MAX]; /* only border now, todo: camera lens. (ton) */ - render_initialize_from_scene(re, scene, 1, 0); + render_initialize_from_scene(re, scene, NULL, 1, 0); if(nfra!=scene->r.cfra) { /* @@ -2976,7 +2977,7 @@ void RE_ReadRenderResult(Scene *scene, Scene *scenode) re= RE_GetRender(scene->id.name); if(re==NULL) re= RE_NewRender(scene->id.name); - RE_InitState(re, NULL, &scene->r, winx, winy, &disprect); + RE_InitState(re, NULL, &scene->r, NULL, winx, winy, &disprect); re->scene= scene; read_render_result(re, 0);