Cleanup: Use DNA deprecated guards around old flags
[blender.git] / source / blender / editors / object / object_bake.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2004 by Blender Foundation
17  * All rights reserved.
18  */
19
20 /** \file
21  * \ingroup edobj
22  */
23
24 #include <string.h>
25
26 #include "MEM_guardedalloc.h"
27
28 #include "DNA_mesh_types.h"
29 #include "DNA_meshdata_types.h"
30 #include "DNA_object_types.h"
31 #include "DNA_scene_types.h"
32 #include "DNA_screen_types.h"
33 #include "DNA_space_types.h"
34 #include "DNA_world_types.h"
35
36 #include "BLI_blenlib.h"
37 #include "BLI_utildefines.h"
38
39 #include "BKE_DerivedMesh.h"
40 #include "BKE_blender.h"
41 #include "BKE_cdderivedmesh.h"
42 #include "BKE_context.h"
43 #include "BKE_global.h"
44 #include "BKE_image.h"
45 #include "BKE_material.h"
46 #include "BKE_mesh.h"
47 #include "BKE_modifier.h"
48 #include "BKE_multires.h"
49 #include "BKE_report.h"
50 #include "BKE_scene.h"
51
52 #include "DEG_depsgraph.h"
53
54 #include "RE_multires_bake.h"
55 #include "RE_pipeline.h"
56 #include "RE_shader_ext.h"
57
58 #include "PIL_time.h"
59
60 #include "IMB_imbuf.h"
61 #include "IMB_imbuf_types.h"
62
63 #include "WM_api.h"
64 #include "WM_types.h"
65
66 #include "ED_object.h"
67 #include "ED_screen.h"
68 #include "ED_uvedit.h"
69
70 #include "object_intern.h"
71
72 static Image *bake_object_image_get(Object *ob, int mat_nr)
73 {
74   Image *image = NULL;
75   ED_object_get_active_image(ob, mat_nr + 1, &image, NULL, NULL, NULL);
76   return image;
77 }
78
79 static Image **bake_object_image_get_array(Object *ob)
80 {
81   Image **image_array = MEM_mallocN(sizeof(Material *) * ob->totcol, __func__);
82   for (int i = 0; i < ob->totcol; i++) {
83     image_array[i] = bake_object_image_get(ob, i);
84   }
85   return image_array;
86 }
87
88 /* ****************** multires BAKING ********************** */
89
90 /* holder of per-object data needed for bake job
91  * needed to make job totally thread-safe */
92 typedef struct MultiresBakerJobData {
93   struct MultiresBakerJobData *next, *prev;
94   /* material aligned image array (for per-face bake image) */
95   struct {
96     Image **array;
97     int len;
98   } ob_image;
99   DerivedMesh *lores_dm, *hires_dm;
100   bool simple;
101   int lvl, tot_lvl;
102   ListBase images;
103 } MultiresBakerJobData;
104
105 /* data passing to multires-baker job */
106 typedef struct {
107   Scene *scene;
108   ListBase data;
109   /** Clear the images before baking */
110   bool bake_clear;
111   /** Bake-filter, aka margin */
112   int bake_filter;
113   /** mode of baking (displacement, normals, AO) */
114   short mode;
115   /** Use low-resolution mesh when baking displacement maps */
116   bool use_lores_mesh;
117   /** Number of rays to be cast when doing AO baking */
118   int number_of_rays;
119   /** Bias between object and start ray point when doing AO baking */
120   float bias;
121   /** Number of threads to be used for baking */
122   int threads;
123   /** User scale used to scale displacement when baking derivative map. */
124   float user_scale;
125 } MultiresBakeJob;
126
127 static bool multiresbake_check(bContext *C, wmOperator *op)
128 {
129   Scene *scene = CTX_data_scene(C);
130   Object *ob;
131   Mesh *me;
132   MultiresModifierData *mmd;
133   bool ok = true;
134   int a;
135
136   CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) {
137     ob = base->object;
138
139     if (ob->type != OB_MESH) {
140       BKE_report(
141           op->reports, RPT_ERROR, "Baking of multires data only works with an active mesh object");
142
143       ok = false;
144       break;
145     }
146
147     me = (Mesh *)ob->data;
148     mmd = get_multires_modifier(scene, ob, 0);
149
150     /* Multi-resolution should be and be last in the stack */
151     if (ok && mmd) {
152       ModifierData *md;
153
154       ok = mmd->totlvl > 0;
155
156       for (md = (ModifierData *)mmd->modifier.next; md && ok; md = md->next) {
157         if (BKE_modifier_is_enabled(scene, md, eModifierMode_Realtime)) {
158           ok = false;
159         }
160       }
161     }
162     else {
163       ok = false;
164     }
165
166     if (!ok) {
167       BKE_report(op->reports, RPT_ERROR, "Multires data baking requires multi-resolution object");
168
169       break;
170     }
171
172     if (!me->mloopuv) {
173       BKE_report(op->reports, RPT_ERROR, "Mesh should be unwrapped before multires data baking");
174
175       ok = false;
176     }
177     else {
178       a = me->totpoly;
179       while (ok && a--) {
180         Image *ima = bake_object_image_get(ob, me->mpoly[a].mat_nr);
181
182         if (!ima) {
183           BKE_report(
184               op->reports, RPT_ERROR, "You should have active texture to use multires baker");
185
186           ok = false;
187         }
188         else {
189           ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
190
191           if (!ibuf) {
192             BKE_report(op->reports, RPT_ERROR, "Baking should happen to image with image buffer");
193
194             ok = false;
195           }
196           else {
197             if (ibuf->rect == NULL && ibuf->rect_float == NULL) {
198               ok = false;
199             }
200
201             if (ibuf->rect_float && !(ibuf->channels == 0 || ibuf->channels == 4)) {
202               ok = false;
203             }
204
205             if (!ok) {
206               BKE_report(op->reports, RPT_ERROR, "Baking to unsupported image type");
207             }
208           }
209
210           BKE_image_release_ibuf(ima, ibuf, NULL);
211         }
212       }
213     }
214
215     if (!ok) {
216       break;
217     }
218   }
219   CTX_DATA_END;
220
221   return ok;
222 }
223
224 static DerivedMesh *multiresbake_create_loresdm(Scene *scene, Object *ob, int *lvl)
225 {
226   DerivedMesh *dm;
227   MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0);
228   Mesh *me = (Mesh *)ob->data;
229   MultiresModifierData tmp_mmd = *mmd;
230   DerivedMesh *cddm = CDDM_from_mesh(me);
231
232   DM_set_only_copy(cddm, &CD_MASK_BAREMESH);
233
234   if (mmd->lvl == 0) {
235     dm = CDDM_copy(cddm);
236   }
237   else {
238     tmp_mmd.lvl = mmd->lvl;
239     tmp_mmd.sculptlvl = mmd->lvl;
240     dm = multires_make_derived_from_derived(cddm, &tmp_mmd, scene, ob, 0);
241   }
242
243   cddm->release(cddm);
244
245   *lvl = mmd->lvl;
246
247   return dm;
248 }
249
250 static DerivedMesh *multiresbake_create_hiresdm(Scene *scene, Object *ob, int *lvl, bool *simple)
251 {
252   Mesh *me = (Mesh *)ob->data;
253   MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0);
254   MultiresModifierData tmp_mmd = *mmd;
255   DerivedMesh *cddm = CDDM_from_mesh(me);
256   DerivedMesh *dm;
257
258   DM_set_only_copy(cddm, &CD_MASK_BAREMESH);
259
260   /* TODO: DM_set_only_copy wouldn't set mask for loop and poly data,
261    *       but we really need BAREMESH only to save lots of memory
262    */
263   CustomData_set_only_copy(&cddm->loopData, CD_MASK_BAREMESH.lmask);
264   CustomData_set_only_copy(&cddm->polyData, CD_MASK_BAREMESH.pmask);
265
266   *lvl = mmd->totlvl;
267   *simple = mmd->simple != 0;
268
269   tmp_mmd.lvl = mmd->totlvl;
270   tmp_mmd.sculptlvl = mmd->totlvl;
271   dm = multires_make_derived_from_derived(cddm, &tmp_mmd, scene, ob, 0);
272   cddm->release(cddm);
273
274   return dm;
275 }
276
277 typedef enum ClearFlag {
278   CLEAR_TANGENT_NORMAL = 1,
279   CLEAR_DISPLACEMENT = 2,
280 } ClearFlag;
281
282 static void clear_single_image(Image *image, ClearFlag flag)
283 {
284   const float vec_alpha[4] = {0.0f, 0.0f, 0.0f, 0.0f};
285   const float vec_solid[4] = {0.0f, 0.0f, 0.0f, 1.0f};
286   const float nor_alpha[4] = {0.5f, 0.5f, 1.0f, 0.0f};
287   const float nor_solid[4] = {0.5f, 0.5f, 1.0f, 1.0f};
288   const float disp_alpha[4] = {0.5f, 0.5f, 0.5f, 0.0f};
289   const float disp_solid[4] = {0.5f, 0.5f, 0.5f, 1.0f};
290
291   if ((image->id.tag & LIB_TAG_DOIT) == 0) {
292     ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, NULL);
293
294     if (flag == CLEAR_TANGENT_NORMAL) {
295       IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? nor_alpha : nor_solid);
296     }
297     else if (flag == CLEAR_DISPLACEMENT) {
298       IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? disp_alpha : disp_solid);
299     }
300     else {
301       IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? vec_alpha : vec_solid);
302     }
303
304     image->id.tag |= LIB_TAG_DOIT;
305
306     BKE_image_release_ibuf(image, ibuf, NULL);
307   }
308 }
309
310 static void clear_images_poly(Image **ob_image_array, int ob_image_array_len, ClearFlag flag)
311 {
312   for (int i = 0; i < ob_image_array_len; i++) {
313     Image *image = ob_image_array[i];
314     if (image) {
315       image->id.tag &= ~LIB_TAG_DOIT;
316     }
317   }
318
319   for (int i = 0; i < ob_image_array_len; i++) {
320     Image *image = ob_image_array[i];
321     if (image) {
322       clear_single_image(image, flag);
323     }
324   }
325
326   for (int i = 0; i < ob_image_array_len; i++) {
327     Image *image = ob_image_array[i];
328     if (image) {
329       image->id.tag &= ~LIB_TAG_DOIT;
330     }
331   }
332 }
333
334 static int multiresbake_image_exec_locked(bContext *C, wmOperator *op)
335 {
336   Object *ob;
337   Scene *scene = CTX_data_scene(C);
338   int objects_baked = 0;
339
340   if (!multiresbake_check(C, op)) {
341     return OPERATOR_CANCELLED;
342   }
343
344   if (scene->r.bake_flag & R_BAKE_CLEAR) { /* clear images */
345     CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) {
346       ClearFlag clear_flag = 0;
347
348       ob = base->object;
349       // me = (Mesh *)ob->data;
350
351       if (scene->r.bake_mode == RE_BAKE_NORMALS) {
352         clear_flag = CLEAR_TANGENT_NORMAL;
353       }
354       else if (scene->r.bake_mode == RE_BAKE_DISPLACEMENT) {
355         clear_flag = CLEAR_DISPLACEMENT;
356       }
357
358       {
359         Image **ob_image_array = bake_object_image_get_array(ob);
360         clear_images_poly(ob_image_array, ob->totcol, clear_flag);
361         MEM_freeN(ob_image_array);
362       }
363     }
364     CTX_DATA_END;
365   }
366
367   CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) {
368     MultiresBakeRender bkr = {NULL};
369
370     ob = base->object;
371
372     multires_flush_sculpt_updates(ob);
373
374     /* copy data stored in job descriptor */
375     bkr.scene = scene;
376     bkr.bake_filter = scene->r.bake_filter;
377     bkr.mode = scene->r.bake_mode;
378     bkr.use_lores_mesh = scene->r.bake_flag & R_BAKE_LORES_MESH;
379     bkr.bias = scene->r.bake_biasdist;
380     bkr.number_of_rays = scene->r.bake_samples;
381     bkr.threads = BKE_scene_num_threads(scene);
382     bkr.user_scale = (scene->r.bake_flag & R_BAKE_USERSCALE) ? scene->r.bake_user_scale : -1.0f;
383     // bkr.reports= op->reports;
384
385     /* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */
386     bkr.ob_image.array = bake_object_image_get_array(ob);
387     bkr.ob_image.len = ob->totcol;
388
389     bkr.hires_dm = multiresbake_create_hiresdm(scene, ob, &bkr.tot_lvl, &bkr.simple);
390     bkr.lores_dm = multiresbake_create_loresdm(scene, ob, &bkr.lvl);
391
392     RE_multires_bake_images(&bkr);
393
394     MEM_freeN(bkr.ob_image.array);
395
396     BLI_freelistN(&bkr.image);
397
398     bkr.lores_dm->release(bkr.lores_dm);
399     bkr.hires_dm->release(bkr.hires_dm);
400
401     objects_baked++;
402   }
403   CTX_DATA_END;
404
405   if (!objects_baked) {
406     BKE_report(op->reports, RPT_ERROR, "No objects found to bake from");
407   }
408
409   return OPERATOR_FINISHED;
410 }
411
412 /* Multiresbake adopted for job-system executing */
413 static void init_multiresbake_job(bContext *C, MultiresBakeJob *bkj)
414 {
415   Scene *scene = CTX_data_scene(C);
416   Object *ob;
417
418   /* backup scene settings, so their changing in UI would take no effect on baker */
419   bkj->scene = scene;
420   bkj->bake_filter = scene->r.bake_filter;
421   bkj->mode = scene->r.bake_mode;
422   bkj->use_lores_mesh = scene->r.bake_flag & R_BAKE_LORES_MESH;
423   bkj->bake_clear = scene->r.bake_flag & R_BAKE_CLEAR;
424   bkj->bias = scene->r.bake_biasdist;
425   bkj->number_of_rays = scene->r.bake_samples;
426   bkj->threads = BKE_scene_num_threads(scene);
427   bkj->user_scale = (scene->r.bake_flag & R_BAKE_USERSCALE) ? scene->r.bake_user_scale : -1.0f;
428   // bkj->reports = op->reports;
429
430   CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) {
431     MultiresBakerJobData *data;
432     int lvl;
433
434     ob = base->object;
435
436     multires_flush_sculpt_updates(ob);
437
438     data = MEM_callocN(sizeof(MultiresBakerJobData), "multiresBaker derivedMesh_data");
439
440     data->ob_image.array = bake_object_image_get_array(ob);
441     data->ob_image.len = ob->totcol;
442
443     /* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */
444     data->hires_dm = multiresbake_create_hiresdm(scene, ob, &data->tot_lvl, &data->simple);
445     data->lores_dm = multiresbake_create_loresdm(scene, ob, &lvl);
446     data->lvl = lvl;
447
448     BLI_addtail(&bkj->data, data);
449   }
450   CTX_DATA_END;
451 }
452
453 static void multiresbake_startjob(void *bkv, short *stop, short *do_update, float *progress)
454 {
455   MultiresBakerJobData *data;
456   MultiresBakeJob *bkj = bkv;
457   int baked_objects = 0, tot_obj;
458
459   tot_obj = BLI_listbase_count(&bkj->data);
460
461   if (bkj->bake_clear) { /* clear images */
462     for (data = bkj->data.first; data; data = data->next) {
463       ClearFlag clear_flag = 0;
464
465       if (bkj->mode == RE_BAKE_NORMALS) {
466         clear_flag = CLEAR_TANGENT_NORMAL;
467       }
468       else if (bkj->mode == RE_BAKE_DISPLACEMENT) {
469         clear_flag = CLEAR_DISPLACEMENT;
470       }
471
472       clear_images_poly(data->ob_image.array, data->ob_image.len, clear_flag);
473     }
474   }
475
476   for (data = bkj->data.first; data; data = data->next) {
477     MultiresBakeRender bkr = {NULL};
478
479     /* copy data stored in job descriptor */
480     bkr.scene = bkj->scene;
481     bkr.bake_filter = bkj->bake_filter;
482     bkr.mode = bkj->mode;
483     bkr.use_lores_mesh = bkj->use_lores_mesh;
484     bkr.user_scale = bkj->user_scale;
485     // bkr.reports = bkj->reports;
486     bkr.ob_image.array = data->ob_image.array;
487     bkr.ob_image.len = data->ob_image.len;
488
489     /* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */
490     bkr.lores_dm = data->lores_dm;
491     bkr.hires_dm = data->hires_dm;
492     bkr.tot_lvl = data->tot_lvl;
493     bkr.lvl = data->lvl;
494     bkr.simple = data->simple;
495
496     /* needed for proper progress bar */
497     bkr.tot_obj = tot_obj;
498     bkr.baked_objects = baked_objects;
499
500     bkr.stop = stop;
501     bkr.do_update = do_update;
502     bkr.progress = progress;
503
504     bkr.bias = bkj->bias;
505     bkr.number_of_rays = bkj->number_of_rays;
506     bkr.threads = bkj->threads;
507
508     RE_multires_bake_images(&bkr);
509
510     data->images = bkr.image;
511
512     baked_objects++;
513   }
514 }
515
516 static void multiresbake_freejob(void *bkv)
517 {
518   MultiresBakeJob *bkj = bkv;
519   MultiresBakerJobData *data, *next;
520   LinkData *link;
521
522   data = bkj->data.first;
523   while (data) {
524     next = data->next;
525     data->lores_dm->release(data->lores_dm);
526     data->hires_dm->release(data->hires_dm);
527
528     /* delete here, since this delete will be called from main thread */
529     for (link = data->images.first; link; link = link->next) {
530       Image *ima = (Image *)link->data;
531       BKE_image_free_gputextures(ima);
532     }
533
534     MEM_freeN(data->ob_image.array);
535
536     BLI_freelistN(&data->images);
537
538     MEM_freeN(data);
539     data = next;
540   }
541
542   MEM_freeN(bkj);
543 }
544
545 static int multiresbake_image_exec(bContext *C, wmOperator *op)
546 {
547   Scene *scene = CTX_data_scene(C);
548   MultiresBakeJob *bkr;
549   wmJob *wm_job;
550
551   if (!multiresbake_check(C, op)) {
552     return OPERATOR_CANCELLED;
553   }
554
555   bkr = MEM_callocN(sizeof(MultiresBakeJob), "MultiresBakeJob data");
556   init_multiresbake_job(C, bkr);
557
558   if (!bkr->data.first) {
559     BKE_report(op->reports, RPT_ERROR, "No objects found to bake from");
560     return OPERATOR_CANCELLED;
561   }
562
563   /* setup job */
564   wm_job = WM_jobs_get(CTX_wm_manager(C),
565                        CTX_wm_window(C),
566                        scene,
567                        "Multires Bake",
568                        WM_JOB_EXCL_RENDER | WM_JOB_PRIORITY | WM_JOB_PROGRESS,
569                        WM_JOB_TYPE_OBJECT_BAKE_TEXTURE);
570   WM_jobs_customdata_set(wm_job, bkr, multiresbake_freejob);
571   WM_jobs_timer(wm_job, 0.5, NC_IMAGE, 0); /* TODO - only draw bake image, can we enforce this */
572   WM_jobs_callbacks(wm_job, multiresbake_startjob, NULL, NULL, NULL);
573
574   G.is_break = false;
575
576   WM_jobs_start(CTX_wm_manager(C), wm_job);
577   WM_cursor_wait(0);
578
579   /* add modal handler for ESC */
580   WM_event_add_modal_handler(C, op);
581
582   return OPERATOR_RUNNING_MODAL;
583 }
584
585 /* ****************** render BAKING ********************** */
586
587 /* catch esc */
588 static int objects_bake_render_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
589 {
590   /* no running blender, remove handler and pass through */
591   if (0 == WM_jobs_test(CTX_wm_manager(C), CTX_data_scene(C), WM_JOB_TYPE_OBJECT_BAKE_TEXTURE)) {
592     return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
593   }
594
595   /* running render */
596   switch (event->type) {
597     case EVT_ESCKEY:
598       return OPERATOR_RUNNING_MODAL;
599   }
600   return OPERATOR_PASS_THROUGH;
601 }
602
603 static bool is_multires_bake(Scene *scene)
604 {
605   if (ELEM(scene->r.bake_mode, RE_BAKE_NORMALS, RE_BAKE_DISPLACEMENT, RE_BAKE_AO)) {
606     return scene->r.bake_flag & R_BAKE_MULTIRES;
607   }
608
609   return 0;
610 }
611
612 static int objects_bake_render_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(_event))
613 {
614   Scene *scene = CTX_data_scene(C);
615   int result = OPERATOR_CANCELLED;
616
617   result = multiresbake_image_exec(C, op);
618
619   WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, scene);
620
621   return result;
622 }
623
624 static int bake_image_exec(bContext *C, wmOperator *op)
625 {
626   Scene *scene = CTX_data_scene(C);
627   int result = OPERATOR_CANCELLED;
628
629   if (!is_multires_bake(scene)) {
630     BLI_assert(0);
631     return result;
632   }
633
634   result = multiresbake_image_exec_locked(C, op);
635
636   WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, scene);
637
638   return result;
639 }
640
641 void OBJECT_OT_bake_image(wmOperatorType *ot)
642 {
643   /* identifiers */
644   ot->name = "Bake";
645   ot->description = "Bake image textures of selected objects";
646   ot->idname = "OBJECT_OT_bake_image";
647
648   /* api callbacks */
649   ot->exec = bake_image_exec;
650   ot->invoke = objects_bake_render_invoke;
651   ot->modal = objects_bake_render_modal;
652   ot->poll = ED_operator_object_active;
653 }