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