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