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