J-key render switching back, now with 10 slots.
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Tue, 9 Feb 2010 19:37:37 +0000 (19:37 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Tue, 9 Feb 2010 19:37:37 +0000 (19:37 +0000)
Implementation note: this was done by giving each Render a slot number,
and for every slot a new Render will be created. Not sure if this is
ideal, but it ensures that all passes, render info, etc are separate so
you can also compare render layers and passes, in 2.4x only whatever it
was currently displaying was backed up.

19 files changed:
source/blender/blenkernel/intern/displist.c
source/blender/blenkernel/intern/image.c
source/blender/blenkernel/intern/sequencer.c
source/blender/editors/object/object_bake.c
source/blender/editors/render/render_preview.c
source/blender/editors/screen/screen_ops.c
source/blender/editors/space_file/writeimage.c
source/blender/editors/space_image/image_buttons.c
source/blender/editors/space_image/image_intern.h
source/blender/editors/space_image/image_ops.c
source/blender/editors/space_image/space_image.c
source/blender/editors/space_node/node_edit.c
source/blender/nodes/intern/CMP_nodes/CMP_composite.c
source/blender/nodes/intern/CMP_nodes/CMP_image.c
source/blender/render/extern/include/RE_pipeline.h
source/blender/render/intern/include/render_types.h
source/blender/render/intern/source/convertblender.c
source/blender/render/intern/source/envmap.c
source/blender/render/intern/source/pipeline.c

index b35cf917895614165690b3c0490612e51cdc43e4..7d89d94c6d5df7697b823b4f496a16de43f083df 100644 (file)
@@ -321,9 +321,9 @@ static Render *fastshade_get_render(Scene *scene)
        /* XXX ugly global still, but we can't do preview while rendering */
        if(G.rendering==0) {
                
-               Render *re= RE_GetRender("_Shade View_");
+               Render *re= RE_GetRender("_Shade View_", RE_SLOT_DEFAULT);
                if(re==NULL) {
-                       re= RE_NewRender("_Shade View_");
+                       re= RE_NewRender("_Shade View_", RE_SLOT_DEFAULT);
                
                        RE_Database_Baking(re, scene, 0, 0);    /* 0= no faces */
                }
@@ -337,7 +337,7 @@ static Render *fastshade_get_render(Scene *scene)
 /* called on file reading */
 void fastshade_free_render(void)
 {
-       Render *re= RE_GetRender("_Shade View_");
+       Render *re= RE_GetRender("_Shade View_", RE_SLOT_DEFAULT);
        
        if(re) {
                RE_Database_Free(re);
index 09b86234d33a77f3a8436e73c53665225d9925b5..41a05a989e6559e472b4d4b6e93275dbda781a18 100644 (file)
@@ -1088,7 +1088,7 @@ static void stampdata(Scene *scene, StampData *stamp_data, int do_prefix)
        }
 
        {
-               Render *re= RE_GetRender(scene->id.name);
+               Render *re= RE_GetRender(scene->id.name, RE_SLOT_RENDERING);
                RenderStats *stats= re ? RE_GetStats(re):NULL;
 
                if (stats && (scene->r.stamp & R_STAMP_RENDERTIME)) {
@@ -1599,7 +1599,7 @@ RenderResult *BKE_image_acquire_renderresult(struct Scene *scene, Image *ima)
        if(ima->rr)
                return ima->rr;
        else if(ima->type==IMA_TYPE_R_RESULT)
-               return RE_AcquireResultRead(RE_GetRender(scene->id.name));
+               return RE_AcquireResultRead(RE_GetRender(scene->id.name, RE_SLOT_VIEW));
        return NULL;
 }
 
@@ -1607,7 +1607,7 @@ void BKE_image_release_renderresult(struct Scene *scene, Image *ima)
 {
        if(ima->rr);
        else if(ima->type==IMA_TYPE_R_RESULT)
-               RE_ReleaseResult(RE_GetRender(scene->id.name));
+               RE_ReleaseResult(RE_GetRender(scene->id.name, RE_SLOT_VIEW));
 }
 
 /* after imbuf load, openexr type can return with a exrhandle open */
@@ -1919,7 +1919,7 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_
                return NULL;
 
        if(iuser && iuser->scene) {
-               re= RE_GetRender(iuser->scene->id.name);
+               re= RE_GetRender(iuser->scene->id.name, RE_SLOT_VIEW);
                rr= RE_AcquireResultRead(re);
 
                /* release is done in BKE_image_release_ibuf using lock_r */
@@ -1953,7 +1953,7 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_
                pass= (iuser)? iuser->pass: 0;
                
                /* this gives active layer, composite or seqence result */
-               RE_AcquireResultImage(RE_GetRender(iuser->scene->id.name), &rres);
+               RE_AcquireResultImage(RE_GetRender(iuser->scene->id.name, RE_SLOT_VIEW), &rres);
                rect= (unsigned int *)rres.rect32;
                rectf= rres.rectf;
                rectz= rres.rectz;
index 8c119eb753ba7eaaa37bf5fff42400c158edf562..c5865db5e263f178ade9310b2c191fafa90641fc 100644 (file)
@@ -2049,7 +2049,6 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int
                Scene *sce= seq->scene;// *oldsce= scene;
                Render *re;
                RenderResult rres;
-               char scenename[64];
                int have_seq= FALSE;
                int sce_valid= FALSE;
 
@@ -2093,11 +2092,10 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int
 
                        oldcfra = seq->scene->r.cfra;
 
-                       if(rendering) {
-                               BLI_strncpy(scenename, sce->id.name+2, 64);
-                               strcpy(sce->id.name+2, " do_build_seq_ibuf");
-                       }
-                       re= RE_NewRender(sce->id.name);
+                       if(rendering)
+                               re= RE_NewRender(" do_build_seq_ibuf", RE_SLOT_DEFAULT);
+                       else
+                               re= RE_NewRender(sce->id.name, RE_SLOT_VIEW);
                        
                        /* prevent eternal loop */
                        doseq= scene->r.scemode & R_DOSEQ;
@@ -2106,9 +2104,6 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int
                        RE_BlenderFrame(re, sce, NULL,
                                        seq->sfra+se->nr+seq->anim_startofs);
                        
-                       if(rendering)
-                               BLI_strncpy(sce->id.name+2, scenename, 64);
-                       
                        RE_AcquireResultImage(re, &rres);
                        
                        if(rres.rectf) {
index 7aa9d557118205fb1e7c3dc96ef638c286b9dd50..39eda367d85ef63f5ff8758ed42167ec9d128d3f 100644 (file)
@@ -141,7 +141,7 @@ static void init_bake_internal(BakeRender *bkr, bContext *C)
        bkr->sa= biggest_image_area(CTX_wm_screen(C)); /* can be NULL */
        bkr->scene= scene;
        bkr->actob= (scene->r.bake_flag & R_BAKE_TO_ACTIVE) ? OBACT : NULL;
-       bkr->re= RE_NewRender("_Bake View_");
+       bkr->re= RE_NewRender("_Bake View_", RE_SLOT_DEFAULT);
 
        if(scene->r.bake_mode==RE_BAKE_AO) {
                /* If raytracing or AO is disabled, switch it on temporarily for baking. */
index 1f1a0ff859dbac17afb8d1d79091a67e200ced9f..8aa57ca3fbb1054018c9f997d454931c0e052d18 100644 (file)
@@ -474,7 +474,7 @@ static int ed_preview_draw_rect(ScrArea *sa, Scene *sce, ID *id, int split, int
                }
        }
 
-       re= RE_GetRender(name);
+       re= RE_GetRender(name, RE_SLOT_DEFAULT);
        RE_AcquireResultImage(re, &rres);
 
        if(rres.rectf) {
@@ -702,7 +702,7 @@ void BIF_view3d_previewrender(Scene *scene, ScrArea *sa)
                ri->status= 0;
                
                sprintf(name, "View3dPreview %p", sa);
-               re= ri->re= RE_NewRender(name);
+               re= ri->re= RE_NewRender(name, RE_SLOT_DEFAULT);
                //RE_display_draw_cb(re, view3d_previewrender_progress);
                //RE_stats_draw_cb(re, view3d_previewrender_stats);
                //RE_test_break_cb(re, qtest);
@@ -890,11 +890,11 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs
        
        if(!split || first) sprintf(name, "Preview %p", sp->owner);
        else sprintf(name, "SecondPreview %p", sp->owner);
-       re= RE_GetRender(name);
+       re= RE_GetRender(name, RE_SLOT_DEFAULT);
        
        /* full refreshed render from first tile */
        if(re==NULL)
-               re= RE_NewRender(name);
+               re= RE_NewRender(name, RE_SLOT_DEFAULT);
                
        /* sce->r gets copied in RE_InitState! */
        sce->r.scemode &= ~(R_MATNODE_PREVIEW|R_TEXNODE_PREVIEW);
index 53cd34c46f5b0534ed830a61ed54a93f84f4a5c9..2957e77a89e0d1185c567498c34ae83feebaf3cf 100644 (file)
@@ -2885,10 +2885,10 @@ static void screen_set_image_output(bContext *C, int mx, int my)
 static int screen_render_exec(bContext *C, wmOperator *op)
 {
        Scene *scene= CTX_data_scene(C);
-       Render *re= RE_GetRender(scene->id.name);
+       Render *re= RE_GetRender(scene->id.name, RE_SLOT_VIEW);
        
        if(re==NULL) {
-               re= RE_NewRender(scene->id.name);
+               re= RE_NewRender(scene->id.name, RE_SLOT_VIEW);
        }
        RE_test_break_cb(re, NULL, (int (*)(void *)) blender_test_break);
        
@@ -3236,7 +3236,7 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event)
        rj->image= ima;
        
        /* setup new render */
-       re= RE_NewRender(scene->id.name);
+       re= RE_NewRender(scene->id.name, RE_SLOT_VIEW);
        RE_test_break_cb(re, rj, render_breakjob);
        RE_display_draw_cb(re, rj, image_rect_update);
        RE_stats_draw_cb(re, rj, image_renderinfo_cb);
@@ -3398,7 +3398,7 @@ static int screen_opengl_render_init(bContext *C, wmOperator *op)
        oglrender->iuser.ok= 1;
        
        /* create render and render result */
-       oglrender->re= RE_NewRender(scene->id.name);
+       oglrender->re= RE_NewRender(scene->id.name, RE_SLOT_VIEW);
        RE_InitState(oglrender->re, NULL, &scene->r, NULL, sizex, sizey, NULL);
        
        rr= RE_AcquireResultWrite(oglrender->re);
index 5f0b75d068afb7861858672d4a29f1bae6ca2143..14a8a79a1fa8d63c827d384d3a9b3fb417bab23b 100644 (file)
@@ -114,14 +114,14 @@ static void save_rendered_image_cb_real(char *name, int confirm)
        
        if(overwrite) {
                if(scene->r.imtype==R_MULTILAYER) {
-                       Render *re= RE_GetRender(scene->id.name);
+                       Render *re= RE_GetRender(scene->id.name, RE_SLOT_VIEW);
                        RenderResult *rr= RE_AcquireResultRead(re);
                        if(rr) 
                                RE_WriteRenderResult(rr, str, scene->r.quality);
                        RE_ReleaseResult(re);
                }
                else {
-                       Render *re= RE_GetRender(scene->id.name);
+                       Render *re= RE_GetRender(scene->id.name, RE_SLOT_VIEW);
                        RenderResult rres;
                        ImBuf *ibuf;
                        
@@ -235,7 +235,7 @@ void BIF_save_rendered_image(char *name)
 /* calls fileselect */
 void BIF_save_rendered_image_fs(Scene *scene)
 {
-       Render *re= RE_GetRender(scene->id.name);
+       Render *re= RE_GetRender(scene->id.name, RE_SLOT_VIEW);
        RenderResult rres;
        
        RE_AcquireResultImage(re, &rres);
index 94df99d9c8d2cb79d825cd475f1ecb6e4a2b63da..2eb371357f12cf2ec0db097404a0e18aae58dda6 100644 (file)
@@ -533,6 +533,22 @@ static void image_panel_preview(ScrArea *sa, short cntrl)  // IMAGE_HANDLER_PREVI
 
 /* ********************* callbacks for standard image buttons *************** */
 
+static char *slot_menu()
+{
+       char *str;
+       int a, slot;
+       
+       str= MEM_callocN(RE_SLOT_MAX*32, "menu slots");
+       
+       strcpy(str, "Slot %t");
+       a= strlen(str);
+
+       for(slot=0; slot<RE_SLOT_MAX; slot++)
+               a += sprintf(str+a, "|Slot %d %%x%d", slot+1, slot);
+       
+       return str;
+}
+
 static char *layer_menu(RenderResult *rr, short *curlay)
 {
        RenderLayer *rl;
@@ -599,7 +615,10 @@ static void set_frames_cb(bContext *C, void *ima_v, void *iuser_v)
 /* 5 layer button callbacks... */
 static void image_multi_cb(bContext *C, void *rr_v, void *iuser_v) 
 {
-       BKE_image_multilayer_index(rr_v, iuser_v); 
+       ImageUser *iuser= iuser_v;
+
+       RE_SetViewSlot(iuser->menunr);
+       BKE_image_multilayer_index(rr_v, iuser); 
        WM_event_add_notifier(C, NC_IMAGE|ND_DRAW, NULL);
 }
 static void image_multi_inclay_cb(bContext *C, void *rr_v, void *iuser_v) 
@@ -699,34 +718,45 @@ static void image_user_change(bContext *C, void *iuser_v, void *unused)
 }
 #endif
 
-static void uiblock_layer_pass_buttons(uiLayout *layout, RenderResult *rr, ImageUser *iuser, int w)
+static void uiblock_layer_pass_buttons(uiLayout *layout, RenderResult *rr, ImageUser *iuser, int w, int render)
 {
        uiBlock *block= uiLayoutGetBlock(layout);
        uiBut *but;
        RenderLayer *rl= NULL;
-       int wmenu1, wmenu2;
+       int wmenu1, wmenu2, wmenu3;
        char *strp;
 
        uiLayoutRow(layout, 1);
 
        /* layer menu is 1/3 larger than pass */
-       wmenu1= (3*w)/5;
-       wmenu2= (2*w)/5;
+       wmenu1= (2*w)/5;
+       wmenu2= (3*w)/5;
+       wmenu3= (3*w)/6;
        
        /* menu buts */
-       strp= layer_menu(rr, &iuser->layer);
-       but= uiDefButS(block, MENU, 0, strp,                                    0, 0, wmenu1, 20, &iuser->layer, 0,0,0,0, "Select Layer");
-       uiButSetFunc(but, image_multi_cb, rr, iuser);
-       MEM_freeN(strp);
-       
-       rl= BLI_findlink(&rr->layers, iuser->layer - (rr->rectf?1:0)); /* fake compo layer, return NULL is meant to be */
-       strp= pass_menu(rl, &iuser->pass);
-       but= uiDefButS(block, MENU, 0, strp,                                    0, 0, wmenu2, 20, &iuser->pass, 0,0,0,0, "Select Pass");
-       uiButSetFunc(but, image_multi_cb, rr, iuser);
-       MEM_freeN(strp);        
+       if(render) {
+               strp= slot_menu();
+               iuser->menunr= RE_GetViewSlot();
+               but= uiDefButS(block, MENU, 0, strp,                                    0, 0, wmenu1, 20, &iuser->menunr, 0,0,0,0, "Select Slot");
+               uiButSetFunc(but, image_multi_cb, rr, iuser);
+               MEM_freeN(strp);
+       }
+
+       if(rr) {
+               strp= layer_menu(rr, &iuser->layer);
+               but= uiDefButS(block, MENU, 0, strp,                                    0, 0, wmenu2, 20, &iuser->layer, 0,0,0,0, "Select Layer");
+               uiButSetFunc(but, image_multi_cb, rr, iuser);
+               MEM_freeN(strp);
+               
+               rl= BLI_findlink(&rr->layers, iuser->layer - (rr->rectf?1:0)); /* fake compo layer, return NULL is meant to be */
+               strp= pass_menu(rl, &iuser->pass);
+               but= uiDefButS(block, MENU, 0, strp,                                    0, 0, wmenu3, 20, &iuser->pass, 0,0,0,0, "Select Pass");
+               uiButSetFunc(but, image_multi_cb, rr, iuser);
+               MEM_freeN(strp);        
+       }
 }
 
-static void uiblock_layer_pass_arrow_buttons(uiLayout *layout, RenderResult *rr, ImageUser *iuser
+static void uiblock_layer_pass_arrow_buttons(uiLayout *layout, RenderResult *rr, ImageUser *iuser, int render)
 {
        uiBlock *block= uiLayoutGetBlock(layout);
        uiLayout *row;
@@ -747,7 +777,7 @@ static void uiblock_layer_pass_arrow_buttons(uiLayout *layout, RenderResult *rr,
        but= uiDefIconBut(block, BUT, 0, ICON_TRIA_RIGHT,       0,0,18,20, NULL, 0, 0, 0, 0, "Next Layer");
        uiButSetFunc(but, image_multi_inclay_cb, rr, iuser);
 
-       uiblock_layer_pass_buttons(row, rr, iuser, 230);
+       uiblock_layer_pass_buttons(row, rr, iuser, 230, render);
 
        /* decrease, increase arrows */
        but= uiDefIconBut(block, BUT, 0, ICON_TRIA_LEFT,        0,0,17,20, NULL, 0, 0, 0, 0, "Previous Pass");
@@ -856,9 +886,9 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propn
                        }
                        else if(ima->type==IMA_TYPE_R_RESULT) {
                                /* browse layer/passes */
-                               Render *re= RE_GetRender(scene->id.name);
+                               Render *re= RE_GetRender(scene->id.name, RE_SLOT_VIEW);
                                RenderResult *rr= RE_AcquireResultRead(re);
-                               uiblock_layer_pass_arrow_buttons(layout, rr, iuser);
+                               uiblock_layer_pass_arrow_buttons(layout, rr, iuser, 1);
                                RE_ReleaseResult(re);
                        }
                }
@@ -885,7 +915,7 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propn
 
                        /* multilayer? */
                        if(ima->type==IMA_TYPE_MULTILAYER && ima->rr) {
-                               uiblock_layer_pass_arrow_buttons(layout, ima->rr, iuser);
+                               uiblock_layer_pass_arrow_buttons(layout, ima->rr, iuser, 0);
                        }
                        else if(ima->source != IMA_SRC_GENERATED) {
                                if(compact == 0) {
@@ -965,10 +995,7 @@ void uiTemplateImageLayers(uiLayout *layout, bContext *C, Image *ima, ImageUser
        /* render layers and passes */
        if(ima && iuser) {
                rr= BKE_image_acquire_renderresult(scene, ima);
-
-               if(rr)
-                       uiblock_layer_pass_buttons(layout, rr, iuser, 160);
-
+               uiblock_layer_pass_buttons(layout, rr, iuser, 160, ima->type==IMA_TYPE_R_RESULT);
                BKE_image_release_renderresult(scene, ima);
        }
 }
index b7f81245296a9bf52fa93cdf8e0a97fdb5388a4c..80fcbe5f240e032e4375464dbd07cef84135c9f8 100644 (file)
@@ -77,6 +77,8 @@ void IMAGE_OT_save_sequence(struct wmOperatorType *ot);
 void IMAGE_OT_pack(struct wmOperatorType *ot);
 void IMAGE_OT_unpack(struct wmOperatorType *ot);
 
+void IMAGE_OT_cycle_render_slot(struct wmOperatorType *ot);
+
 void IMAGE_OT_sample(struct wmOperatorType *ot);
 void IMAGE_OT_curves_point_set(struct wmOperatorType *ot);
 
index 2011649fda6f59ebccb0d5624a5af9d189424dad..a1557e424da373109b4da501fb174c09b20a2e17 100644 (file)
@@ -1791,6 +1791,51 @@ void IMAGE_OT_record_composite(wmOperatorType *ot)
        ot->poll= space_image_poll;
 }
 
+/********************* cycle render slot operator *********************/
+
+static int cycle_render_slot_poll(bContext *C)
+{
+       Image *ima= CTX_data_edit_image(C);
+
+       return (ima && ima->type == IMA_TYPE_R_RESULT);
+}
+
+static int cycle_render_slot_exec(bContext *C, wmOperator *op)
+{
+       Scene *scene= CTX_data_scene(C);
+       int a, slot, cur= RE_GetViewSlot();
+
+       for(a=1; a<RE_SLOT_MAX; a++) {
+               slot= (cur+a)%RE_SLOT_MAX;
+
+               if(RE_GetRender(scene->id.name, slot)) {
+                       RE_SetViewSlot(slot);
+                       break;
+               }
+       }
+
+       if(a == RE_SLOT_MAX)
+               RE_SetViewSlot((cur == 1)? 0: 1);
+
+       WM_event_add_notifier(C, NC_IMAGE|ND_DRAW, NULL);
+
+       return OPERATOR_FINISHED;
+}
+
+void IMAGE_OT_cycle_render_slot(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Cycle Render Slot";
+       ot->idname= "IMAGE_OT_cycle_render_slot";
+       
+       /* api callbacks */
+       ot->exec= cycle_render_slot_exec;
+       ot->poll= cycle_render_slot_poll;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
 /******************** TODO ********************/
 
 /* XXX notifier? */
@@ -1843,3 +1888,4 @@ void BIF_image_update_frame(void)
 }
 #endif
 
+
index a653838c0735954a80d303c859efbe7f2e0b6091..c8c110b3d02372260d8a3368435248daf16b36b6 100644 (file)
@@ -472,6 +472,8 @@ void image_operatortypes(void)
        WM_operatortype_append(IMAGE_OT_pack);
        WM_operatortype_append(IMAGE_OT_unpack);
 
+       WM_operatortype_append(IMAGE_OT_cycle_render_slot);
+
        WM_operatortype_append(IMAGE_OT_sample);
        WM_operatortype_append(IMAGE_OT_curves_point_set);
 
@@ -493,6 +495,8 @@ void image_keymap(struct wmKeyConfig *keyconf)
        WM_keymap_add_item(keymap, "IMAGE_OT_save_as", F3KEY, KM_PRESS, 0, 0);
        WM_keymap_add_item(keymap, "IMAGE_OT_properties", NKEY, KM_PRESS, 0, 0);
        WM_keymap_add_item(keymap, "IMAGE_OT_scopes", PKEY, KM_PRESS, 0, 0);
+
+       WM_keymap_add_item(keymap, "IMAGE_OT_cycle_render_slot", JKEY, KM_PRESS, 0, 0);
        
        keymap= WM_keymap_find(keyconf, "Image", SPACE_IMAGE, 0);
        
index 89fb40367e847443fa4be48d7a29ef6aec873ff8..e03e6e023dd24c63b6ec9d51db3ef11d260aeb86 100644 (file)
@@ -1661,7 +1661,7 @@ void node_read_renderlayers(SpaceNode *snode)
 void node_read_fullsamplelayers(SpaceNode *snode)
 {
        Scene *curscene= NULL; // XXX
-       Render *re= RE_NewRender(curscene->id.name);
+       Render *re= RE_NewRender(curscene->id.name, RE_SLOT_VIEW);
 
        WM_cursor_wait(1);
 
index d117a3cb23529579b6e62a079d191d58abe46f33..079d2ebeac1d5705b983653e4d16cdbddb6e6db5 100644 (file)
@@ -50,7 +50,7 @@ static void node_composit_exec_composite(void *data, bNode *node, bNodeStack **i
                RenderData *rd= data;
                
                if(scene && (rd->scemode & R_DOCOMP)) {
-                       Render *re= RE_GetRender(scene->id.name);
+                       Render *re= RE_GetRender(scene->id.name, RE_SLOT_RENDERING);
                        RenderResult *rr= RE_AcquireResultWrite(re); 
                        if(rr) {
                                CompBuf *outbuf, *zbuf=NULL;
index f209687d6a53929dcbaa386d3b4453b6833c39a7..09f826ebff7092ebb8378f9ce16fb7b8f0d57185 100644 (file)
@@ -346,7 +346,7 @@ void node_composit_rlayers_out(RenderData *rd, RenderLayer *rl, bNodeStack **out
 static void node_composit_exec_rlayers(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
 {
    Scene *sce= (Scene *)node->id;
-   Render *re= (sce)? RE_GetRender(sce->id.name): NULL;
+   Render *re= (sce)? RE_GetRender(sce->id.name, RE_SLOT_RENDERING): NULL;
    RenderData *rd= data;
    RenderResult *rr= NULL;
 
index a90220b9c1bf793c07c36468130e3f1325d9aad1..4084958488cb041598f67bf98f7575a59ecc6e7e 100644 (file)
@@ -146,8 +146,21 @@ typedef struct RenderStats {
 
 /* the name is used as identifier, so elsewhere in blender the result can retrieved */
 /* calling a new render with same name, frees automatic existing render */
-struct Render *RE_NewRender (const char *name);
-struct Render *RE_GetRender(const char *name);
+struct Render *RE_NewRender (const char *name, int slot);
+struct Render *RE_GetRender(const char *name, int slot);
+
+/* render slots. for most cases like baking or preview render this will
+   always be default, for actual render multiple slots can be used. in
+   that case 'rendering' is the slot being rendered to, and 'view' is the
+   slot being viewed. these are always the same except if the currently
+   viewed slot is changed during render, at the end they will be synced. */
+#define RE_SLOT_RENDERING      -2
+#define RE_SLOT_VIEW           -1
+#define RE_SLOT_DEFAULT                 0
+#define RE_SLOT_MAX                    10
+
+void RE_SetViewSlot(int slot);
+int RE_GetViewSlot(void);
 
 /* returns 1 while render is working (or renders called from within render) */
 int RE_RenderInProgress(struct Render *re);
index de7d176759e4b14888402b5a7aedff31016dcf01..c4465781940b6d4fa1925a4cad54ff8cbe51290c 100644 (file)
@@ -113,6 +113,7 @@ struct Render
 {
        struct Render *next, *prev;
        char name[RE_MAXNAME];
+       int slot;
        
        /* state settings */
        short flag, osa, ok, result_ok;
index d05d88266c75b83052726e7d0bd60178e81c06cd..a24fa47ec3ed33c4ecd62e2eff4d5a045844050e 100644 (file)
@@ -5605,7 +5605,7 @@ void RE_make_sticky(Scene *scene, View3D *v3d)
                return;
        }
        
-       re= RE_NewRender("_make sticky_");
+       re= RE_NewRender("_make sticky_", RE_SLOT_DEFAULT);
        RE_InitState(re, NULL, &scene->r, NULL, scene->r.xsch, scene->r.ysch, NULL);
        
        /* use renderdata and camera to set viewplane */
index 7ba860955b3dc75ae89b16d4172a900a27f190aa..0ab0b1c4141d15e943f37f2c17726beb7dfb65af 100644 (file)
@@ -108,7 +108,7 @@ static Render *envmap_render_copy(Render *re, EnvMap *env)
        Render *envre;
        int cuberes;
        
-       envre= RE_NewRender("Envmap");
+       envre= RE_NewRender("Envmap", RE_SLOT_DEFAULT);
        
        env->lastsize= re->r.size;
        cuberes = (env->cuberes * re->r.size) / 100;
index f679b35c627dfa5ed7f618901188222799762a53..c5d4392a53c797d2c7a5d1458a56b71d9d532f24 100644 (file)
 /* ********* globals ******** */
 
 /* here we store all renders */
-static struct ListBase RenderList= {NULL, NULL};
+static struct {
+       ListBase renderlist;
+
+       /* render slots */
+       int viewslot, renderingslot;
+
+       /* commandline thread override */
+       int threads;
+} RenderGlobal = {{NULL, NULL}, 0, 0, -1}; 
 
 /* hardcopy of current render, used while rendering for speed */
 Render R;
 
-/* commandline thread override */
-static int commandline_threads= -1;
-
 /* ********* alloc and free ******** */
 
 
@@ -228,11 +233,11 @@ static void push_render_result(Render *re)
 /* if scemode is R_SINGLE_LAYER, at end of rendering, merge the both render results */
 static void pop_render_result(Render *re)
 {
-       
        if(re->result==NULL) {
                printf("pop render result error; no current result!\n");
                return;
        }
+
        if(re->pushedresult) {
                BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
 
@@ -989,13 +994,35 @@ static void read_render_result(Render *re, int sample)
 
 /* *************************************************** */
 
-Render *RE_GetRender(const char *name)
+void RE_SetViewSlot(int slot)
+{
+       RenderGlobal.viewslot = slot;
+}
+
+int RE_GetViewSlot(void)
+{
+       return RenderGlobal.viewslot;
+}
+
+static int re_get_slot(int slot)
+{
+       if(slot == RE_SLOT_VIEW)
+               return RenderGlobal.viewslot;
+       else if(slot == RE_SLOT_RENDERING)
+               return (G.rendering)? RenderGlobal.renderingslot: RenderGlobal.viewslot;
+
+       return slot;
+}
+
+Render *RE_GetRender(const char *name, int slot)
 {
        Render *re;
+
+       slot= re_get_slot(slot);
        
        /* search for existing renders */
-       for(re= RenderList.first; re; re= re->next) {
-               if(strncmp(re->name, name, RE_MAXNAME)==0) {
+       for(re= RenderGlobal.renderlist.first; re; re= re->next) {
+               if(strncmp(re->name, name, RE_MAXNAME)==0 && re->slot==slot) {
                        break;
                }
        }
@@ -1126,24 +1153,26 @@ void RE_ResultGet32(Render *re, unsigned int *rect)
        RE_ReleaseResultImage(re);
 }
 
-
 RenderStats *RE_GetStats(Render *re)
 {
        return &re->i;
 }
 
-Render *RE_NewRender(const char *name)
+Render *RE_NewRender(const char *name, int slot)
 {
        Render *re;
+
+       slot= re_get_slot(slot);
        
        /* only one render per name exists */
-       re= RE_GetRender(name);
+       re= RE_GetRender(name, slot);
        if(re==NULL) {
                
                /* new render data struct */
                re= MEM_callocN(sizeof(Render), "new render");
-               BLI_addtail(&RenderList, re);
+               BLI_addtail(&RenderGlobal.renderlist, re);
                strncpy(re->name, name, RE_MAXNAME);
+               re->slot= slot;
                BLI_rw_mutex_init(&re->resultmutex);
        }
        
@@ -1178,15 +1207,15 @@ void RE_FreeRender(Render *re)
        RE_FreeRenderResult(re->result);
        RE_FreeRenderResult(re->pushedresult);
        
-       BLI_remlink(&RenderList, re);
+       BLI_remlink(&RenderGlobal.renderlist, re);
        MEM_freeN(re);
 }
 
 /* exit blender */
 void RE_FreeAllRender(void)
 {
-       while(RenderList.first) {
-               RE_FreeRender(RenderList.first);
+       while(RenderGlobal.renderlist.first) {
+               RE_FreeRender(RenderGlobal.renderlist.first);
        }
 }
 
@@ -2186,7 +2215,7 @@ static void do_render_fields_blur_3d(Render *re)
 */
 static void render_scene(Render *re, Scene *sce, int cfra)
 {
-       Render *resc= RE_NewRender(sce->id.name);
+       Render *resc= RE_NewRender(sce->id.name, RE_SLOT_RENDERING);
        int winx= re->winx, winy= re->winy;
        
        sce->r.cfra= cfra;
@@ -2313,7 +2342,7 @@ static void do_merge_fullsample(Render *re, bNodeTree *ntree)
                        Render *re1;
                        
                        tag_scenes_for_render(re);
-                       for(re1= RenderList.first; re1; re1= re1->next) {
+                       for(re1= RenderGlobal.renderlist.first; re1; re1= re1->next) {
                                if(re1->scene->id.flag & LIB_DOIT)
                                        if(re1->r.scemode & R_FULL_SAMPLE)
                                                read_render_result(re1, sample);
@@ -2475,7 +2504,7 @@ static void do_render_composite_fields_blur_3d(Render *re)
 static void renderresult_stampinfo(Scene *scene)
 {
        RenderResult rres;
-       Render *re= RE_GetRender(scene->id.name);
+       Render *re= RE_GetRender(scene->id.name, RE_SLOT_RENDERING);
 
        /* this is the basic trick to get the displayed float or char rect from render result */
        RE_AcquireResultImage(re, &rres);
@@ -2784,8 +2813,9 @@ static int render_initialize_from_scene(Render *re, Scene *scene, SceneRenderLay
 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;
+       RenderGlobal.renderingslot= re->slot;
        re->result_ok= 0;
+       G.rendering= 1;
        
        scene->r.cfra= frame;
        
@@ -2794,8 +2824,9 @@ void RE_BlenderFrame(Render *re, Scene *scene, SceneRenderLayer *srl, int frame)
        }
        
        /* UGLY WARNING */
-       G.rendering= 0;
        re->result_ok= 1;
+       G.rendering= 0;
+       RenderGlobal.renderingslot= RenderGlobal.viewslot;
 }
 
 static int do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh, ReportList *reports)
@@ -2899,6 +2930,7 @@ void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra, int tfra, Repo
        /* ugly global still... is to prevent renderwin events and signal subsurfs etc to make full resol */
        /* is also set by caller renderwin.c */
        G.rendering= 1;
+       RenderGlobal.renderingslot= re->slot;
        re->result_ok= 0;
        
        if(BKE_imtype_is_movie(scene->r.imtype))
@@ -2995,6 +3027,7 @@ void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra, int tfra, Repo
        /* UGLY WARNING */
        G.rendering= 0;
        re->result_ok= 1;
+       RenderGlobal.renderingslot= RenderGlobal.viewslot;
 }
 
 /* note; repeated win/disprect calc... solve that nicer, also in compo */
@@ -3028,9 +3061,9 @@ void RE_ReadRenderResult(Scene *scene, Scene *scenode)
                scene= scenode;
        
        /* get render: it can be called from UI with draw callbacks */
-       re= RE_GetRender(scene->id.name);
+       re= RE_GetRender(scene->id.name, RE_SLOT_VIEW);
        if(re==NULL)
-               re= RE_NewRender(scene->id.name);
+               re= RE_NewRender(scene->id.name, RE_SLOT_VIEW);
        RE_InitState(re, NULL, &scene->r, NULL, winx, winy, &disprect);
        re->scene= scene;
        
@@ -3040,9 +3073,9 @@ void RE_ReadRenderResult(Scene *scene, Scene *scenode)
 void RE_set_max_threads(int threads)
 {
        if (threads==0) {
-               commandline_threads = BLI_system_thread_count();
+               RenderGlobal.threads = BLI_system_thread_count();
        } else if(threads>=1 && threads<=BLENDER_MAX_THREADS) {
-               commandline_threads= threads;
+               RenderGlobal.threads= threads;
        } else {
                printf("Error, threads has to be in range 0-%d\n", BLENDER_MAX_THREADS);
        }
@@ -3050,9 +3083,9 @@ void RE_set_max_threads(int threads)
 
 void RE_init_threadcount(Render *re) 
 {
-        if(commandline_threads >= 1) { /* only set as an arg in background mode */
-               re->r.threads= MIN2(commandline_threads, BLENDER_MAX_THREADS);
-       } else if ((re->r.mode & R_FIXED_THREADS)==0 || commandline_threads == 0) { /* Automatic threads */
+       if(RenderGlobal.threads >= 1) { /* only set as an arg in background mode */
+               re->r.threads= MIN2(RenderGlobal.threads, BLENDER_MAX_THREADS);
+       } else if ((re->r.mode & R_FIXED_THREADS)==0 || RenderGlobal.threads == 0) { /* Automatic threads */
                re->r.threads = BLI_system_thread_count();
        }
 }