Merge branch 'master' into blender2.8
[blender.git] / source / blender / editors / object / object_bake_api.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):
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/editors/object/object_bake_api.c
29  *  \ingroup edobj
30  */
31
32
33 #include "MEM_guardedalloc.h"
34
35 #include "DNA_object_types.h"
36 #include "DNA_mesh_types.h"
37 #include "DNA_material_types.h"
38
39 #include "RNA_access.h"
40 #include "RNA_define.h"
41 #include "RNA_enum_types.h"
42
43 #include "BLI_listbase.h"
44 #include "BLI_string.h"
45 #include "BLI_fileops.h"
46 #include "BLI_math_geom.h"
47 #include "BLI_path_util.h"
48
49 #include "BKE_context.h"
50 #include "BKE_global.h"
51 #include "BKE_image.h"
52 #include "BKE_library.h"
53 #include "BKE_main.h"
54 #include "BKE_node.h"
55 #include "BKE_report.h"
56 #include "BKE_modifier.h"
57 #include "BKE_mesh.h"
58 #include "BKE_screen.h"
59 #include "BKE_depsgraph.h"
60
61 #include "RE_engine.h"
62 #include "RE_pipeline.h"
63
64 #include "IMB_imbuf_types.h"
65 #include "IMB_imbuf.h"
66 #include "IMB_colormanagement.h"
67
68 #include "WM_api.h"
69 #include "WM_types.h"
70
71 #include "ED_object.h"
72 #include "ED_screen.h"
73 #include "ED_uvedit.h"
74
75 #include "GPU_draw.h"
76
77 #include "object_intern.h"
78
79 /* prototypes */
80 static void bake_set_props(wmOperator *op, Scene *scene);
81
82 typedef struct BakeAPIRender {
83         Object *ob;
84         Main *main;
85         Scene *scene;
86         ReportList *reports;
87         ListBase selected_objects;
88
89         ScenePassType pass_type;
90         int pass_filter;
91         int margin;
92
93         int save_mode;
94
95         bool is_clear;
96         bool is_split_materials;
97         bool is_automatic_name;
98         bool is_selected_to_active;
99         bool is_cage;
100
101         float cage_extrusion;
102         int normal_space;
103         BakeNormalSwizzle normal_swizzle[3];
104
105         char uv_layer[MAX_CUSTOMDATA_LAYER_NAME];
106         char custom_cage[MAX_NAME];
107         char filepath[FILE_MAX];
108
109         int width;
110         int height;
111         const char *identifier;
112
113         int result;
114         bool ready;
115
116         /* callbacks */
117         Render *render;
118         float *progress;
119         short *do_update;
120
121         /* for redrawing */
122         ScrArea *sa;
123 } BakeAPIRender;
124
125 /* callbacks */
126
127 static void bake_progress_update(void *bjv, float progress)
128 {
129         BakeAPIRender *bj = bjv;
130
131         if (bj->progress && *bj->progress != progress) {
132                 *bj->progress = progress;
133
134                 /* make jobs timer to send notifier */
135                 *(bj->do_update) = true;
136         }
137 }
138
139 /* catch esc */
140 static int bake_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
141 {
142         /* no running blender, remove handler and pass through */
143         if (0 == WM_jobs_test(CTX_wm_manager(C), CTX_data_scene(C), WM_JOB_TYPE_OBJECT_BAKE))
144                 return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
145
146         /* running render */
147         switch (event->type) {
148                 case ESCKEY:
149                 {
150                         G.is_break = true;
151                         return OPERATOR_RUNNING_MODAL;
152                 }
153         }
154         return OPERATOR_PASS_THROUGH;
155 }
156
157 /* for exec() when there is no render job
158  * note: this wont check for the escape key being pressed, but doing so isnt threadsafe */
159 static int bake_break(void *UNUSED(rjv))
160 {
161         if (G.is_break)
162                 return 1;
163         return 0;
164 }
165
166
167 static void bake_update_image(ScrArea *sa, Image *image)
168 {
169         if (sa && sa->spacetype == SPACE_IMAGE) { /* in case the user changed while baking */
170                 SpaceImage *sima = sa->spacedata.first;
171                 if (sima)
172                         sima->image = image;
173         }
174 }
175
176 static bool write_internal_bake_pixels(
177         Image *image, BakePixel pixel_array[], float *buffer,
178         const int width, const int height, const int margin,
179         const bool is_clear, const bool is_noncolor)
180 {
181         ImBuf *ibuf;
182         void *lock;
183         bool is_float;
184         char *mask_buffer = NULL;
185         const size_t num_pixels = (size_t)width * (size_t)height;
186
187         ibuf = BKE_image_acquire_ibuf(image, NULL, &lock);
188
189         if (!ibuf)
190                 return false;
191
192         if (margin > 0 || !is_clear) {
193                 mask_buffer = MEM_callocN(sizeof(char) * num_pixels, "Bake Mask");
194                 RE_bake_mask_fill(pixel_array, num_pixels, mask_buffer);
195         }
196
197         is_float = (ibuf->flags & IB_rectfloat);
198
199         /* colormanagement conversions */
200         if (!is_noncolor) {
201                 const char *from_colorspace;
202                 const char *to_colorspace;
203
204                 from_colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_SCENE_LINEAR);
205
206                 if (is_float)
207                         to_colorspace = IMB_colormanagement_get_float_colorspace(ibuf);
208                 else
209                         to_colorspace = IMB_colormanagement_get_rect_colorspace(ibuf);
210
211                 if (from_colorspace != to_colorspace)
212                         IMB_colormanagement_transform(buffer, ibuf->x, ibuf->y, ibuf->channels, from_colorspace, to_colorspace, false);
213         }
214
215         /* populates the ImBuf */
216         if (is_clear) {
217                 if (is_float) {
218                         IMB_buffer_float_from_float(
219                                 ibuf->rect_float, buffer, ibuf->channels,
220                                 IB_PROFILE_LINEAR_RGB, IB_PROFILE_LINEAR_RGB, false,
221                                 ibuf->x, ibuf->y, ibuf->x, ibuf->x);
222                 }
223                 else {
224                         IMB_buffer_byte_from_float(
225                                 (unsigned char *) ibuf->rect, buffer, ibuf->channels, ibuf->dither,
226                                 IB_PROFILE_SRGB, IB_PROFILE_SRGB,
227                                 false, ibuf->x, ibuf->y, ibuf->x, ibuf->x);
228                 }
229         }
230         else {
231                 if (is_float) {
232                         IMB_buffer_float_from_float_mask(
233                                 ibuf->rect_float, buffer, ibuf->channels,
234                                 ibuf->x, ibuf->y, ibuf->x, ibuf->x, mask_buffer);
235                 }
236                 else {
237                         IMB_buffer_byte_from_float_mask(
238                                 (unsigned char *) ibuf->rect, buffer, ibuf->channels, ibuf->dither,
239                                 false, ibuf->x, ibuf->y, ibuf->x, ibuf->x, mask_buffer);
240                 }
241         }
242
243         /* margins */
244         if (margin > 0)
245                 RE_bake_margin(ibuf, mask_buffer, margin);
246
247         ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID | IB_BITMAPDIRTY;
248
249         if (ibuf->rect_float)
250                 ibuf->userflags |= IB_RECT_INVALID;
251
252         /* force mipmap recalc */
253         if (ibuf->mipmap[0]) {
254                 ibuf->userflags |= IB_MIPMAP_INVALID;
255                 imb_freemipmapImBuf(ibuf);
256         }
257
258         BKE_image_release_ibuf(image, ibuf, NULL);
259
260         if (mask_buffer)
261                 MEM_freeN(mask_buffer);
262
263         return true;
264 }
265
266 /* force OpenGL reload */
267 static void refresh_images(BakeImages *bake_images)
268 {
269         int i;
270         for (i = 0; i < bake_images->size; i++) {
271                 Image *ima = bake_images->data[i].image;
272                 if (ima->ok == IMA_OK_LOADED) {
273                         GPU_free_image(ima);
274                         DAG_id_tag_update(&ima->id, 0);         
275                 }
276         }
277 }
278
279 static bool write_external_bake_pixels(
280         const char *filepath, BakePixel pixel_array[], float *buffer,
281         const int width, const int height, const int margin,
282         ImageFormatData *im_format, const bool is_noncolor)
283 {
284         ImBuf *ibuf = NULL;
285         bool ok = false;
286         bool is_float;
287
288         is_float = im_format->depth > 8;
289
290         /* create a new ImBuf */
291         ibuf = IMB_allocImBuf(width, height, im_format->planes, (is_float ? IB_rectfloat : IB_rect));
292
293         if (!ibuf)
294                 return false;
295
296         /* populates the ImBuf */
297         if (is_float) {
298                 IMB_buffer_float_from_float(
299                         ibuf->rect_float, buffer, ibuf->channels,
300                         IB_PROFILE_LINEAR_RGB, IB_PROFILE_LINEAR_RGB, false,
301                         ibuf->x, ibuf->y, ibuf->x, ibuf->x);
302         }
303         else {
304                 if (!is_noncolor) {
305                         const char *from_colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_SCENE_LINEAR);
306                         const char *to_colorspace = IMB_colormanagement_get_rect_colorspace(ibuf);
307                         IMB_colormanagement_transform(buffer, ibuf->x, ibuf->y, ibuf->channels, from_colorspace, to_colorspace, false);
308                 }
309
310                 IMB_buffer_byte_from_float(
311                         (unsigned char *) ibuf->rect, buffer, ibuf->channels, ibuf->dither,
312                         IB_PROFILE_SRGB, IB_PROFILE_SRGB,
313                         false, ibuf->x, ibuf->y, ibuf->x, ibuf->x);
314         }
315
316         /* margins */
317         if (margin > 0) {
318                 char *mask_buffer = NULL;
319                 const size_t num_pixels = (size_t)width * (size_t)height;
320
321                 mask_buffer = MEM_callocN(sizeof(char) * num_pixels, "Bake Mask");
322                 RE_bake_mask_fill(pixel_array, num_pixels, mask_buffer);
323                 RE_bake_margin(ibuf, mask_buffer, margin);
324
325                 if (mask_buffer)
326                         MEM_freeN(mask_buffer);
327         }
328
329         if ((ok = BKE_imbuf_write(ibuf, filepath, im_format))) {
330 #ifndef WIN32
331                 chmod(filepath, S_IRUSR | S_IWUSR);
332 #endif
333                 //printf("%s saving bake map: '%s'\n", __func__, filepath);
334         }
335
336         /* garbage collection */
337         IMB_freeImBuf(ibuf);
338
339         return ok;
340 }
341
342 static bool is_noncolor_pass(ScenePassType pass_type)
343 {
344         return ELEM(pass_type,
345                     SCE_PASS_Z,
346                     SCE_PASS_NORMAL,
347                     SCE_PASS_VECTOR,
348                     SCE_PASS_INDEXOB,
349                     SCE_PASS_UV,
350                     SCE_PASS_RAYHITS,
351                     SCE_PASS_INDEXMA);
352 }
353
354 /* if all is good tag image and return true */
355 static bool bake_object_check(Scene *scene, Object *ob, ReportList *reports)
356 {
357         Image *image;
358         void *lock;
359         int i;
360
361         if ((ob->lay & scene->lay) == 0) {
362                 BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is not on a scene layer", ob->id.name + 2);
363                 return false;
364         }
365
366         if (ob->type != OB_MESH) {
367                 BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is not a mesh", ob->id.name + 2);
368                 return false;
369         }
370         else {
371                 Mesh *me = (Mesh *)ob->data;
372
373                 if (CustomData_get_active_layer_index(&me->ldata, CD_MLOOPUV) == -1) {
374                         BKE_reportf(reports, RPT_ERROR,
375                                     "No active UV layer found in the object \"%s\"", ob->id.name + 2);
376                         return false;
377                 }
378         }
379
380         for (i = 0; i < ob->totcol; i++) {
381                 bNodeTree *ntree = NULL;
382                 bNode *node = NULL;
383                 ED_object_get_active_image(ob, i + 1, &image, NULL, &node, &ntree);
384
385                 if (image) {
386                         ImBuf *ibuf;
387
388                         if (node) {
389                                 if (BKE_node_is_connected_to_output(ntree, node)) {
390                                         /* we don't return false since this may be a false positive
391                                          * this can't be RPT_ERROR though, otherwise it prevents
392                                          * multiple highpoly objects to be baked at once */
393                                         BKE_reportf(reports, RPT_INFO,
394                                                     "Circular dependency for image \"%s\" from object \"%s\"",
395                                                     image->id.name + 2, ob->id.name + 2);
396                                 }
397                         }
398
399                         ibuf = BKE_image_acquire_ibuf(image, NULL, &lock);
400
401                         if (ibuf) {
402                                 BKE_image_release_ibuf(image, ibuf, lock);
403                         }
404                         else {
405                                 BKE_reportf(reports, RPT_ERROR,
406                                             "Uninitialized image \"%s\" from object \"%s\"",
407                                             image->id.name + 2, ob->id.name + 2);
408
409                                 BKE_image_release_ibuf(image, ibuf, lock);
410                                 return false;
411                         }
412                 }
413                 else {
414                         if (ob->mat[i]) {
415                                 BKE_reportf(reports, RPT_ERROR,
416                                             "No active image found in material \"%s\" (%d) for object \"%s\"",
417                                             ob->mat[i]->id.name + 2, i, ob->id.name + 2);
418                         }
419                         else if (((Mesh *) ob->data)->mat[i]) {
420                                 BKE_reportf(reports, RPT_ERROR,
421                                             "No active image found in material \"%s\" (%d) for object \"%s\"",
422                                             ((Mesh *) ob->data)->mat[i]->id.name + 2, i, ob->id.name + 2);
423                         }
424                         else {
425                                 BKE_reportf(reports, RPT_ERROR,
426                                             "No active image found in material (%d) for object \"%s\"",
427                                             i, ob->id.name + 2);
428                         }
429                         return false;
430                 }
431
432                 image->id.tag |= LIB_TAG_DOIT;
433         }
434         return true;
435 }
436
437 static bool bake_pass_filter_check(ScenePassType pass_type, const int pass_filter, ReportList *reports)
438 {
439         switch (pass_type) {
440                 case SCE_PASS_COMBINED:
441                         if ((pass_filter & R_BAKE_PASS_FILTER_EMIT) != 0) {
442                                 return true;
443                         }
444
445                         if (((pass_filter & R_BAKE_PASS_FILTER_DIRECT) != 0) ||
446                             ((pass_filter & R_BAKE_PASS_FILTER_INDIRECT) != 0))
447                         {
448                                 if (((pass_filter & R_BAKE_PASS_FILTER_DIFFUSE) != 0) ||
449                                     ((pass_filter & R_BAKE_PASS_FILTER_GLOSSY) != 0) ||
450                                     ((pass_filter & R_BAKE_PASS_FILTER_TRANSM) != 0) ||
451                                     ((pass_filter & R_BAKE_PASS_FILTER_SUBSURFACE) != 0))
452                                 {
453                                         return true;
454                                 }
455
456                                 if ((pass_filter & R_BAKE_PASS_FILTER_AO) != 0) {
457                                         BKE_report(reports, RPT_ERROR,
458                                                    "Combined bake pass Ambient Occlusion contribution requires an enabled light pass "
459                                                    "(bake the Ambient Occlusion pass type instead)");
460                                 }
461                                 else {
462                                         BKE_report(reports, RPT_ERROR,
463                                                    "Combined bake pass requires Emit, or a light pass with "
464                                                    "Direct or Indirect contributions enabled");
465                                 }
466
467                                 return false;
468                         }
469                         else {
470                                 BKE_report(reports, RPT_ERROR,
471                                            "Combined bake pass requires Emit, or a light pass with "
472                                            "Direct or Indirect contributions enabled");
473                                 return false;
474                         }
475                         break;
476                 case SCE_PASS_DIFFUSE_COLOR:
477                 case SCE_PASS_GLOSSY_COLOR:
478                 case SCE_PASS_TRANSM_COLOR:
479                 case SCE_PASS_SUBSURFACE_COLOR:
480                         if (((pass_filter & R_BAKE_PASS_FILTER_COLOR) != 0) ||
481                             ((pass_filter & R_BAKE_PASS_FILTER_DIRECT) != 0) ||
482                             ((pass_filter & R_BAKE_PASS_FILTER_INDIRECT) != 0))
483                         {
484                                 return true;
485                         }
486                         else {
487                                 BKE_report(reports, RPT_ERROR,
488                                            "Bake pass requires Direct, Indirect, or Color contributions to be enabled");
489                                 return false;
490                         }
491                         break;
492                 default:
493                         return true;
494                         break;
495         }
496 }
497
498 /* before even getting in the bake function we check for some basic errors */
499 static bool bake_objects_check(Main *bmain, Scene *scene, Object *ob, ListBase *selected_objects,
500                                ReportList *reports, const bool is_selected_to_active)
501 {
502         CollectionPointerLink *link;
503
504         /* error handling and tag (in case multiple materials share the same image) */
505         BKE_main_id_tag_idcode(bmain, ID_IM, LIB_TAG_DOIT, false);
506
507         if (is_selected_to_active) {
508                 int tot_objects = 0;
509
510                 if (!bake_object_check(scene, ob, reports))
511                         return false;
512
513                 for (link = selected_objects->first; link; link = link->next) {
514                         Object *ob_iter = (Object *)link->ptr.data;
515
516                         if (ob_iter == ob)
517                                 continue;
518
519                         if (ELEM(ob_iter->type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL) == false) {
520                                 BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is not a mesh or can't be converted to a mesh (Curve, Text, Surface or Metaball)", ob_iter->id.name + 2);
521                                 return false;
522                         }
523                         tot_objects += 1;
524                 }
525
526                 if (tot_objects == 0) {
527                         BKE_report(reports, RPT_ERROR, "No valid selected objects");
528                         return false;
529                 }
530         }
531         else {
532                 if (BLI_listbase_is_empty(selected_objects)) {
533                         BKE_report(reports, RPT_ERROR, "No valid selected objects");
534                         return false;
535                 }
536
537                 for (link = selected_objects->first; link; link = link->next) {
538                         if (!bake_object_check(scene, link->ptr.data, reports))
539                                 return false;
540                 }
541         }
542         return true;
543 }
544
545 /* it needs to be called after bake_objects_check since the image tagging happens there */
546 static void bake_images_clear(Main *bmain, const bool is_tangent)
547 {
548         Image *image;
549         for (image = bmain->image.first; image; image = image->id.next) {
550                 if ((image->id.tag & LIB_TAG_DOIT) != 0) {
551                         RE_bake_ibuf_clear(image, is_tangent);
552                 }
553         }
554 }
555
556 static void build_image_lookup(Main *bmain, Object *ob, BakeImages *bake_images)
557 {
558         const int tot_mat = ob->totcol;
559         int i, j;
560         int tot_images = 0;
561
562         /* error handling and tag (in case multiple materials share the same image) */
563         BKE_main_id_tag_idcode(bmain, ID_IM, LIB_TAG_DOIT, false);
564
565         for (i = 0; i < tot_mat; i++) {
566                 Image *image;
567                 ED_object_get_active_image(ob, i + 1, &image, NULL, NULL, NULL);
568
569                 if ((image->id.tag & LIB_TAG_DOIT)) {
570                         for (j = 0; j < i; j++) {
571                                 if (bake_images->data[j].image == image) {
572                                         bake_images->lookup[i] = j;
573                                         break;
574                                 }
575                         }
576                 }
577                 else {
578                         bake_images->lookup[i] = tot_images;
579                         bake_images->data[tot_images].image = image;
580                         image->id.tag |= LIB_TAG_DOIT;
581                         tot_images++;
582                 }
583         }
584
585         bake_images->size = tot_images;
586 }
587
588 /*
589  * returns the total number of pixels
590  */
591 static size_t initialize_internal_images(BakeImages *bake_images, ReportList *reports)
592 {
593         int i;
594         size_t tot_size = 0;
595
596         for (i = 0; i < bake_images->size; i++) {
597                 ImBuf *ibuf;
598                 void *lock;
599
600                 BakeImage *bk_image = &bake_images->data[i];
601                 ibuf = BKE_image_acquire_ibuf(bk_image->image, NULL, &lock);
602
603                 if (ibuf) {
604                         bk_image->width = ibuf->x;
605                         bk_image->height = ibuf->y;
606                         bk_image->offset = tot_size;
607
608                         tot_size += (size_t)ibuf->x * (size_t)ibuf->y;
609                 }
610                 else {
611                         BKE_image_release_ibuf(bk_image->image, ibuf, lock);
612                         BKE_reportf(reports, RPT_ERROR, "Uninitialized image %s", bk_image->image->id.name + 2);
613                         return 0;
614                 }
615                 BKE_image_release_ibuf(bk_image->image, ibuf, lock);
616         }
617         return tot_size;
618 }
619
620 /* create new mesh with edit mode changes and modifiers applied */
621 static Mesh *bake_mesh_new_from_object(Main *bmain, Scene *scene, Object *ob)
622 {
623         if (ob->mode & OB_MODE_EDIT)
624                 ED_object_editmode_load(ob);
625
626         Mesh *me = BKE_mesh_new_from_object(bmain, scene, ob, 1, 2, 0, 0);
627         BKE_mesh_split_faces(me, true);
628
629         return me;
630 }
631
632 static int bake(
633         Render *re, Main *bmain, Scene *scene, Object *ob_low, ListBase *selected_objects, ReportList *reports,
634         const ScenePassType pass_type, const int pass_filter, const int margin,
635         const BakeSaveMode save_mode, const bool is_clear, const bool is_split_materials,
636         const bool is_automatic_name, const bool is_selected_to_active, const bool is_cage,
637         const float cage_extrusion, const int normal_space, const BakeNormalSwizzle normal_swizzle[],
638         const char *custom_cage, const char *filepath, const int width, const int height,
639         const char *identifier, ScrArea *sa, const char *uv_layer)
640 {
641         int op_result = OPERATOR_CANCELLED;
642         bool ok = false;
643
644         Object *ob_cage = NULL;
645
646         BakeHighPolyData *highpoly = NULL;
647         int tot_highpoly = 0;
648
649         char restrict_flag_low = ob_low->restrictflag;
650         char restrict_flag_cage = 0;
651
652         Mesh *me_low = NULL;
653         Mesh *me_cage = NULL;
654
655         MultiresModifierData *mmd_low = NULL;
656         int mmd_flags_low = 0;
657
658         float *result = NULL;
659
660         BakePixel *pixel_array_low = NULL;
661         BakePixel *pixel_array_high = NULL;
662
663         const bool is_save_internal = (save_mode == R_BAKE_SAVE_INTERNAL);
664         const bool is_noncolor = is_noncolor_pass(pass_type);
665         const int depth = RE_pass_depth(pass_type);
666
667         BakeImages bake_images = {NULL};
668
669         size_t num_pixels;
670         int tot_materials;
671
672         RE_bake_engine_set_engine_parameters(re, bmain, scene);
673
674         if (!RE_bake_has_engine(re)) {
675                 BKE_report(reports, RPT_ERROR, "Current render engine does not support baking");
676                 goto cleanup;
677         }
678
679         tot_materials = ob_low->totcol;
680
681         if (uv_layer && uv_layer[0] != '\0') {
682                 Mesh *me = (Mesh *)ob_low->data;
683                 if (CustomData_get_named_layer(&me->ldata, CD_MLOOPUV, uv_layer) == -1) {
684                         BKE_reportf(reports, RPT_ERROR,
685                                     "No UV layer named \"%s\" found in the object \"%s\"", uv_layer, ob_low->id.name + 2);
686                         goto cleanup;
687                 }
688         }
689
690         if (tot_materials == 0) {
691                 if (is_save_internal) {
692                         BKE_report(reports, RPT_ERROR,
693                                    "No active image found, add a material or bake to an external file");
694
695                         goto cleanup;
696                 }
697                 else if (is_split_materials) {
698                         BKE_report(reports, RPT_ERROR,
699                                    "No active image found, add a material or bake without the Split Materials option");
700
701                         goto cleanup;
702                 }
703                 else {
704                         /* baking externally without splitting materials */
705                         tot_materials = 1;
706                 }
707         }
708
709         /* we overallocate in case there is more materials than images */
710         bake_images.data = MEM_mallocN(sizeof(BakeImage) * tot_materials, "bake images dimensions (width, height, offset)");
711         bake_images.lookup = MEM_mallocN(sizeof(int) * tot_materials, "bake images lookup (from material to BakeImage)");
712
713         build_image_lookup(bmain, ob_low, &bake_images);
714
715         if (is_save_internal) {
716                 num_pixels = initialize_internal_images(&bake_images, reports);
717
718                 if (num_pixels == 0) {
719                         goto cleanup;
720                 }
721         }
722         else {
723                 /* when saving extenally always use the size specified in the UI */
724
725                 num_pixels = (size_t)width * (size_t)height * bake_images.size;
726
727                 for (int i = 0; i < bake_images.size; i++) {
728                         bake_images.data[i].width = width;
729                         bake_images.data[i].height = height;
730                         bake_images.data[i].offset = (is_split_materials ? num_pixels : 0);
731                         bake_images.data[i].image = NULL;
732                 }
733
734                 if (!is_split_materials) {
735                         /* saving a single image */
736                         for (int i = 0; i < tot_materials; i++) {
737                                 bake_images.lookup[i] = 0;
738                         }
739                 }
740         }
741
742         if (is_selected_to_active) {
743                 CollectionPointerLink *link;
744                 tot_highpoly = 0;
745
746                 for (link = selected_objects->first; link; link = link->next) {
747                         Object *ob_iter = link->ptr.data;
748
749                         if (ob_iter == ob_low)
750                                 continue;
751
752                         tot_highpoly ++;
753                 }
754
755                 if (is_cage && custom_cage[0] != '\0') {
756                         ob_cage = BLI_findstring(&bmain->object, custom_cage, offsetof(ID, name) + 2);
757
758                         if (ob_cage == NULL || ob_cage->type != OB_MESH) {
759                                 BKE_report(reports, RPT_ERROR, "No valid cage object");
760                                 goto cleanup;
761                         }
762                         else {
763                                 restrict_flag_cage = ob_cage->restrictflag;
764                                 ob_cage->restrictflag |= OB_RESTRICT_RENDER;
765                         }
766                 }
767         }
768
769         pixel_array_low = MEM_mallocN(sizeof(BakePixel) * num_pixels, "bake pixels low poly");
770         pixel_array_high = MEM_mallocN(sizeof(BakePixel) * num_pixels, "bake pixels high poly");
771         result = MEM_callocN(sizeof(float) * depth * num_pixels, "bake return pixels");
772
773         /* for multires bake, use linear UV subdivision to match low res UVs */
774         if (pass_type == SCE_PASS_NORMAL && normal_space == R_BAKE_SPACE_TANGENT && !is_selected_to_active) {
775                 mmd_low = (MultiresModifierData *) modifiers_findByType(ob_low, eModifierType_Multires);
776                 if (mmd_low) {
777                         mmd_flags_low = mmd_low->flags;
778                         mmd_low->flags |= eMultiresModifierFlag_PlainUv;
779                 }
780         }
781
782         /* get the mesh as it arrives in the renderer */
783         me_low = bake_mesh_new_from_object(bmain, scene, ob_low);
784
785         /* populate the pixel array with the face data */
786         if ((is_selected_to_active && (ob_cage == NULL) && is_cage) == false)
787                 RE_bake_pixels_populate(me_low, pixel_array_low, num_pixels, &bake_images, uv_layer);
788         /* else populate the pixel array with the 'cage' mesh (the smooth version of the mesh)  */
789
790         if (is_selected_to_active) {
791                 CollectionPointerLink *link;
792                 ModifierData *md, *nmd;
793                 ListBase modifiers_tmp, modifiers_original;
794                 int i = 0;
795
796                 /* prepare cage mesh */
797                 if (ob_cage) {
798                         me_cage = bake_mesh_new_from_object(bmain, scene, ob_cage);
799                         if ((me_low->totpoly != me_cage->totpoly) || (me_low->totloop != me_cage->totloop)) {
800                                 BKE_report(reports, RPT_ERROR,
801                                            "Invalid cage object, the cage mesh must have the same number "
802                                            "of faces as the active object");
803                                 goto cleanup;
804                         }
805                 }
806                 else if (is_cage) {
807                         modifiers_original = ob_low->modifiers;
808                         BLI_listbase_clear(&modifiers_tmp);
809
810                         for (md = ob_low->modifiers.first; md; md = md->next) {
811                                 /* Edge Split cannot be applied in the cage,
812                                  * the cage is supposed to have interpolated normals
813                                  * between the faces unless the geometry is physically
814                                  * split. So we create a copy of the low poly mesh without
815                                  * the eventual edge split.*/
816
817                                 if (md->type == eModifierType_EdgeSplit)
818                                         continue;
819
820                                 nmd = modifier_new(md->type);
821                                 BLI_strncpy(nmd->name, md->name, sizeof(nmd->name));
822                                 modifier_copyData(md, nmd);
823                                 BLI_addtail(&modifiers_tmp, nmd);
824                         }
825
826                         /* temporarily replace the modifiers */
827                         ob_low->modifiers = modifiers_tmp;
828
829                         /* get the cage mesh as it arrives in the renderer */
830                         me_cage = bake_mesh_new_from_object(bmain, scene, ob_low);
831                         RE_bake_pixels_populate(me_cage, pixel_array_low, num_pixels, &bake_images, uv_layer);
832                 }
833
834                 highpoly = MEM_callocN(sizeof(BakeHighPolyData) * tot_highpoly, "bake high poly objects");
835
836                 /* populate highpoly array */
837                 for (link = selected_objects->first; link; link = link->next) {
838                         TriangulateModifierData *tmd;
839                         Object *ob_iter = link->ptr.data;
840
841                         if (ob_iter == ob_low)
842                                 continue;
843
844                         /* initialize highpoly_data */
845                         highpoly[i].ob = ob_iter;
846                         highpoly[i].restrict_flag = ob_iter->restrictflag;
847
848                         /* triangulating so BVH returns the primitive_id that will be used for rendering */
849                         highpoly[i].tri_mod = ED_object_modifier_add(
850                                 reports, bmain, scene, highpoly[i].ob,
851                                 "TmpTriangulate", eModifierType_Triangulate);
852                         tmd = (TriangulateModifierData *)highpoly[i].tri_mod;
853                         tmd->quad_method = MOD_TRIANGULATE_QUAD_FIXED;
854                         tmd->ngon_method = MOD_TRIANGULATE_NGON_EARCLIP;
855
856                         highpoly[i].me = bake_mesh_new_from_object(bmain, scene, highpoly[i].ob);
857                         highpoly[i].ob->restrictflag &= ~OB_RESTRICT_RENDER;
858
859                         /* lowpoly to highpoly transformation matrix */
860                         copy_m4_m4(highpoly[i].obmat, highpoly[i].ob->obmat);
861                         invert_m4_m4(highpoly[i].imat, highpoly[i].obmat);
862
863                         highpoly[i].is_flip_object = is_negative_m4(highpoly[i].ob->obmat);
864
865                         i++;
866                 }
867
868                 BLI_assert(i == tot_highpoly);
869
870                 ob_low->restrictflag |= OB_RESTRICT_RENDER;
871
872                 /* populate the pixel arrays with the corresponding face data for each high poly object */
873                 if (!RE_bake_pixels_populate_from_objects(
874                             me_low, pixel_array_low, pixel_array_high, highpoly, tot_highpoly, num_pixels, ob_cage != NULL,
875                             cage_extrusion, ob_low->obmat, (ob_cage ? ob_cage->obmat : ob_low->obmat), me_cage))
876                 {
877                         BKE_report(reports, RPT_ERROR, "Error handling selected objects");
878                         goto cage_cleanup;
879                 }
880
881                 /* the baking itself */
882                 for (i = 0; i < tot_highpoly; i++) {
883                         ok = RE_bake_engine(re, highpoly[i].ob, i, pixel_array_high,
884                                             num_pixels, depth, pass_type, pass_filter, result);
885                         if (!ok) {
886                                 BKE_reportf(reports, RPT_ERROR, "Error baking from object \"%s\"", highpoly[i].ob->id.name + 2);
887                                 goto cage_cleanup;
888                         }
889                 }
890
891 cage_cleanup:
892                 /* reverting data back */
893                 if ((ob_cage == NULL) && is_cage) {
894                         ob_low->modifiers = modifiers_original;
895
896                         while ((md = BLI_pophead(&modifiers_tmp))) {
897                                 modifier_free(md);
898                         }
899                 }
900
901                 if (!ok) {
902                         goto cleanup;
903                 }
904         }
905         else {
906                 /* make sure low poly renders */
907                 ob_low->restrictflag &= ~OB_RESTRICT_RENDER;
908
909                 if (RE_bake_has_engine(re)) {
910                         ok = RE_bake_engine(re, ob_low, 0, pixel_array_low, num_pixels, depth, pass_type, pass_filter, result);
911                 }
912                 else {
913                         BKE_report(reports, RPT_ERROR, "Current render engine does not support baking");
914                         goto cleanup;
915                 }
916         }
917
918         /* normal space conversion
919          * the normals are expected to be in world space, +X +Y +Z */
920         if (ok && pass_type == SCE_PASS_NORMAL) {
921                 switch (normal_space) {
922                         case R_BAKE_SPACE_WORLD:
923                         {
924                                 /* Cycles internal format */
925                                 if ((normal_swizzle[0] == R_BAKE_POSX) &&
926                                     (normal_swizzle[1] == R_BAKE_POSY) &&
927                                     (normal_swizzle[2] == R_BAKE_POSZ))
928                                 {
929                                         break;
930                                 }
931                                 else {
932                                         RE_bake_normal_world_to_world(pixel_array_low, num_pixels,  depth, result, normal_swizzle);
933                                 }
934                                 break;
935                         }
936                         case R_BAKE_SPACE_OBJECT:
937                         {
938                                 RE_bake_normal_world_to_object(pixel_array_low, num_pixels, depth, result, ob_low, normal_swizzle);
939                                 break;
940                         }
941                         case R_BAKE_SPACE_TANGENT:
942                         {
943                                 if (is_selected_to_active) {
944                                         RE_bake_normal_world_to_tangent(pixel_array_low, num_pixels, depth, result, me_low, normal_swizzle, ob_low->obmat);
945                                 }
946                                 else {
947                                         /* from multiresolution */
948                                         Mesh *me_nores = NULL;
949                                         ModifierData *md = NULL;
950                                         int mode;
951
952                                         md = modifiers_findByType(ob_low, eModifierType_Multires);
953
954                                         if (md) {
955                                                 mode = md->mode;
956                                                 md->mode &= ~eModifierMode_Render;
957                                         }
958
959                                         me_nores = bake_mesh_new_from_object(bmain, scene, ob_low);
960                                         RE_bake_pixels_populate(me_nores, pixel_array_low, num_pixels, &bake_images, uv_layer);
961
962                                         RE_bake_normal_world_to_tangent(pixel_array_low, num_pixels, depth, result, me_nores, normal_swizzle, ob_low->obmat);
963                                         BKE_libblock_free(bmain, me_nores);
964
965                                         if (md)
966                                                 md->mode = mode;
967                                 }
968                                 break;
969                         }
970                         default:
971                                 break;
972                 }
973         }
974
975         if (!ok) {
976                 BKE_reportf(reports, RPT_ERROR, "Problem baking object \"%s\"", ob_low->id.name + 2);
977                 op_result = OPERATOR_CANCELLED;
978         }
979         else {
980                 /* save the results */
981                 for (int i = 0; i < bake_images.size; i++) {
982                         BakeImage *bk_image = &bake_images.data[i];
983
984                         if (is_save_internal) {
985                                 ok = write_internal_bake_pixels(
986                                          bk_image->image,
987                                          pixel_array_low + bk_image->offset,
988                                          result + bk_image->offset * depth,
989                                          bk_image->width, bk_image->height,
990                                          margin, is_clear, is_noncolor);
991
992                                 /* might be read by UI to set active image for display */
993                                 bake_update_image(sa, bk_image->image);
994
995                                 if (!ok) {
996                                         BKE_reportf(reports, RPT_ERROR,
997                                                    "Problem saving the bake map internally for object \"%s\"", ob_low->id.name + 2);
998                                         op_result = OPERATOR_CANCELLED;
999                                 }
1000                                 else {
1001                                         BKE_report(reports, RPT_INFO,
1002                                                    "Baking map saved to internal image, save it externally or pack it");
1003                                         op_result = OPERATOR_FINISHED;
1004                                 }
1005                         }
1006                         /* save externally */
1007                         else {
1008                                 BakeData *bake = &scene->r.bake;
1009                                 char name[FILE_MAX];
1010
1011                                 BKE_image_path_from_imtype(name, filepath, bmain->name, 0, bake->im_format.imtype, true, false, NULL);
1012
1013                                 if (is_automatic_name) {
1014                                         BLI_path_suffix(name, FILE_MAX, ob_low->id.name + 2, "_");
1015                                         BLI_path_suffix(name, FILE_MAX, identifier, "_");
1016                                 }
1017
1018                                 if (is_split_materials) {
1019                                         if (bk_image->image) {
1020                                                 BLI_path_suffix(name, FILE_MAX, bk_image->image->id.name + 2, "_");
1021                                         }
1022                                         else {
1023                                                 if (ob_low->mat[i]) {
1024                                                         BLI_path_suffix(name, FILE_MAX, ob_low->mat[i]->id.name + 2, "_");
1025                                                 }
1026                                                 else if (me_low->mat[i]) {
1027                                                         BLI_path_suffix(name, FILE_MAX, me_low->mat[i]->id.name + 2, "_");
1028                                                 }
1029                                                 else {
1030                                                         /* if everything else fails, use the material index */
1031                                                         char tmp[4];
1032                                                         sprintf(tmp, "%d", i % 1000);
1033                                                         BLI_path_suffix(name, FILE_MAX, tmp, "_");
1034                                                 }
1035                                         }
1036                                 }
1037
1038                                 /* save it externally */
1039                                 ok = write_external_bake_pixels(
1040                                         name,
1041                                         pixel_array_low + bk_image->offset,
1042                                         result + bk_image->offset * depth,
1043                                         bk_image->width, bk_image->height,
1044                                         margin, &bake->im_format, is_noncolor);
1045
1046                                 if (!ok) {
1047                                         BKE_reportf(reports, RPT_ERROR, "Problem saving baked map in \"%s\"", name);
1048                                         op_result = OPERATOR_CANCELLED;
1049                                 }
1050                                 else {
1051                                         BKE_reportf(reports, RPT_INFO, "Baking map written to \"%s\"", name);
1052                                         op_result = OPERATOR_FINISHED;
1053                                 }
1054
1055                                 if (!is_split_materials) {
1056                                         break;
1057                                 }
1058                         }
1059                 }
1060         }
1061
1062         if (is_save_internal)
1063                 refresh_images(&bake_images);
1064
1065 cleanup:
1066
1067         if (highpoly) {
1068                 int i;
1069                 for (i = 0; i < tot_highpoly; i++) {
1070                         highpoly[i].ob->restrictflag = highpoly[i].restrict_flag;
1071
1072                         if (highpoly[i].tri_mod)
1073                                 ED_object_modifier_remove(reports, bmain, highpoly[i].ob, highpoly[i].tri_mod);
1074
1075                         if (highpoly[i].me)
1076                                 BKE_libblock_free(bmain, highpoly[i].me);
1077                 }
1078                 MEM_freeN(highpoly);
1079         }
1080
1081         ob_low->restrictflag = restrict_flag_low;
1082
1083         if (mmd_low)
1084                 mmd_low->flags = mmd_flags_low;
1085
1086         if (ob_cage)
1087                 ob_cage->restrictflag = restrict_flag_cage;
1088
1089         if (pixel_array_low)
1090                 MEM_freeN(pixel_array_low);
1091
1092         if (pixel_array_high)
1093                 MEM_freeN(pixel_array_high);
1094
1095         if (bake_images.data)
1096                 MEM_freeN(bake_images.data);
1097
1098         if (bake_images.lookup)
1099                 MEM_freeN(bake_images.lookup);
1100
1101         if (result)
1102                 MEM_freeN(result);
1103
1104         if (me_low)
1105                 BKE_libblock_free(bmain, me_low);
1106
1107         if (me_cage)
1108                 BKE_libblock_free(bmain, me_cage);
1109
1110         return op_result;
1111 }
1112
1113 static void bake_init_api_data(wmOperator *op, bContext *C, BakeAPIRender *bkr)
1114 {
1115         bool is_save_internal;
1116         bScreen *sc = CTX_wm_screen(C);
1117
1118         bkr->ob = CTX_data_active_object(C);
1119         bkr->main = CTX_data_main(C);
1120         bkr->scene = CTX_data_scene(C);
1121         bkr->sa = sc ? BKE_screen_find_big_area(sc, SPACE_IMAGE, 10) : NULL;
1122
1123         bkr->pass_type = RNA_enum_get(op->ptr, "type");
1124         bkr->pass_filter = RNA_enum_get(op->ptr, "pass_filter");
1125         bkr->margin = RNA_int_get(op->ptr, "margin");
1126
1127         bkr->save_mode = RNA_enum_get(op->ptr, "save_mode");
1128         is_save_internal = (bkr->save_mode == R_BAKE_SAVE_INTERNAL);
1129
1130         bkr->is_clear = RNA_boolean_get(op->ptr, "use_clear");
1131         bkr->is_split_materials = (!is_save_internal) && RNA_boolean_get(op->ptr, "use_split_materials");
1132         bkr->is_automatic_name = RNA_boolean_get(op->ptr, "use_automatic_name");
1133         bkr->is_selected_to_active = RNA_boolean_get(op->ptr, "use_selected_to_active");
1134         bkr->is_cage = RNA_boolean_get(op->ptr, "use_cage");
1135         bkr->cage_extrusion = RNA_float_get(op->ptr, "cage_extrusion");
1136
1137         bkr->normal_space = RNA_enum_get(op->ptr, "normal_space");
1138         bkr->normal_swizzle[0] = RNA_enum_get(op->ptr, "normal_r");
1139         bkr->normal_swizzle[1] = RNA_enum_get(op->ptr, "normal_g");
1140         bkr->normal_swizzle[2] = RNA_enum_get(op->ptr, "normal_b");
1141
1142         bkr->width = RNA_int_get(op->ptr, "width");
1143         bkr->height = RNA_int_get(op->ptr, "height");
1144         bkr->identifier = "";
1145
1146         RNA_string_get(op->ptr, "uv_layer", bkr->uv_layer);
1147
1148         RNA_string_get(op->ptr, "cage_object", bkr->custom_cage);
1149
1150         if ((!is_save_internal) && bkr->is_automatic_name) {
1151                 PropertyRNA *prop = RNA_struct_find_property(op->ptr, "type");
1152                 RNA_property_enum_identifier(C, op->ptr, prop, bkr->pass_type, &bkr->identifier);
1153         }
1154
1155         CTX_data_selected_objects(C, &bkr->selected_objects);
1156
1157         bkr->reports = op->reports;
1158
1159         bkr->result = OPERATOR_CANCELLED;
1160
1161         bkr->render = RE_NewRender(bkr->scene->id.name);
1162
1163         /* XXX hack to force saving to always be internal. Whether (and how) to support
1164          * external saving will be addressed later */
1165         bkr->save_mode = R_BAKE_SAVE_INTERNAL;
1166 }
1167
1168 static int bake_exec(bContext *C, wmOperator *op)
1169 {
1170         Render *re;
1171         int result = OPERATOR_CANCELLED;
1172         BakeAPIRender bkr = {NULL};
1173         Scene *scene = CTX_data_scene(C);
1174
1175         bake_set_props(op, scene);
1176
1177         bake_init_api_data(op, C, &bkr);
1178         re = bkr.render;
1179
1180         /* setup new render */
1181         RE_test_break_cb(re, NULL, bake_break);
1182
1183         if (!bake_pass_filter_check(bkr.pass_type, bkr.pass_filter, bkr.reports)) {
1184                 goto finally;
1185         }
1186
1187         if (!bake_objects_check(bkr.main, bkr.scene, bkr.ob, &bkr.selected_objects, bkr.reports, bkr.is_selected_to_active)) {
1188                 goto finally;
1189         }
1190
1191         if (bkr.is_clear) {
1192                 const bool is_tangent = ((bkr.pass_type == SCE_PASS_NORMAL) && (bkr.normal_space == R_BAKE_SPACE_TANGENT));
1193                 bake_images_clear(bkr.main, is_tangent);
1194         }
1195
1196         RE_SetReports(re, bkr.reports);
1197
1198         if (bkr.is_selected_to_active) {
1199                 result = bake(
1200                         bkr.render, bkr.main, bkr.scene, bkr.ob, &bkr.selected_objects, bkr.reports,
1201                         bkr.pass_type, bkr.pass_filter, bkr.margin, bkr.save_mode,
1202                         bkr.is_clear, bkr.is_split_materials, bkr.is_automatic_name, true, bkr.is_cage,
1203                         bkr.cage_extrusion, bkr.normal_space, bkr.normal_swizzle,
1204                         bkr.custom_cage, bkr.filepath, bkr.width, bkr.height, bkr.identifier, bkr.sa,
1205                         bkr.uv_layer);
1206         }
1207         else {
1208                 CollectionPointerLink *link;
1209                 const bool is_clear = bkr.is_clear && BLI_listbase_is_single(&bkr.selected_objects);
1210                 for (link = bkr.selected_objects.first; link; link = link->next) {
1211                         Object *ob_iter = link->ptr.data;
1212                         result = bake(
1213                                 bkr.render, bkr.main, bkr.scene, ob_iter, NULL, bkr.reports,
1214                                 bkr.pass_type, bkr.pass_filter, bkr.margin, bkr.save_mode,
1215                                 is_clear, bkr.is_split_materials, bkr.is_automatic_name, false, bkr.is_cage,
1216                                 bkr.cage_extrusion, bkr.normal_space, bkr.normal_swizzle,
1217                                 bkr.custom_cage, bkr.filepath, bkr.width, bkr.height, bkr.identifier, bkr.sa,
1218                                 bkr.uv_layer);
1219                 }
1220         }
1221
1222         RE_SetReports(re, NULL);
1223
1224
1225 finally:
1226         BLI_freelistN(&bkr.selected_objects);
1227         return result;
1228 }
1229
1230 static void bake_startjob(void *bkv, short *UNUSED(stop), short *do_update, float *progress)
1231 {
1232         BakeAPIRender *bkr = (BakeAPIRender *)bkv;
1233
1234         /* setup new render */
1235         bkr->do_update = do_update;
1236         bkr->progress = progress;
1237
1238         RE_SetReports(bkr->render, bkr->reports);
1239
1240         if (!bake_pass_filter_check(bkr->pass_type, bkr->pass_filter, bkr->reports)) {
1241                 bkr->result = OPERATOR_CANCELLED;
1242                 return;
1243         }
1244
1245         if (!bake_objects_check(bkr->main, bkr->scene, bkr->ob, &bkr->selected_objects, bkr->reports, bkr->is_selected_to_active)) {
1246                 bkr->result = OPERATOR_CANCELLED;
1247                 return;
1248         }
1249
1250         if (bkr->is_clear) {
1251                 const bool is_tangent = ((bkr->pass_type == SCE_PASS_NORMAL) && (bkr->normal_space == R_BAKE_SPACE_TANGENT));
1252                 bake_images_clear(bkr->main, is_tangent);
1253         }
1254
1255         if (bkr->is_selected_to_active) {
1256                 bkr->result = bake(
1257                         bkr->render, bkr->main, bkr->scene, bkr->ob, &bkr->selected_objects, bkr->reports,
1258                         bkr->pass_type, bkr->pass_filter, bkr->margin, bkr->save_mode,
1259                         bkr->is_clear, bkr->is_split_materials, bkr->is_automatic_name, true, bkr->is_cage,
1260                         bkr->cage_extrusion, bkr->normal_space, bkr->normal_swizzle,
1261                         bkr->custom_cage, bkr->filepath, bkr->width, bkr->height, bkr->identifier, bkr->sa,
1262                         bkr->uv_layer);
1263         }
1264         else {
1265                 CollectionPointerLink *link;
1266                 const bool is_clear = bkr->is_clear && BLI_listbase_is_single(&bkr->selected_objects);
1267                 for (link = bkr->selected_objects.first; link; link = link->next) {
1268                         Object *ob_iter = link->ptr.data;
1269                         bkr->result = bake(
1270                                 bkr->render, bkr->main, bkr->scene, ob_iter, NULL, bkr->reports,
1271                                 bkr->pass_type, bkr->pass_filter, bkr->margin, bkr->save_mode,
1272                                 is_clear, bkr->is_split_materials, bkr->is_automatic_name, false, bkr->is_cage,
1273                                 bkr->cage_extrusion, bkr->normal_space, bkr->normal_swizzle,
1274                                 bkr->custom_cage, bkr->filepath, bkr->width, bkr->height, bkr->identifier, bkr->sa,
1275                                 bkr->uv_layer);
1276
1277                         if (bkr->result == OPERATOR_CANCELLED)
1278                                 return;
1279                 }
1280         }
1281
1282         RE_SetReports(bkr->render, NULL);
1283 }
1284
1285 static void bake_freejob(void *bkv)
1286 {
1287         BakeAPIRender *bkr = (BakeAPIRender *)bkv;
1288
1289         BLI_freelistN(&bkr->selected_objects);
1290         MEM_freeN(bkr);
1291
1292         G.is_rendering = false;
1293 }
1294
1295 static void bake_set_props(wmOperator *op, Scene *scene)
1296 {
1297         PropertyRNA *prop;
1298         BakeData *bake = &scene->r.bake;
1299
1300         prop = RNA_struct_find_property(op->ptr, "filepath");
1301         if (!RNA_property_is_set(op->ptr, prop)) {
1302                 RNA_property_string_set(op->ptr, prop, bake->filepath);
1303         }
1304
1305         prop =  RNA_struct_find_property(op->ptr, "width");
1306         if (!RNA_property_is_set(op->ptr, prop)) {
1307                 RNA_property_int_set(op->ptr, prop, bake->width);
1308         }
1309
1310         prop =  RNA_struct_find_property(op->ptr, "height");
1311         if (!RNA_property_is_set(op->ptr, prop)) {
1312                 RNA_property_int_set(op->ptr, prop, bake->width);
1313         }
1314
1315         prop = RNA_struct_find_property(op->ptr, "margin");
1316         if (!RNA_property_is_set(op->ptr, prop)) {
1317                 RNA_property_int_set(op->ptr, prop, bake->margin);
1318         }
1319
1320         prop = RNA_struct_find_property(op->ptr, "use_selected_to_active");
1321         if (!RNA_property_is_set(op->ptr, prop)) {
1322                 RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_TO_ACTIVE) != 0);
1323         }
1324
1325         prop = RNA_struct_find_property(op->ptr, "cage_extrusion");
1326         if (!RNA_property_is_set(op->ptr, prop)) {
1327                 RNA_property_float_set(op->ptr, prop, bake->cage_extrusion);
1328         }
1329
1330         prop = RNA_struct_find_property(op->ptr, "cage_object");
1331         if (!RNA_property_is_set(op->ptr, prop)) {
1332                 RNA_property_string_set(op->ptr, prop, bake->cage);
1333         }
1334
1335         prop = RNA_struct_find_property(op->ptr, "normal_space");
1336         if (!RNA_property_is_set(op->ptr, prop)) {
1337                 RNA_property_enum_set(op->ptr, prop, bake->normal_space);
1338         }
1339
1340         prop = RNA_struct_find_property(op->ptr, "normal_r");
1341         if (!RNA_property_is_set(op->ptr, prop)) {
1342                 RNA_property_enum_set(op->ptr, prop, bake->normal_swizzle[0]);
1343         }
1344
1345         prop = RNA_struct_find_property(op->ptr, "normal_g");
1346         if (!RNA_property_is_set(op->ptr, prop)) {
1347                 RNA_property_enum_set(op->ptr, prop, bake->normal_swizzle[1]);
1348         }
1349
1350         prop = RNA_struct_find_property(op->ptr, "normal_b");
1351         if (!RNA_property_is_set(op->ptr, prop)) {
1352                 RNA_property_enum_set(op->ptr, prop, bake->normal_swizzle[2]);
1353         }
1354
1355         prop = RNA_struct_find_property(op->ptr, "save_mode");
1356         if (!RNA_property_is_set(op->ptr, prop)) {
1357                 RNA_property_enum_set(op->ptr, prop, bake->save_mode);
1358         }
1359
1360         prop = RNA_struct_find_property(op->ptr, "use_clear");
1361         if (!RNA_property_is_set(op->ptr, prop)) {
1362                 RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_CLEAR) != 0);
1363         }
1364
1365         prop = RNA_struct_find_property(op->ptr, "use_cage");
1366         if (!RNA_property_is_set(op->ptr, prop)) {
1367                 RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_CAGE) != 0);
1368         }
1369
1370         prop = RNA_struct_find_property(op->ptr, "use_split_materials");
1371         if (!RNA_property_is_set(op->ptr, prop)) {
1372                 RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_SPLIT_MAT) != 0);
1373         }
1374
1375         prop = RNA_struct_find_property(op->ptr, "use_automatic_name");
1376         if (!RNA_property_is_set(op->ptr, prop)) {
1377                 RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_AUTO_NAME) != 0);
1378         }
1379
1380         prop = RNA_struct_find_property(op->ptr, "pass_filter");
1381         if (!RNA_property_is_set(op->ptr, prop)) {
1382                 RNA_property_enum_set(op->ptr, prop, bake->pass_filter);
1383         }
1384 }
1385
1386 static int bake_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
1387 {
1388         wmJob *wm_job;
1389         BakeAPIRender *bkr;
1390         Render *re;
1391         Scene *scene = CTX_data_scene(C);
1392
1393         bake_set_props(op, scene);
1394
1395         /* only one render job at a time */
1396         if (WM_jobs_test(CTX_wm_manager(C), scene, WM_JOB_TYPE_OBJECT_BAKE))
1397                 return OPERATOR_CANCELLED;
1398
1399         bkr = MEM_mallocN(sizeof(BakeAPIRender), "render bake");
1400
1401         /* init bake render */
1402         bake_init_api_data(op, C, bkr);
1403         re = bkr->render;
1404
1405         /* setup new render */
1406         RE_test_break_cb(re, NULL, bake_break);
1407         RE_progress_cb(re, bkr, bake_progress_update);
1408
1409         /* setup job */
1410         wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Texture Bake",
1411                              WM_JOB_EXCL_RENDER | WM_JOB_PRIORITY | WM_JOB_PROGRESS, WM_JOB_TYPE_OBJECT_BAKE);
1412         WM_jobs_customdata_set(wm_job, bkr, bake_freejob);
1413         WM_jobs_timer(wm_job, 0.5, NC_IMAGE, 0); /* TODO - only draw bake image, can we enforce this */
1414         WM_jobs_callbacks(wm_job, bake_startjob, NULL, NULL, NULL);
1415
1416         G.is_break = false;
1417         G.is_rendering = true;
1418
1419         WM_jobs_start(CTX_wm_manager(C), wm_job);
1420
1421         WM_cursor_wait(0);
1422
1423         /* add modal handler for ESC */
1424         WM_event_add_modal_handler(C, op);
1425
1426         WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, scene);
1427         return OPERATOR_RUNNING_MODAL;
1428 }
1429
1430 void OBJECT_OT_bake(wmOperatorType *ot)
1431 {
1432         PropertyRNA *prop;
1433
1434         /* identifiers */
1435         ot->name = "Bake";
1436         ot->description = "Bake image textures of selected objects";
1437         ot->idname = "OBJECT_OT_bake";
1438
1439         /* api callbacks */
1440         ot->exec = bake_exec;
1441         ot->modal = bake_modal;
1442         ot->invoke = bake_invoke;
1443         ot->poll = ED_operator_object_active_editable_mesh;
1444
1445         RNA_def_enum(ot->srna, "type", rna_enum_bake_pass_type_items, SCE_PASS_COMBINED, "Type",
1446                      "Type of pass to bake, some of them may not be supported by the current render engine");
1447         prop = RNA_def_enum(ot->srna, "pass_filter", rna_enum_bake_pass_filter_type_items, R_BAKE_PASS_FILTER_NONE, "Pass Filter",
1448                      "Filter to combined, diffuse, glossy, transmission and subsurface passes");
1449         RNA_def_property_flag(prop, PROP_ENUM_FLAG);
1450         RNA_def_string_file_path(ot->srna, "filepath", NULL, FILE_MAX, "File Path",
1451                                  "Image filepath to use when saving externally");
1452         RNA_def_int(ot->srna, "width", 512, 1, INT_MAX, "Width",
1453                     "Horizontal dimension of the baking map (external only)", 64, 4096);
1454         RNA_def_int(ot->srna, "height", 512, 1, INT_MAX, "Height",
1455                     "Vertical dimension of the baking map (external only)", 64, 4096);
1456         RNA_def_int(ot->srna, "margin", 16, 0, INT_MAX, "Margin",
1457                     "Extends the baked result as a post process filter", 0, 64);
1458         RNA_def_boolean(ot->srna, "use_selected_to_active", false, "Selected to Active",
1459                         "Bake shading on the surface of selected objects to the active object");
1460         RNA_def_float(ot->srna, "cage_extrusion", 0.0f, 0.0f, FLT_MAX, "Cage Extrusion",
1461                       "Distance to use for the inward ray cast when using selected to active", 0.0f, 1.0f);
1462         RNA_def_string(ot->srna, "cage_object", NULL, MAX_NAME, "Cage Object",
1463                        "Object to use as cage, instead of calculating the cage from the active object with cage extrusion");
1464         RNA_def_enum(ot->srna, "normal_space", rna_enum_normal_space_items, R_BAKE_SPACE_TANGENT, "Normal Space",
1465                      "Choose normal space for baking");
1466         RNA_def_enum(ot->srna, "normal_r", rna_enum_normal_swizzle_items, R_BAKE_POSX, "R", "Axis to bake in red channel");
1467         RNA_def_enum(ot->srna, "normal_g", rna_enum_normal_swizzle_items, R_BAKE_POSY, "G", "Axis to bake in green channel");
1468         RNA_def_enum(ot->srna, "normal_b", rna_enum_normal_swizzle_items, R_BAKE_POSZ, "B", "Axis to bake in blue channel");
1469         RNA_def_enum(ot->srna, "save_mode", rna_enum_bake_save_mode_items, R_BAKE_SAVE_INTERNAL, "Save Mode",
1470                      "Choose how to save the baking map");
1471         RNA_def_boolean(ot->srna, "use_clear", false, "Clear",
1472                         "Clear Images before baking (only for internal saving)");
1473         RNA_def_boolean(ot->srna, "use_cage", false, "Cage",
1474                         "Cast rays to active object from a cage");
1475         RNA_def_boolean(ot->srna, "use_split_materials", false, "Split Materials",
1476                         "Split baked maps per material, using material name in output file (external only)");
1477         RNA_def_boolean(ot->srna, "use_automatic_name", false, "Automatic Name",
1478                         "Automatically name the output file with the pass type");
1479         RNA_def_string(ot->srna, "uv_layer", NULL, MAX_CUSTOMDATA_LAYER_NAME, "UV Layer", "UV layer to override active");
1480 }