376f2ed294b60eb8e641fc7c5fe8bcc9482eb113
[blender.git] / source / blender / editors / object / object_bake.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2004 by Blender Foundation
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): Morten Mikkelsen,
24  *                 Sergey Sharybin
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 /** \file blender/editors/object/object_bake.c
30  *  \ingroup edobj
31  */
32
33 #include <string.h>
34
35 #include "MEM_guardedalloc.h"
36
37 #include "DNA_scene_types.h"
38 #include "DNA_screen_types.h"
39 #include "DNA_space_types.h"
40 #include "DNA_world_types.h"
41 #include "DNA_object_types.h"
42 #include "DNA_mesh_types.h"
43 #include "DNA_meshdata_types.h"
44
45 #include "BLI_blenlib.h"
46 #include "BLI_threads.h"
47 #include "BLI_utildefines.h"
48 #include "BLI_math.h"
49 #include "BLI_math_geom.h"
50
51 #include "BKE_blender.h"
52 #include "BKE_ccg.h"
53 #include "BKE_screen.h"
54 #include "BKE_context.h"
55 #include "BKE_global.h"
56 #include "BKE_image.h"
57 #include "BKE_main.h"
58 #include "BKE_multires.h"
59 #include "BKE_report.h"
60 #include "BKE_cdderivedmesh.h"
61 #include "BKE_modifier.h"
62 #include "BKE_DerivedMesh.h"
63 #include "BKE_subsurf.h"
64 #include "BKE_depsgraph.h"
65 #include "BKE_mesh.h"
66 #include "BKE_scene.h"
67
68 #include "RE_pipeline.h"
69 #include "RE_shader_ext.h"
70 #include "RE_multires_bake.h"
71
72 #include "PIL_time.h"
73
74 #include "IMB_imbuf_types.h"
75 #include "IMB_imbuf.h"
76 #include "IMB_colormanagement.h"
77
78 #include "GPU_draw.h" /* GPU_free_image */
79
80 #include "WM_api.h"
81 #include "WM_types.h"
82
83 #include "ED_object.h"
84
85 #include "object_intern.h"
86
87 /* ****************** multires BAKING ********************** */
88
89 /* holder of per-object data needed for bake job
90  * needed to make job totally thread-safe */
91 typedef struct MultiresBakerJobData {
92         struct MultiresBakerJobData *next, *prev;
93         DerivedMesh *lores_dm, *hires_dm;
94         int simple, lvl, tot_lvl;
95         ListBase images;
96 } MultiresBakerJobData;
97
98 /* data passing to multires-baker job */
99 typedef struct {
100         ListBase data;
101         int bake_clear, bake_filter;
102         short mode, use_lores_mesh;
103         int number_of_rays;
104         float bias;
105         int raytrace_structure;
106         int octree_resolution;
107         int threads;
108 } MultiresBakeJob;
109
110 static bool multiresbake_check(bContext *C, wmOperator *op)
111 {
112         Scene *scene = CTX_data_scene(C);
113         Object *ob;
114         Mesh *me;
115         MultiresModifierData *mmd;
116         bool ok = true;
117         int a;
118
119         CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
120         {
121                 ob = base->object;
122
123                 if (ob->type != OB_MESH) {
124                         BKE_report(op->reports, RPT_ERROR, "Baking of multires data only works with an active mesh object");
125
126                         ok = false;
127                         break;
128                 }
129
130                 me = (Mesh *)ob->data;
131                 mmd = get_multires_modifier(scene, ob, 0);
132
133                 /* Multi-resolution should be and be last in the stack */
134                 if (ok && mmd) {
135                         ModifierData *md;
136
137                         ok = mmd->totlvl > 0;
138
139                         for (md = (ModifierData *)mmd->modifier.next; md && ok; md = md->next) {
140                                 if (modifier_isEnabled(scene, md, eModifierMode_Realtime)) {
141                                         ok = false;
142                                 }
143                         }
144                 }
145                 else {
146                         ok = false;
147                 }
148
149                 if (!ok) {
150                         BKE_report(op->reports, RPT_ERROR, "Multires data baking requires multi-resolution object");
151
152                         break;
153                 }
154
155                 if (mmd->lvl == 0) {
156                         BKE_report(op->reports, RPT_ERROR, "Multires data baking is not supported for preview subdivision level 0");
157                         ok = false;
158                         break;
159                 }
160
161                 if (!me->mtpoly) {
162                         BKE_report(op->reports, RPT_ERROR, "Mesh should be unwrapped before multires data baking");
163
164                         ok = false;
165                 }
166                 else {
167                         a = me->totpoly;
168                         while (ok && a--) {
169                                 Image *ima = me->mtpoly[a].tpage;
170
171                                 if (!ima) {
172                                         BKE_report(op->reports, RPT_ERROR, "You should have active texture to use multires baker");
173
174                                         ok = false;
175                                 }
176                                 else {
177                                         ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
178
179                                         if (!ibuf) {
180                                                 BKE_report(op->reports, RPT_ERROR, "Baking should happen to image with image buffer");
181
182                                                 ok = false;
183                                         }
184                                         else {
185                                                 if (ibuf->rect == NULL && ibuf->rect_float == NULL)
186                                                         ok = false;
187
188                                                 if (ibuf->rect_float && !(ibuf->channels == 0 || ibuf->channels == 4))
189                                                         ok = false;
190
191                                                 if (!ok)
192                                                         BKE_report(op->reports, RPT_ERROR, "Baking to unsupported image type");
193                                         }
194
195                                         BKE_image_release_ibuf(ima, ibuf, NULL);
196                                 }
197                         }
198                 }
199
200                 if (!ok)
201                         break;
202         }
203         CTX_DATA_END;
204
205         return ok;
206 }
207
208 static DerivedMesh *multiresbake_create_loresdm(Scene *scene, Object *ob, int *lvl)
209 {
210         DerivedMesh *dm;
211         MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0);
212         Mesh *me = (Mesh *)ob->data;
213
214         *lvl = mmd->lvl;
215
216         if (*lvl == 0) {
217                 DerivedMesh *tmp_dm = CDDM_from_mesh(me, ob);
218
219                 DM_set_only_copy(tmp_dm, CD_MASK_BAREMESH | CD_MASK_MTFACE);
220
221                 dm = CDDM_copy(tmp_dm);
222                 tmp_dm->release(tmp_dm);
223         }
224         else {
225                 MultiresModifierData tmp_mmd = *mmd;
226                 DerivedMesh *cddm = CDDM_from_mesh(me, ob);
227
228                 DM_set_only_copy(cddm, CD_MASK_BAREMESH | CD_MASK_MTFACE);
229
230                 tmp_mmd.lvl = *lvl;
231                 tmp_mmd.sculptlvl = *lvl;
232                 dm = multires_make_derived_from_derived(cddm, &tmp_mmd, ob, 0);
233                 cddm->release(cddm);
234         }
235
236         return dm;
237 }
238
239 static DerivedMesh *multiresbake_create_hiresdm(Scene *scene, Object *ob, int *lvl, int *simple)
240 {
241         Mesh *me = (Mesh *)ob->data;
242         MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0);
243         MultiresModifierData tmp_mmd = *mmd;
244         DerivedMesh *cddm = CDDM_from_mesh(me, ob);
245         DerivedMesh *dm;
246
247         DM_set_only_copy(cddm, CD_MASK_BAREMESH);
248
249         /* TODO: DM_set_only_copy wouldn't set mask for loop and poly data,
250          *       but we really need BAREMESH only to save lots of memory
251          */
252         CustomData_set_only_copy(&cddm->loopData, CD_MASK_BAREMESH);
253         CustomData_set_only_copy(&cddm->polyData, CD_MASK_BAREMESH);
254
255         *lvl = mmd->totlvl;
256         *simple = mmd->simple;
257
258         tmp_mmd.lvl = mmd->totlvl;
259         tmp_mmd.sculptlvl = mmd->totlvl;
260         dm = multires_make_derived_from_derived(cddm, &tmp_mmd, ob, 0);
261         cddm->release(cddm);
262
263         return dm;
264 }
265
266 typedef enum ClearFlag {
267         CLEAR_TANGENT_NORMAL = 1,
268         CLEAR_DISPLACEMENT = 2
269 } ClearFlag;
270
271
272 static void clear_single_image(Image *image, ClearFlag flag)
273 {
274         const float vec_alpha[4] = {0.0f, 0.0f, 0.0f, 0.0f};
275         const float vec_solid[4] = {0.0f, 0.0f, 0.0f, 1.0f};
276         const float nor_alpha[4] = {0.5f, 0.5f, 1.0f, 0.0f};
277         const float nor_solid[4] = {0.5f, 0.5f, 1.0f, 1.0f};
278         const float disp_alpha[4] = {0.5f, 0.5f, 0.5f, 0.0f};
279         const float disp_solid[4] = {0.5f, 0.5f, 0.5f, 1.0f};
280
281         if ((image->id.flag & LIB_DOIT) == 0) {
282                 ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, NULL);
283
284                 if (flag == CLEAR_TANGENT_NORMAL)
285                         IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? nor_alpha : nor_solid);
286                 else if (flag == CLEAR_DISPLACEMENT)
287                         IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? disp_alpha : disp_solid);
288                 else
289                         IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? vec_alpha : vec_solid);
290
291                 image->id.flag |= LIB_DOIT;
292
293                 BKE_image_release_ibuf(image, ibuf, NULL);
294         }
295 }
296
297 static void clear_images(MTFace *mtface, int totface, ClearFlag flag)
298 {
299         int a;
300
301         for (a = 0; a < totface; a++) {
302                 mtface[a].tpage->id.flag &= ~LIB_DOIT;
303         }
304
305         for (a = 0; a < totface; a++) {
306                 clear_single_image(mtface[a].tpage, flag);
307         }
308
309         for (a = 0; a < totface; a++) {
310                 mtface[a].tpage->id.flag &= ~LIB_DOIT;
311         }
312 }
313
314 static void clear_images_poly(MTexPoly *mtpoly, int totpoly, ClearFlag flag)
315 {
316         int a;
317
318         for (a = 0; a < totpoly; a++) {
319                 mtpoly[a].tpage->id.flag &= ~LIB_DOIT;
320         }
321
322         for (a = 0; a < totpoly; a++) {
323                 clear_single_image(mtpoly[a].tpage, flag);
324         }
325
326         for (a = 0; a < totpoly; a++) {
327                 mtpoly[a].tpage->id.flag &= ~LIB_DOIT;
328         }
329 }
330
331 static int multiresbake_image_exec_locked(bContext *C, wmOperator *op)
332 {
333         Object *ob;
334         Scene *scene = CTX_data_scene(C);
335         int objects_baked = 0;
336
337         if (!multiresbake_check(C, op))
338                 return OPERATOR_CANCELLED;
339
340         if (scene->r.bake_flag & R_BAKE_CLEAR) {  /* clear images */
341                 CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
342                 {
343                         Mesh *me;
344                         ClearFlag clear_flag = 0;
345
346                         ob = base->object;
347                         me = (Mesh *)ob->data;
348
349                         if (scene->r.bake_mode == RE_BAKE_NORMALS) {
350                                 clear_flag = CLEAR_TANGENT_NORMAL;
351                         }
352                         else if (scene->r.bake_mode == RE_BAKE_DISPLACEMENT) {
353                                 clear_flag = CLEAR_DISPLACEMENT;
354                         }
355
356                         clear_images(me->mtface, me->totface, clear_flag);
357                         clear_images_poly(me->mtpoly, me->totpoly, clear_flag);
358                 }
359                 CTX_DATA_END;
360         }
361
362         CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
363         {
364                 MultiresBakeRender bkr = {NULL};
365
366                 ob = base->object;
367
368                 multires_force_update(ob);
369
370                 /* copy data stored in job descriptor */
371                 bkr.bake_filter = scene->r.bake_filter;
372                 bkr.mode = scene->r.bake_mode;
373                 bkr.use_lores_mesh = scene->r.bake_flag & R_BAKE_LORES_MESH;
374                 bkr.bias = scene->r.bake_biasdist;
375                 bkr.number_of_rays = scene->r.bake_samples;
376                 bkr.raytrace_structure = scene->r.raytrace_structure;
377                 bkr.octree_resolution = scene->r.ocres;
378                 bkr.threads = BKE_scene_num_threads(scene);
379
380                 /* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */
381                 bkr.hires_dm = multiresbake_create_hiresdm(scene, ob, &bkr.tot_lvl, &bkr.simple);
382                 bkr.lores_dm = multiresbake_create_loresdm(scene, ob, &bkr.lvl);
383
384                 RE_multires_bake_images(&bkr);
385
386                 BLI_freelistN(&bkr.image);
387
388                 bkr.lores_dm->release(bkr.lores_dm);
389                 bkr.hires_dm->release(bkr.hires_dm);
390
391                 objects_baked++;
392         }
393         CTX_DATA_END;
394
395         if (!objects_baked)
396                 BKE_report(op->reports, RPT_ERROR, "No objects found to bake from");
397
398         return OPERATOR_FINISHED;
399 }
400
401 /* Multiresbake adopted for job-system executing */
402 static void init_multiresbake_job(bContext *C, MultiresBakeJob *bkj)
403 {
404         Scene *scene = CTX_data_scene(C);
405         Object *ob;
406
407         /* backup scene settings, so their changing in UI would take no effect on baker */
408         bkj->bake_filter = scene->r.bake_filter;
409         bkj->mode = scene->r.bake_mode;
410         bkj->use_lores_mesh = scene->r.bake_flag & R_BAKE_LORES_MESH;
411         bkj->bake_clear = scene->r.bake_flag & R_BAKE_CLEAR;
412         bkj->bias = scene->r.bake_biasdist;
413         bkj->number_of_rays = scene->r.bake_samples;
414         bkj->raytrace_structure = scene->r.raytrace_structure;
415         bkj->octree_resolution = scene->r.ocres;
416         bkj->threads = BKE_scene_num_threads(scene);
417
418         CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
419         {
420                 MultiresBakerJobData *data;
421                 int lvl;
422
423                 ob = base->object;
424
425                 multires_force_update(ob);
426
427                 data = MEM_callocN(sizeof(MultiresBakerJobData), "multiresBaker derivedMesh_data");
428
429                 /* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */
430                 data->hires_dm = multiresbake_create_hiresdm(scene, ob, &data->tot_lvl, &data->simple);
431                 data->lores_dm = multiresbake_create_loresdm(scene, ob, &lvl);
432                 data->lvl = lvl;
433
434                 BLI_addtail(&bkj->data, data);
435         }
436         CTX_DATA_END;
437 }
438
439 static void multiresbake_startjob(void *bkv, short *stop, short *do_update, float *progress)
440 {
441         MultiresBakerJobData *data;
442         MultiresBakeJob *bkj = bkv;
443         int baked_objects = 0, tot_obj;
444
445         tot_obj = BLI_countlist(&bkj->data);
446
447         if (bkj->bake_clear) {  /* clear images */
448                 for (data = bkj->data.first; data; data = data->next) {
449                         DerivedMesh *dm = data->lores_dm;
450                         MTFace *mtface = CustomData_get_layer(&dm->faceData, CD_MTFACE);
451                         ClearFlag clear_flag = 0;
452
453                         if (bkj->mode == RE_BAKE_NORMALS) {
454                                 clear_flag = CLEAR_TANGENT_NORMAL;
455                         }
456                         else if (bkj->mode == RE_BAKE_DISPLACEMENT) {
457                                 clear_flag = CLEAR_DISPLACEMENT;
458                         }
459
460                         clear_images(mtface, dm->getNumTessFaces(dm), clear_flag);
461                 }
462         }
463
464         for (data = bkj->data.first; data; data = data->next) {
465                 MultiresBakeRender bkr = {NULL};
466
467                 /* copy data stored in job descriptor */
468                 bkr.bake_filter = bkj->bake_filter;
469                 bkr.mode = bkj->mode;
470                 bkr.use_lores_mesh = bkj->use_lores_mesh;
471
472                 /* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */
473                 bkr.lores_dm = data->lores_dm;
474                 bkr.hires_dm = data->hires_dm;
475                 bkr.tot_lvl = data->tot_lvl;
476                 bkr.lvl = data->lvl;
477                 bkr.simple = data->simple;
478
479                 /* needed for proper progress bar */
480                 bkr.tot_obj = tot_obj;
481                 bkr.baked_objects = baked_objects;
482
483                 bkr.stop = stop;
484                 bkr.do_update = do_update;
485                 bkr.progress = progress;
486
487                 bkr.bias = bkj->bias;
488                 bkr.number_of_rays = bkj->number_of_rays;
489                 bkr.raytrace_structure = bkj->raytrace_structure;
490                 bkr.octree_resolution = bkj->octree_resolution;
491                 bkr.threads = bkj->threads;
492
493                 RE_multires_bake_images(&bkr);
494
495                 data->images = bkr.image;
496
497                 baked_objects++;
498         }
499 }
500
501 static void multiresbake_freejob(void *bkv)
502 {
503         MultiresBakeJob *bkj = bkv;
504         MultiresBakerJobData *data, *next;
505         LinkData *link;
506
507         data = bkj->data.first;
508         while (data) {
509                 next = data->next;
510                 data->lores_dm->release(data->lores_dm);
511                 data->hires_dm->release(data->hires_dm);
512
513                 /* delete here, since this delete will be called from main thread */
514                 for (link = data->images.first; link; link = link->next) {
515                         Image *ima = (Image *)link->data;
516                         GPU_free_image(ima);
517                 }
518
519                 BLI_freelistN(&data->images);
520
521                 MEM_freeN(data);
522                 data = next;
523         }
524
525         MEM_freeN(bkj);
526 }
527
528 static int multiresbake_image_exec(bContext *C, wmOperator *op)
529 {
530         Scene *scene = CTX_data_scene(C);
531         MultiresBakeJob *bkr;
532         wmJob *wm_job;
533
534         if (!multiresbake_check(C, op))
535                 return OPERATOR_CANCELLED;
536
537         bkr = MEM_callocN(sizeof(MultiresBakeJob), "MultiresBakeJob data");
538         init_multiresbake_job(C, bkr);
539
540         if (!bkr->data.first) {
541                 BKE_report(op->reports, RPT_ERROR, "No objects found to bake from");
542                 return OPERATOR_CANCELLED;
543         }
544
545         /* setup job */
546         wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Multires Bake",
547                              WM_JOB_EXCL_RENDER | WM_JOB_PRIORITY | WM_JOB_PROGRESS, WM_JOB_TYPE_OBJECT_BAKE_TEXTURE);
548         WM_jobs_customdata_set(wm_job, bkr, multiresbake_freejob);
549         WM_jobs_timer(wm_job, 0.2, NC_IMAGE, 0); /* TODO - only draw bake image, can we enforce this */
550         WM_jobs_callbacks(wm_job, multiresbake_startjob, NULL, NULL, NULL);
551
552         G.is_break = FALSE;
553
554         WM_jobs_start(CTX_wm_manager(C), wm_job);
555         WM_cursor_wait(0);
556
557         /* add modal handler for ESC */
558         WM_event_add_modal_handler(C, op);
559
560         return OPERATOR_RUNNING_MODAL;
561 }
562
563 /* ****************** render BAKING ********************** */
564
565 /* threaded break test */
566 static int thread_break(void *UNUSED(arg))
567 {
568         return G.is_break;
569 }
570
571 typedef struct BakeRender {
572         Render *re;
573         Main *main;
574         Scene *scene;
575         struct Object *actob;
576         int result, ready;
577
578         ReportList *reports;
579
580         short *stop;
581         short *do_update;
582         float *progress;
583         
584         ListBase threads;
585
586         /* backup */
587         short prev_wo_amb_occ;
588         short prev_r_raytrace;
589
590         /* for redrawing */
591         ScrArea *sa;
592 } BakeRender;
593
594 /* use by exec and invoke */
595 static int test_bake_internal(bContext *C, ReportList *reports)
596 {
597         Scene *scene = CTX_data_scene(C);
598
599         if ((scene->r.bake_flag & R_BAKE_TO_ACTIVE) && CTX_data_active_object(C) == NULL) {
600                 BKE_report(reports, RPT_ERROR, "No active object");
601         }
602         else if (scene->r.bake_mode == RE_BAKE_AO && scene->world == NULL) {
603                 BKE_report(reports, RPT_ERROR, "No world set up");
604         }
605         else {
606                 return 1;
607         }
608
609         return 0;
610 }
611
612 static void init_bake_internal(BakeRender *bkr, bContext *C)
613 {
614         Scene *scene = CTX_data_scene(C);
615         bScreen *sc = CTX_wm_screen(C);
616
617         /* get editmode results */
618         ED_object_editmode_load(CTX_data_edit_object(C));
619
620         bkr->sa = sc ? BKE_screen_find_big_area(sc, SPACE_IMAGE, 10) : NULL; /* can be NULL */
621         bkr->main = CTX_data_main(C);
622         bkr->scene = scene;
623         bkr->actob = (scene->r.bake_flag & R_BAKE_TO_ACTIVE) ? OBACT : NULL;
624         bkr->re = RE_NewRender("_Bake View_");
625
626         if (scene->r.bake_mode == RE_BAKE_AO) {
627                 /* If raytracing or AO is disabled, switch it on temporarily for baking. */
628                 bkr->prev_wo_amb_occ = (scene->world->mode & WO_AMB_OCC) != 0;
629                 scene->world->mode |= WO_AMB_OCC;
630         }
631         if (scene->r.bake_mode == RE_BAKE_AO || bkr->actob) {
632                 bkr->prev_r_raytrace = (scene->r.mode & R_RAYTRACE) != 0;
633                 scene->r.mode |= R_RAYTRACE;
634         }
635 }
636
637 static void finish_bake_internal(BakeRender *bkr)
638 {
639         Image *ima;
640
641         RE_Database_Free(bkr->re);
642
643         /* restore raytrace and AO */
644         if (bkr->scene->r.bake_mode == RE_BAKE_AO)
645                 if (bkr->prev_wo_amb_occ == 0)
646                         bkr->scene->world->mode &= ~WO_AMB_OCC;
647
648         if (bkr->scene->r.bake_mode == RE_BAKE_AO || bkr->actob)
649                 if (bkr->prev_r_raytrace == 0)
650                         bkr->scene->r.mode &= ~R_RAYTRACE;
651
652         /* force OpenGL reload and mipmap recalc */
653         if ((bkr->scene->r.bake_flag & R_BAKE_VCOL) == 0) {
654                 for (ima = G.main->image.first; ima; ima = ima->id.next) {
655                         ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
656
657                         /* some of the images could have been changed during bake,
658                          * so recreate mipmaps regardless bake result status
659                          */
660                         if (ima->ok == IMA_OK_LOADED) {
661                                 if (ibuf) {
662                                         if (ibuf->userflags & IB_BITMAPDIRTY) {
663                                                 GPU_free_image(ima);
664                                                 imb_freemipmapImBuf(ibuf);
665                                         }
666
667                                         /* invalidate display buffers for changed images */
668                                         if (ibuf->userflags & IB_BITMAPDIRTY)
669                                                 ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
670                                 }
671                         }
672
673                         /* freed when baking is done, but if its canceled we need to free here */
674                         if (ibuf) {
675                                 if (ibuf->userdata) {
676                                         BakeImBufuserData *userdata = (BakeImBufuserData *) ibuf->userdata;
677                                         if (userdata->mask_buffer)
678                                                 MEM_freeN(userdata->mask_buffer);
679                                         if (userdata->displacement_buffer)
680                                                 MEM_freeN(userdata->displacement_buffer);
681                                         MEM_freeN(userdata);
682                                         ibuf->userdata = NULL;
683                                 }
684                         }
685
686                         BKE_image_release_ibuf(ima, ibuf, NULL);
687                 }
688         }
689
690         if (bkr->scene->r.bake_flag & R_BAKE_VCOL) {
691                 /* update all tagged meshes */
692                 Mesh *me;
693                 BLI_assert(BLI_thread_is_main());
694                 for (me = G.main->mesh.first; me; me = me->id.next) {
695                         if (me->id.flag & LIB_DOIT) {
696                                 DAG_id_tag_update(&me->id, OB_RECALC_DATA);
697                                 BKE_mesh_tessface_clear(me);
698                         }
699                 }
700         }
701
702 }
703
704 static void *do_bake_render(void *bake_v)
705 {
706         BakeRender *bkr = bake_v;
707
708         bkr->result = RE_bake_shade_all_selected(bkr->re, bkr->scene->r.bake_mode, bkr->actob, NULL, bkr->progress);
709         bkr->ready = 1;
710
711         return NULL;
712 }
713
714 static void bake_startjob(void *bkv, short *stop, short *do_update, float *progress)
715 {
716         BakeRender *bkr = bkv;
717         Scene *scene = bkr->scene;
718         Main *bmain = bkr->main;
719
720         bkr->stop = stop;
721         bkr->do_update = do_update;
722         bkr->progress = progress;
723
724         RE_test_break_cb(bkr->re, NULL, thread_break);
725         G.is_break = FALSE;   /* blender_test_break uses this global */
726
727         RE_Database_Baking(bkr->re, bmain, scene, scene->lay, scene->r.bake_mode, bkr->actob);
728
729         /* baking itself is threaded, cannot use test_break in threads. we also update optional imagewindow */
730         bkr->result = RE_bake_shade_all_selected(bkr->re, scene->r.bake_mode, bkr->actob, bkr->do_update, bkr->progress);
731 }
732
733 static void bake_update(void *bkv)
734 {
735         BakeRender *bkr = bkv;
736
737         if (bkr->sa && bkr->sa->spacetype == SPACE_IMAGE) { /* in case the user changed while baking */
738                 SpaceImage *sima = bkr->sa->spacedata.first;
739                 if (sima)
740                         sima->image = RE_bake_shade_get_image();
741         }
742 }
743
744 static void bake_freejob(void *bkv)
745 {
746         BakeRender *bkr = bkv;
747         finish_bake_internal(bkr);
748
749         if (bkr->result == BAKE_RESULT_NO_OBJECTS)
750                 BKE_report(bkr->reports, RPT_ERROR, "No objects or images found to bake to");
751         else if (bkr->result == BAKE_RESULT_FEEDBACK_LOOP)
752                 BKE_report(bkr->reports, RPT_WARNING, "Circular reference in texture stack");
753
754         MEM_freeN(bkr);
755         G.is_rendering = FALSE;
756 }
757
758 /* catch esc */
759 static int objects_bake_render_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
760 {
761         /* no running blender, remove handler and pass through */
762         if (0 == WM_jobs_test(CTX_wm_manager(C), CTX_data_scene(C), WM_JOB_TYPE_OBJECT_BAKE_TEXTURE))
763                 return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
764
765         /* running render */
766         switch (event->type) {
767                 case ESCKEY:
768                         return OPERATOR_RUNNING_MODAL;
769                         break;
770         }
771         return OPERATOR_PASS_THROUGH;
772 }
773
774 static int is_multires_bake(Scene *scene)
775 {
776         if (ELEM3(scene->r.bake_mode, RE_BAKE_NORMALS, RE_BAKE_DISPLACEMENT, RE_BAKE_AO))
777                 return scene->r.bake_flag & R_BAKE_MULTIRES;
778
779         return 0;
780 }
781
782 static int objects_bake_render_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(_event))
783 {
784         Scene *scene = CTX_data_scene(C);
785         int result = OPERATOR_CANCELLED;
786
787         if (is_multires_bake(scene)) {
788                 result = multiresbake_image_exec(C, op);
789         }
790         else {
791                 /* only one render job at a time */
792                 if (WM_jobs_test(CTX_wm_manager(C), scene, WM_JOB_TYPE_OBJECT_BAKE_TEXTURE))
793                         return OPERATOR_CANCELLED;
794
795                 if (test_bake_internal(C, op->reports) == 0) {
796                         return OPERATOR_CANCELLED;
797                 }
798                 else {
799                         BakeRender *bkr = MEM_callocN(sizeof(BakeRender), "render bake");
800                         wmJob *wm_job;
801
802                         init_bake_internal(bkr, C);
803                         bkr->reports = op->reports;
804
805                         /* setup job */
806                         wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Texture Bake",
807                                              WM_JOB_EXCL_RENDER | WM_JOB_PRIORITY | WM_JOB_PROGRESS, WM_JOB_TYPE_OBJECT_BAKE_TEXTURE);
808                         WM_jobs_customdata_set(wm_job, bkr, bake_freejob);
809                         WM_jobs_timer(wm_job, 0.2, NC_IMAGE, 0); /* TODO - only draw bake image, can we enforce this */
810                         WM_jobs_callbacks(wm_job, bake_startjob, NULL, bake_update, NULL);
811
812                         G.is_break = FALSE;
813                         G.is_rendering = TRUE;
814
815                         WM_jobs_start(CTX_wm_manager(C), wm_job);
816
817                         WM_cursor_wait(0);
818
819                         /* add modal handler for ESC */
820                         WM_event_add_modal_handler(C, op);
821                 }
822
823                 result = OPERATOR_RUNNING_MODAL;
824         }
825
826         WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, scene);
827
828         return result;
829 }
830
831
832 static int bake_image_exec(bContext *C, wmOperator *op)
833 {
834         Main *bmain = CTX_data_main(C);
835         Scene *scene = CTX_data_scene(C);
836         int result = OPERATOR_CANCELLED;
837
838         if (is_multires_bake(scene)) {
839                 result = multiresbake_image_exec_locked(C, op);
840         }
841         else {
842                 if (test_bake_internal(C, op->reports) == 0) {
843                         return OPERATOR_CANCELLED;
844                 }
845                 else {
846                         ListBase threads;
847                         BakeRender bkr = {NULL};
848
849                         init_bake_internal(&bkr, C);
850                         bkr.reports = op->reports;
851
852                         RE_test_break_cb(bkr.re, NULL, thread_break);
853                         G.is_break = FALSE;   /* blender_test_break uses this global */
854
855                         RE_Database_Baking(bkr.re, bmain, scene, scene->lay, scene->r.bake_mode, (scene->r.bake_flag & R_BAKE_TO_ACTIVE) ? OBACT : NULL);
856
857                         /* baking itself is threaded, cannot use test_break in threads  */
858                         BLI_init_threads(&threads, do_bake_render, 1);
859                         bkr.ready = 0;
860                         BLI_insert_thread(&threads, &bkr);
861
862                         while (bkr.ready == 0) {
863                                 PIL_sleep_ms(50);
864                                 if (bkr.ready)
865                                         break;
866
867                                 /* used to redraw in 2.4x but this is just for exec in 2.5 */
868                                 if (!G.background)
869                                         blender_test_break();
870                         }
871                         BLI_end_threads(&threads);
872
873                         if (bkr.result == BAKE_RESULT_NO_OBJECTS)
874                                 BKE_report(op->reports, RPT_ERROR, "No valid images found to bake to");
875                         else if (bkr.result == BAKE_RESULT_FEEDBACK_LOOP)
876                                 BKE_report(op->reports, RPT_ERROR, "Circular reference in texture stack");
877
878                         finish_bake_internal(&bkr);
879
880                         result = OPERATOR_FINISHED;
881                 }
882         }
883
884         WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, scene);
885
886         return result;
887 }
888
889 void OBJECT_OT_bake_image(wmOperatorType *ot)
890 {
891         /* identifiers */
892         ot->name = "Bake";
893         ot->description = "Bake image textures of selected objects";
894         ot->idname = "OBJECT_OT_bake_image";
895
896         /* api callbacks */
897         ot->exec = bake_image_exec;
898         ot->invoke = objects_bake_render_invoke;
899         ot->modal = objects_bake_render_modal;
900 }