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