diff options
author | Campbell Barton <ideasman42@gmail.com> | 2009-12-30 17:37:25 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2009-12-30 17:37:25 +0300 |
commit | 57cd505d3f29b83bea74f4132455f00b248d5808 (patch) | |
tree | eef3278dc77873f421201d806ad2411095f7e3a1 | |
parent | a4913896b8f42be9bdde6ebc320a4955578a8f9e (diff) |
bake is now modal like render and updates the image view while baking.
it also has an exec function which doesnt update (like render too)
-rw-r--r-- | source/blender/editors/include/ED_mesh.h | 2 | ||||
-rw-r--r-- | source/blender/editors/mesh/meshtools.c | 200 | ||||
-rw-r--r-- | source/blender/editors/object/object_bake.c | 341 | ||||
-rw-r--r-- | source/blender/editors/object/object_edit.c | 28 | ||||
-rw-r--r-- | source/blender/editors/object/object_intern.h | 3 | ||||
-rw-r--r-- | source/blender/editors/object/object_ops.c | 3 | ||||
-rw-r--r-- | source/blender/editors/space_image/space_image.c | 2 | ||||
-rw-r--r-- | source/blender/render/extern/include/RE_shader_ext.h | 2 | ||||
-rw-r--r-- | source/blender/render/intern/source/rendercore.c | 11 |
9 files changed, 358 insertions, 234 deletions
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 66c32b06f95..174447c0f9f 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -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); diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index 1feaa2dc83a..b52447e111f 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -76,16 +76,6 @@ #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 index 00000000000..4b02cd8e623 --- /dev/null +++ b/source/blender/editors/object/object_bake.c @@ -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; +} diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 790db0dc564..9ef1fafff82 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -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; -} /* ********************** */ diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index c5bb61b4403..10ff93c540f 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -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 */ diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 05eab6528fd..eb2086fe95d 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -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) diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index a077357d03e..4622962bac5 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -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: diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h index 2615be1440a..28d88e1f8b4 100644 --- a/source/blender/render/extern/include/RE_shader_ext.h +++ b/source/blender/render/extern/include/RE_shader_ext.h @@ -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 */ diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index cae6c640f8b..c55632b36dc 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -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]); } |