bake is now modal like render and updates the image view while baking.
authorCampbell Barton <ideasman42@gmail.com>
Wed, 30 Dec 2009 14:37:25 +0000 (14:37 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Wed, 30 Dec 2009 14:37:25 +0000 (14:37 +0000)
it also has an exec function which doesnt update (like render too)

source/blender/editors/include/ED_mesh.h
source/blender/editors/mesh/meshtools.c
source/blender/editors/object/object_bake.c [new file with mode: 0644]
source/blender/editors/object/object_edit.c
source/blender/editors/object/object_intern.h
source/blender/editors/object/object_ops.c
source/blender/editors/space_image/space_image.c
source/blender/render/extern/include/RE_shader_ext.h
source/blender/render/intern/source/rendercore.c

index 66c32b0..174447c 100644 (file)
@@ -85,8 +85,6 @@ int                   *mesh_get_x_mirror_faces(struct Object *ob, struct EditMesh *em);
 int                    join_mesh_exec(struct bContext *C, struct wmOperator *op);
 int                    join_mesh_shapes_exec(struct bContext *C, struct wmOperator *op);
 
-void           objects_bake_render(struct Scene *scene, short event, char **error_msg);
-
 /* mesh_ops.c */
 void           ED_operatortypes_mesh(void);
 void           ED_operatormacros_mesh(void);
index 1feaa2d..b52447e 100644 (file)
 #include "BKE_utildefines.h"
 #include "BKE_report.h"
 
-#include "RE_pipeline.h"
-#include "RE_shader_ext.h"
-
-#include "PIL_time.h"
-
-#include "IMB_imbuf_types.h"
-#include "IMB_imbuf.h"
-
-#include "GPU_draw.h"
-
 #include "BLO_sys_types.h" // for intptr_t support
 
 #include "ED_mesh.h"
@@ -99,8 +89,6 @@
 #include "mesh_intern.h"
 
 /* XXX */
-static void waitcursor(int val) {}
-static void error() {}
 static int pupmenu() {return 0;}
 /* XXX */
 
@@ -1132,191 +1120,3 @@ int *mesh_get_x_mirror_faces(Object *ob, EditMesh *em)
        
        return mirrorfaces;
 }
-
-/* ****************** render BAKING ********************** */
-
-/* threaded break test */
-static int thread_break(void *unused)
-{
-       return G.afbreek;
-}
-
-static ScrArea *biggest_image_area(bScreen *screen)
-{
-       ScrArea *sa, *big= NULL;
-       int size, maxsize= 0;
-       
-       for(sa= screen->areabase.first; sa; sa= sa->next) {
-               if(sa->spacetype==SPACE_IMAGE) {
-                       size= sa->winx*sa->winy;
-                       if(sa->winx > 10 && sa->winy > 10 && size > maxsize) {
-                               maxsize= size;
-                               big= sa;
-                       }
-               }
-       }
-       return big;
-}
-
-
-typedef struct BakeRender {
-       Render *re;
-       struct Object *actob;
-       int event, tot, ready;
-} BakeRender;
-
-static void *do_bake_render(void *bake_v)
-{
-       BakeRender *bkr= bake_v;
-       
-       bkr->tot= RE_bake_shade_all_selected(bkr->re, bkr->event, bkr->actob);
-       bkr->ready= 1;
-       
-       return NULL;
-}
-
-
-void objects_bake_render(Scene *scene, short event, char **error_msg)
-{
-       Object *actob= OBACT;
-       int active= scene->r.bake_flag & R_BAKE_TO_ACTIVE;
-       short prev_r_raytrace= 0, prev_wo_amb_occ= 0;
-       
-       if(event==0) event= scene->r.bake_mode;
-       
-       if(scene->r.renderer!=R_INTERN) {        
-               *error_msg = "Bake only supported for Internal Renderer";
-               return;
-       }        
-       
-       if(active && !actob) {
-               *error_msg = "No active object";
-               return;
-       }
-       
-       if(event>0) {
-               bScreen *screen= NULL; // XXX CTX
-               Render *re= RE_NewRender("_Bake View_");
-               ScrArea *area= NULL; //biggest_image_area(screen); // XXX
-               ListBase threads;
-               BakeRender bkr;
-               int timer=0, tot; // XXX, sculptmode= G.f & G_SCULPTMODE;
-
-// XXX         if(sculptmode) set_sculptmode();
-               
-               if(event==1) event= RE_BAKE_ALL;
-               else if(event==2) event= RE_BAKE_AO;
-               else if(event==3) event= RE_BAKE_NORMALS;
-               else if(event==4) event= RE_BAKE_TEXTURE;
-               else if(event==5) event= RE_BAKE_DISPLACEMENT;
-               else event= RE_BAKE_SHADOW;
-
-               if(event==RE_BAKE_AO) {
-                       if(scene->world==NULL) {
-                               *error_msg = "No world set up";
-                               return;
-                       }
-
-                       /* If raytracing or AO is disabled, switch it on temporarily for baking. */
-                       prev_wo_amb_occ = (scene->world->mode & WO_AMB_OCC) != 0;
-                       scene->world->mode |= WO_AMB_OCC;
-               }
-               if(event==RE_BAKE_AO || active) {
-                       prev_r_raytrace = (scene->r.mode & R_RAYTRACE) != 0;
-                       scene->r.mode |= R_RAYTRACE;
-               }
-               
-               waitcursor(1);
-               RE_test_break_cb(re, NULL, thread_break);
-               G.afbreek= 0;   /* blender_test_break uses this global */
-               
-               RE_Database_Baking(re, scene, event, (active)? actob: NULL);
-               
-               /* baking itself is threaded, cannot use test_break in threads. we also update optional imagewindow */
-       
-               BLI_init_threads(&threads, do_bake_render, 1);
-               bkr.re= re;
-               bkr.event= event;
-               bkr.ready= 0;
-               bkr.actob= (active)? actob: NULL;
-               BLI_insert_thread(&threads, &bkr);
-               
-               while(bkr.ready==0) {
-                       PIL_sleep_ms(50);
-                       if(bkr.ready)
-                               break;
-                       
-                       if (!G.background) {
-                               blender_test_break();
-                               
-                               timer++;
-                               if(area && timer==20) {
-                                       Image *ima= RE_bake_shade_get_image();
-                                       if(ima) ((SpaceImage *)area->spacedata.first)->image= ima;
-// XX                                  scrarea_do_windraw(area);
-//                                     myswapbuffers();        
-                                       timer= 0;
-                               }
-                       }
-               }
-               BLI_end_threads(&threads);
-               tot= bkr.tot;
-               
-               RE_Database_Free(re);
-               waitcursor(0);
-               
-               if(tot==0) *error_msg = "No Images found to bake to";
-               else {
-                       Image *ima;
-                       /* force OpenGL reload and mipmap recalc */
-                       for(ima= G.main->image.first; ima; ima= ima->id.next) {
-                               if(ima->ok==IMA_OK_LOADED) {
-                                       ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
-                                       if(ibuf && (ibuf->userflags & IB_BITMAPDIRTY)) {
-                                               GPU_free_image(ima); 
-                                               imb_freemipmapImBuf(ibuf);
-                                       }
-                               }
-                       }
-               }
-               
-               /* restore raytrace and AO */
-               if(event==RE_BAKE_AO)
-                       if(prev_wo_amb_occ == 0)
-                               scene->world->mode &= ~WO_AMB_OCC;
-
-               if(event==RE_BAKE_AO || active)
-                       if(prev_r_raytrace == 0)
-                               scene->r.mode &= ~R_RAYTRACE;
-               
-// XXX         if(sculptmode) set_sculptmode();
-               
-       }
-}
-
-/* all selected meshes with UV maps are rendered for current scene visibility */
-static void objects_bake_render_ui(Scene *scene, short event)
-{
-       char *error_msg = NULL;
-//     int is_editmode = (obedit!=NULL);
-       
-       /* Deal with editmode, this is a bit clunky but since UV's are in editmode, users are likely to bake from their */
-// XXX if (is_editmode) exit_editmode(0);
-       
-       objects_bake_render(scene, event, &error_msg);
-       
-// XXX if (is_editmode) enter_editmode(0);
-       
-       if (error_msg)
-               error(error_msg);
-}
-
-void objects_bake_render_menu(Scene *scene)
-{
-       short event;
-       
-       event= pupmenu("Bake Selected Meshes %t|Full Render %x1|Ambient Occlusion %x2|Normals %x3|Texture Only %x4|Displacement %x5|Shadow %x6");
-       if (event < 1) return;
-       objects_bake_render_ui(scene, event);
-}
-
diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c
new file mode 100644 (file)
index 0000000..4b02cd8
--- /dev/null
@@ -0,0 +1,341 @@
+/**
+ * $Id:
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2004 by Blender Foundation
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/*
+       meshtools.c: no editmode (violated already :), tools operating on meshes
+*/
+
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_image_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
+#include "DNA_world_types.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_threads.h"
+
+#include "BKE_blender.h"
+#include "BKE_context.h"
+#include "BKE_global.h"
+#include "BKE_image.h"
+#include "BKE_main.h"
+#include "BKE_object.h"
+#include "BKE_utildefines.h"
+#include "BKE_report.h"
+
+#include "RE_pipeline.h"
+#include "RE_shader_ext.h"
+
+#include "PIL_time.h"
+
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+
+#include "GPU_draw.h" /* GPU_free_image */
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+
+/* ****************** render BAKING ********************** */
+
+/* threaded break test */
+static int thread_break(void *unused)
+{
+       return G.afbreek;
+}
+
+static ScrArea *biggest_image_area(bScreen *screen)
+{
+       ScrArea *sa, *big= NULL;
+       int size, maxsize= 0;
+
+       for(sa= screen->areabase.first; sa; sa= sa->next) {
+               if(sa->spacetype==SPACE_IMAGE) {
+                       size= sa->winx*sa->winy;
+                       if(sa->winx > 10 && sa->winy > 10 && size > maxsize) {
+                               maxsize= size;
+                               big= sa;
+                       }
+               }
+       }
+       return big;
+}
+
+
+typedef struct BakeRender {
+       Render *re;
+       Scene *scene;
+       struct Object *actob;
+       int tot, ready;
+
+       ReportList *reports;
+
+       short *stop;
+       short *do_update;
+
+       ListBase threads;
+
+       /* backup */
+       short prev_wo_amb_occ;
+       short prev_r_raytrace;
+
+       /* for redrawing */
+       ScrArea *sa;
+} BakeRender;
+
+/* use by exec and invoke */
+int test_bake_internal(bContext *C, ReportList *reports)
+{
+       Scene *scene= CTX_data_scene(C);
+
+       if(scene->r.renderer!=R_INTERN) {
+               BKE_report(reports, RPT_ERROR, "Bake only supported for Internal Renderer");
+       } else if((scene->r.bake_flag & R_BAKE_TO_ACTIVE) && CTX_data_active_object(C)==NULL) {
+               BKE_report(reports, RPT_ERROR, "No active object");
+       }
+       else if(scene->r.bake_mode==RE_BAKE_AO && scene->world==NULL) {
+               BKE_report(reports, RPT_ERROR, "No world set up");
+       }
+       else {
+               return 1;
+       }
+
+       return 0;
+}
+
+static void init_bake_internal(BakeRender *bkr, bContext *C)
+{
+       Scene *scene= CTX_data_scene(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_");
+
+       if(scene->r.bake_mode==RE_BAKE_AO) {
+               /* If raytracing or AO is disabled, switch it on temporarily for baking. */
+               bkr->prev_wo_amb_occ = (scene->world->mode & WO_AMB_OCC) != 0;
+               scene->world->mode |= WO_AMB_OCC;
+       }
+       if(scene->r.bake_mode==RE_BAKE_AO || bkr->actob) {
+               bkr->prev_r_raytrace = (scene->r.mode & R_RAYTRACE) != 0;
+               scene->r.mode |= R_RAYTRACE;
+       }
+}
+
+static void finish_bake_internal(BakeRender *bkr)
+{
+       RE_Database_Free(bkr->re);
+
+       /* restore raytrace and AO */
+       if(bkr->scene->r.bake_mode==RE_BAKE_AO)
+               if(bkr->prev_wo_amb_occ == 0)
+                       bkr->scene->world->mode &= ~WO_AMB_OCC;
+
+       if(bkr->scene->r.bake_mode==RE_BAKE_AO || bkr->actob)
+               if(bkr->prev_r_raytrace == 0)
+                       bkr->scene->r.mode &= ~R_RAYTRACE;
+
+       if(bkr->tot) {
+               Image *ima;
+               /* force OpenGL reload and mipmap recalc */
+               for(ima= G.main->image.first; ima; ima= ima->id.next) {
+                       if(ima->ok==IMA_OK_LOADED) {
+                               ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
+                               if(ibuf && (ibuf->userflags & IB_BITMAPDIRTY)) {
+                                       GPU_free_image(ima);
+                                       imb_freemipmapImBuf(ibuf);
+                               }
+                       }
+               }
+       }
+}
+
+static void *do_bake_render(void *bake_v)
+{
+       BakeRender *bkr= bake_v;
+
+       bkr->tot= RE_bake_shade_all_selected(bkr->re, bkr->scene->r.bake_mode, bkr->actob, NULL);
+       bkr->ready= 1;
+
+       return NULL;
+}
+
+static void bake_startjob(void *bkv, short *stop, short *do_update)
+{
+       BakeRender *bkr= bkv;
+       Scene *scene= bkr->scene;
+
+       bkr->stop= stop;
+       bkr->do_update= do_update;
+
+       RE_test_break_cb(bkr->re, NULL, thread_break);
+       G.afbreek= 0;   /* blender_test_break uses this global */
+
+       RE_Database_Baking(bkr->re, scene, scene->r.bake_mode, bkr->actob);
+
+       /* baking itself is threaded, cannot use test_break in threads. we also update optional imagewindow */
+       bkr->tot= RE_bake_shade_all_selected(bkr->re, scene->r.bake_mode, bkr->actob, bkr->do_update);
+}
+
+static void bake_update(void *bkv)
+{
+       BakeRender *bkr= bkv;
+
+       if(bkr->sa && bkr->sa->spacetype==SPACE_IMAGE) { /* incase the user changed while baking */
+               SpaceImage *sima= bkr->sa->spacedata.first;
+               sima->image= RE_bake_shade_get_image();
+       }
+}
+
+static void bake_freejob(void *bkv)
+{
+       BakeRender *bkr= bkv;
+       BLI_end_threads(&bkr->threads);
+       finish_bake_internal(bkr);
+
+       if(bkr->tot==0) BKE_report(bkr->reports, RPT_ERROR, "No Images found to bake to");
+       MEM_freeN(bkr);
+}
+
+/* catch esc */
+static int objects_bake_render_modal(bContext *C, wmOperator *op, wmEvent *event)
+{
+       /* no running blender, remove handler and pass through */
+       if(0==WM_jobs_test(CTX_wm_manager(C), CTX_data_scene(C)))
+               return OPERATOR_FINISHED|OPERATOR_PASS_THROUGH;
+
+       /* running render */
+       switch (event->type) {
+               case ESCKEY:
+                       return OPERATOR_RUNNING_MODAL;
+                       break;
+       }
+       return OPERATOR_PASS_THROUGH;
+}
+
+static int objects_bake_render_invoke(bContext *C, wmOperator *op, wmEvent *_event)
+{
+       Scene *scene= CTX_data_scene(C);
+
+       if(test_bake_internal(C, op->reports)==0) {
+               return OPERATOR_CANCELLED;
+       }
+       else {
+               BakeRender *bkr= MEM_callocN(sizeof(BakeRender), "render bake");
+               wmJob *steve;
+
+               init_bake_internal(bkr, C);
+               bkr->reports= op->reports;
+
+               /* setup job */
+               steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, WM_JOB_EXCL_RENDER|WM_JOB_PRIORITY);
+               WM_jobs_customdata(steve, bkr, bake_freejob);
+               WM_jobs_timer(steve, 0.2, NC_IMAGE, 0); /* TODO - only draw bake image, can we enforce this */
+               WM_jobs_callbacks(steve, bake_startjob, NULL, bake_update);
+
+               G.afbreek= 0;
+
+               WM_jobs_start(CTX_wm_manager(C), steve);
+
+               WM_cursor_wait(0);
+               WM_event_add_notifier(C, NC_SCENE|ND_RENDER_RESULT, scene);
+
+               /* add modal handler for ESC */
+               WM_event_add_modal_handler(C, op);
+       }
+
+       return OPERATOR_RUNNING_MODAL;
+}
+
+
+static int bake_image_exec(bContext *C, wmOperator *op)
+{
+       Scene *scene= CTX_data_scene(C);
+
+
+       if(test_bake_internal(C, op->reports)==0) {
+               return OPERATOR_CANCELLED;
+       }
+       else {
+               ListBase threads;
+               BakeRender bkr;
+
+               memset(&bkr, 0, sizeof(bkr));
+
+               init_bake_internal(&bkr, C);
+               bkr.reports= op->reports;
+
+               RE_test_break_cb(bkr.re, NULL, thread_break);
+               G.afbreek= 0;   /* blender_test_break uses this global */
+
+               RE_Database_Baking(bkr.re, scene, scene->r.bake_mode, (scene->r.bake_flag & R_BAKE_TO_ACTIVE)? OBACT: NULL);
+
+               /* baking itself is threaded, cannot use test_break in threads  */
+               BLI_init_threads(&threads, do_bake_render, 1);
+               bkr.ready= 0;
+               BLI_insert_thread(&threads, &bkr);
+
+               while(bkr.ready==0) {
+                       PIL_sleep_ms(50);
+                       if(bkr.ready)
+                               break;
+
+                       /* used to redraw in 2.4x but this is just for exec in 2.5 */
+                       if (!G.background)
+                               blender_test_break();
+               }
+               BLI_end_threads(&threads);
+
+               if(bkr.tot==0) BKE_report(op->reports, RPT_ERROR, "No Images found to bake to");
+
+               finish_bake_internal(&bkr);
+       }
+
+       WM_event_add_notifier(C, NC_SCENE|ND_RENDER_RESULT, scene);
+       return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_bake_image(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Bake";
+       ot->description= "Bake image textures of selected objects.";
+       ot->idname= "OBJECT_OT_bake_image";
+
+       /* api callbacks */
+       ot->exec= bake_image_exec;
+       ot->invoke= objects_bake_render_invoke;
+       ot->modal= objects_bake_render_modal;
+}
index 790db0d..9ef1faf 100644 (file)
@@ -1671,34 +1671,6 @@ void OBJECT_OT_shade_smooth(wmOperatorType *ot)
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
-/* bake */
-
-static int bake_image_exec(bContext *C, wmOperator *op)
-{
-       Scene *scene= CTX_data_scene(C);
-       char *error_msg= NULL;
-       objects_bake_render(scene, 0, &error_msg);
-
-       if(error_msg) {
-               BKE_report(op->reports, RPT_ERROR, error_msg);
-               return OPERATOR_CANCELLED;
-       }
-       else {
-               WM_event_add_notifier(C, NC_SCENE|ND_RENDER_RESULT, scene);
-               return OPERATOR_FINISHED;
-       }
-}
-
-void OBJECT_OT_bake_image(wmOperatorType *ot)
-{
-       /* identifiers */
-       ot->name= "Bake";
-       ot->description= "Bake selected objects.";
-       ot->idname= "OBJECT_OT_bake_image";
-
-       /* api callbacks */
-       ot->exec= bake_image_exec;
-}
 
 /* ********************** */
 
index c5bb61b..10ff93c 100644 (file)
@@ -203,5 +203,8 @@ void OBJECT_OT_shape_key_move(struct wmOperatorType *ot);
 void OBJECT_OT_group_add(struct wmOperatorType *ot);
 void OBJECT_OT_group_remove(struct wmOperatorType *ot);
 
+/* object_bake.c */
+void OBJECT_OT_bake_image(wmOperatorType *ot);
+
 #endif /* ED_OBJECT_INTERN_H */
 
index 05eab65..eb2086f 100644 (file)
@@ -81,7 +81,6 @@ void ED_operatortypes_object(void)
        WM_operatortype_append(OBJECT_OT_restrictview_set);
        WM_operatortype_append(OBJECT_OT_shade_smooth);
        WM_operatortype_append(OBJECT_OT_shade_flat);
-       WM_operatortype_append(OBJECT_OT_bake_image);
 
        WM_operatortype_append(OBJECT_OT_parent_set);
        WM_operatortype_append(OBJECT_OT_parent_no_inverse_set);
@@ -197,6 +196,8 @@ void ED_operatortypes_object(void)
        WM_operatortype_append(OBJECT_OT_hook_assign);
        WM_operatortype_append(OBJECT_OT_hook_reset);
        WM_operatortype_append(OBJECT_OT_hook_recenter);
+
+       WM_operatortype_append(OBJECT_OT_bake_image);
 }
 
 void ED_operatormacros_object(void)
index a077357..4622962 100644 (file)
@@ -290,7 +290,7 @@ static void image_listener(ScrArea *sa, wmNotifier *wmn)
                                        break;
                        }
                        break;
-               case NC_IMAGE:  
+               case NC_IMAGE:
                        ED_area_tag_redraw(sa);
                        break;
                case NC_SPACE:  
index 2615be1..28d88e1 100644 (file)
@@ -197,7 +197,7 @@ struct Image;
 struct Object;
 
 void RE_shade_external(struct Render *re, struct ShadeInput *shi, struct ShadeResult *shr);
-int RE_bake_shade_all_selected(struct Render *re, int type, struct Object *actob);
+int RE_bake_shade_all_selected(struct Render *re, int type, struct Object *actob, short *do_update);
 struct Image *RE_bake_shade_get_image(void);
 
 #endif /* RE_SHADER_EXT_H */
index cae6c64..c55632b 100644 (file)
@@ -1988,6 +1988,8 @@ typedef struct BakeShade {
        char *rect_mask; /* bake pixel mask */
 
        float dxco[3], dyco[3];
+
+       short *do_update;
 } BakeShade;
 
 /* bake uses a char mask to know what has been baked */
@@ -2587,6 +2589,11 @@ static void *do_bake_thread(void *bs_v)
                /* fast threadsafe break test */
                if(R.test_break(R.tbh))
                        break;
+
+               /* access is not threadsafe but since its just true/false probably ok
+                * only used for interactive baking */
+               if(bs->do_update)
+                       *bs->do_update= TRUE;
        }
        bs->ready= 1;
        
@@ -2596,7 +2603,7 @@ static void *do_bake_thread(void *bs_v)
 /* using object selection tags, the faces with UV maps get baked */
 /* render should have been setup */
 /* returns 0 if nothing was handled */
-int RE_bake_shade_all_selected(Render *re, int type, Object *actob)
+int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_update)
 {
        BakeShade handles[BLENDER_MAX_THREADS];
        ListBase threads;
@@ -2645,6 +2652,8 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob)
                handles[a].zspan= MEM_callocN(sizeof(ZSpan), "zspan for bake");
                
                handles[a].usemask = usemask;
+
+               handles[a].do_update = do_update; /* use to tell the view to update */
                
                BLI_insert_thread(&threads, &handles[a]);
        }