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