Cleanup: comment line length (editors)
[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         Main *bmain = CTX_data_main(C);
592         Scene *scene = CTX_data_scene(C);
593         bScreen *sc = CTX_wm_screen(C);
594
595         /* get editmode results */
596         ED_object_editmode_load(bmain, CTX_data_edit_object(C));
597
598         bkr->sa = sc ? BKE_screen_find_big_area(sc, SPACE_IMAGE, 10) : NULL; /* can be NULL */
599         bkr->main = bmain;
600         bkr->scene = scene;
601         bkr->actob = (scene->r.bake_flag & R_BAKE_TO_ACTIVE) ? OBACT : NULL;
602         bkr->re = RE_NewRender("_Bake View_");
603
604         if (scene->r.bake_mode == RE_BAKE_AO) {
605                 /* If raytracing or AO is disabled, switch it on temporarily for baking. */
606                 bkr->prev_wo_amb_occ = (scene->world->mode & WO_AMB_OCC) != 0;
607                 scene->world->mode |= WO_AMB_OCC;
608         }
609         if (scene->r.bake_mode == RE_BAKE_AO || bkr->actob) {
610                 bkr->prev_r_raytrace = (scene->r.mode & R_RAYTRACE) != 0;
611                 scene->r.mode |= R_RAYTRACE;
612         }
613 }
614
615 static void finish_bake_internal(BakeRender *bkr)
616 {
617         Image *ima;
618
619         RE_Database_Free(bkr->re);
620
621         /* restore raytrace and AO */
622         if (bkr->scene->r.bake_mode == RE_BAKE_AO)
623                 if (bkr->prev_wo_amb_occ == 0)
624                         bkr->scene->world->mode &= ~WO_AMB_OCC;
625
626         if (bkr->scene->r.bake_mode == RE_BAKE_AO || bkr->actob)
627                 if (bkr->prev_r_raytrace == 0)
628                         bkr->scene->r.mode &= ~R_RAYTRACE;
629
630         /* force OpenGL reload and mipmap recalc */
631         if ((bkr->scene->r.bake_flag & R_BAKE_VCOL) == 0) {
632                 for (ima = bkr->main->image.first; ima; ima = ima->id.next) {
633                         ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
634
635                         /* some of the images could have been changed during bake,
636                          * so recreate mipmaps regardless bake result status
637                          */
638                         if (ima->ok == IMA_OK_LOADED) {
639                                 if (ibuf) {
640                                         if (ibuf->userflags & IB_BITMAPDIRTY) {
641                                                 GPU_free_image(ima);
642                                                 imb_freemipmapImBuf(ibuf);
643                                         }
644
645                                         /* invalidate display buffers for changed images */
646                                         if (ibuf->userflags & IB_BITMAPDIRTY)
647                                                 ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
648                                 }
649                         }
650
651                         /* freed when baking is done, but if its canceled we need to free here */
652                         if (ibuf) {
653                                 if (ibuf->userdata) {
654                                         BakeImBufuserData *userdata = (BakeImBufuserData *) ibuf->userdata;
655                                         if (userdata->mask_buffer)
656                                                 MEM_freeN(userdata->mask_buffer);
657                                         if (userdata->displacement_buffer)
658                                                 MEM_freeN(userdata->displacement_buffer);
659                                         MEM_freeN(userdata);
660                                         ibuf->userdata = NULL;
661                                 }
662                         }
663
664                         BKE_image_release_ibuf(ima, ibuf, NULL);
665                         DAG_id_tag_update(&ima->id, 0);
666                 }
667         }
668
669         if (bkr->scene->r.bake_flag & R_BAKE_VCOL) {
670                 /* update all tagged meshes */
671                 Mesh *me;
672                 BLI_assert(BLI_thread_is_main());
673                 for (me = bkr->main->mesh.first; me; me = me->id.next) {
674                         if (me->id.tag & LIB_TAG_DOIT) {
675                                 DAG_id_tag_update(&me->id, OB_RECALC_DATA);
676                                 BKE_mesh_tessface_clear(me);
677                         }
678                 }
679         }
680
681 }
682
683 static void *do_bake_render(void *bake_v)
684 {
685         BakeRender *bkr = bake_v;
686
687         bkr->result = RE_bake_shade_all_selected(bkr->re, bkr->scene->r.bake_mode, bkr->actob, NULL, bkr->progress);
688         bkr->ready = 1;
689
690         return NULL;
691 }
692
693 static void bake_startjob(void *bkv, short *stop, short *do_update, float *progress)
694 {
695         BakeRender *bkr = bkv;
696         Scene *scene = bkr->scene;
697         Main *bmain = bkr->main;
698
699         bkr->stop = stop;
700         bkr->do_update = do_update;
701         bkr->progress = progress;
702
703         RE_test_break_cb(bkr->re, NULL, thread_break);
704         G.is_break = false;   /* BKE_blender_test_break uses this global */
705
706         RE_Database_Baking(bkr->re, bmain, scene, scene->lay, scene->r.bake_mode, bkr->actob);
707
708         /* baking itself is threaded, cannot use test_break in threads. we also update optional imagewindow */
709         bkr->result = RE_bake_shade_all_selected(bkr->re, scene->r.bake_mode, bkr->actob, bkr->do_update, bkr->progress);
710 }
711
712 static void bake_update(void *bkv)
713 {
714         BakeRender *bkr = bkv;
715
716         if (bkr->sa && bkr->sa->spacetype == SPACE_IMAGE) { /* in case the user changed while baking */
717                 SpaceImage *sima = bkr->sa->spacedata.first;
718                 if (sima)
719                         sima->image = RE_bake_shade_get_image();
720         }
721 }
722
723 static void bake_freejob(void *bkv)
724 {
725         BakeRender *bkr = bkv;
726         finish_bake_internal(bkr);
727
728         if (bkr->result == BAKE_RESULT_NO_OBJECTS)
729                 BKE_report(bkr->reports, RPT_ERROR, "No objects or images found to bake to");
730         else if (bkr->result == BAKE_RESULT_FEEDBACK_LOOP)
731                 BKE_report(bkr->reports, RPT_WARNING, "Circular reference in texture stack");
732
733         MEM_freeN(bkr);
734         G.is_rendering = false;
735 }
736
737 /* catch esc */
738 static int objects_bake_render_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
739 {
740         /* no running blender, remove handler and pass through */
741         if (0 == WM_jobs_test(CTX_wm_manager(C), CTX_data_scene(C), WM_JOB_TYPE_OBJECT_BAKE_TEXTURE))
742                 return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
743
744         /* running render */
745         switch (event->type) {
746                 case ESCKEY:
747                         return OPERATOR_RUNNING_MODAL;
748         }
749         return OPERATOR_PASS_THROUGH;
750 }
751
752 static bool is_multires_bake(Scene *scene)
753 {
754         if (ELEM(scene->r.bake_mode, RE_BAKE_NORMALS, RE_BAKE_DISPLACEMENT, RE_BAKE_DERIVATIVE, RE_BAKE_AO))
755                 return scene->r.bake_flag & R_BAKE_MULTIRES;
756
757         return 0;
758 }
759
760 static int objects_bake_render_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(_event))
761 {
762         Scene *scene = CTX_data_scene(C);
763         int result = OPERATOR_CANCELLED;
764
765         if (is_multires_bake(scene)) {
766                 result = multiresbake_image_exec(C, op);
767         }
768         else {
769                 /* only one render job at a time */
770                 if (WM_jobs_test(CTX_wm_manager(C), scene, WM_JOB_TYPE_OBJECT_BAKE_TEXTURE))
771                         return OPERATOR_CANCELLED;
772
773                 if (test_bake_internal(C, op->reports) == 0) {
774                         return OPERATOR_CANCELLED;
775                 }
776                 else {
777                         BakeRender *bkr = MEM_callocN(sizeof(BakeRender), "render bake");
778                         wmJob *wm_job;
779
780                         init_bake_internal(bkr, C);
781                         bkr->reports = op->reports;
782
783                         /* setup job */
784                         wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Texture Bake",
785                                              WM_JOB_EXCL_RENDER | WM_JOB_PRIORITY | WM_JOB_PROGRESS, WM_JOB_TYPE_OBJECT_BAKE_TEXTURE);
786                         WM_jobs_customdata_set(wm_job, bkr, bake_freejob);
787                         WM_jobs_timer(wm_job, 0.5, NC_IMAGE, 0); /* TODO - only draw bake image, can we enforce this */
788                         WM_jobs_callbacks(wm_job, bake_startjob, NULL, bake_update, NULL);
789
790                         G.is_break = false;
791                         G.is_rendering = true;
792
793                         WM_jobs_start(CTX_wm_manager(C), wm_job);
794
795                         WM_cursor_wait(0);
796
797                         /* add modal handler for ESC */
798                         WM_event_add_modal_handler(C, op);
799                 }
800
801                 result = OPERATOR_RUNNING_MODAL;
802         }
803
804         WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, scene);
805
806         return result;
807 }
808
809
810 static int bake_image_exec(bContext *C, wmOperator *op)
811 {
812         Main *bmain = CTX_data_main(C);
813         Scene *scene = CTX_data_scene(C);
814         int result = OPERATOR_CANCELLED;
815
816         if (is_multires_bake(scene)) {
817                 result = multiresbake_image_exec_locked(C, op);
818         }
819         else {
820                 if (test_bake_internal(C, op->reports) == 0) {
821                         return OPERATOR_CANCELLED;
822                 }
823                 else {
824                         ListBase threads;
825                         BakeRender bkr = {NULL};
826
827                         init_bake_internal(&bkr, C);
828                         bkr.reports = op->reports;
829
830                         RE_test_break_cb(bkr.re, NULL, thread_break);
831                         G.is_break = false;   /* BKE_blender_test_break uses this global */
832
833                         RE_Database_Baking(bkr.re, bmain, scene, scene->lay, scene->r.bake_mode, (scene->r.bake_flag & R_BAKE_TO_ACTIVE) ? OBACT : NULL);
834
835                         /* baking itself is threaded, cannot use test_break in threads  */
836                         BLI_threadpool_init(&threads, do_bake_render, 1);
837                         bkr.ready = 0;
838                         BLI_threadpool_insert(&threads, &bkr);
839
840                         while (bkr.ready == 0) {
841                                 PIL_sleep_ms(50);
842                                 if (bkr.ready)
843                                         break;
844
845                                 /* used to redraw in 2.4x but this is just for exec in 2.5 */
846                                 if (!G.background)
847                                         BKE_blender_test_break();
848                         }
849                         BLI_threadpool_end(&threads);
850
851                         if (bkr.result == BAKE_RESULT_NO_OBJECTS)
852                                 BKE_report(op->reports, RPT_ERROR, "No valid images found to bake to");
853                         else if (bkr.result == BAKE_RESULT_FEEDBACK_LOOP)
854                                 BKE_report(op->reports, RPT_ERROR, "Circular reference in texture stack");
855
856                         finish_bake_internal(&bkr);
857
858                         result = OPERATOR_FINISHED;
859                 }
860         }
861
862         WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, scene);
863
864         return result;
865 }
866
867 void OBJECT_OT_bake_image(wmOperatorType *ot)
868 {
869         /* identifiers */
870         ot->name = "Bake";
871         ot->description = "Bake image textures of selected objects";
872         ot->idname = "OBJECT_OT_bake_image";
873
874         /* api callbacks */
875         ot->exec = bake_image_exec;
876         ot->invoke = objects_bake_render_invoke;
877         ot->modal = objects_bake_render_modal;
878         ot->poll = ED_operator_object_active;
879 }