Blender  V3.3
object_bake_api.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2004 Blender Foundation. All rights reserved. */
3 
8 #include "MEM_guardedalloc.h"
9 
10 #include "DNA_material_types.h"
11 #include "DNA_mesh_types.h"
12 #include "DNA_meshdata_types.h"
13 #include "DNA_object_types.h"
14 
15 #include "RNA_access.h"
16 #include "RNA_define.h"
17 #include "RNA_enum_types.h"
18 
19 #include "BLI_fileops.h"
20 #include "BLI_listbase.h"
21 #include "BLI_path_util.h"
22 #include "BLI_string.h"
23 
24 #include "BKE_attribute.h"
25 #include "BKE_callbacks.h"
26 #include "BKE_context.h"
27 #include "BKE_editmesh.h"
28 #include "BKE_global.h"
29 #include "BKE_image.h"
30 #include "BKE_image_format.h"
31 #include "BKE_layer.h"
32 #include "BKE_lib_id.h"
33 #include "BKE_main.h"
34 #include "BKE_material.h"
35 #include "BKE_mesh.h"
36 #include "BKE_mesh_mapping.h"
37 #include "BKE_modifier.h"
38 #include "BKE_node.h"
39 #include "BKE_object.h"
40 #include "BKE_report.h"
41 #include "BKE_scene.h"
42 #include "BKE_screen.h"
43 
44 #include "DEG_depsgraph.h"
45 #include "DEG_depsgraph_build.h"
46 #include "DEG_depsgraph_query.h"
47 
48 #include "RE_engine.h"
49 #include "RE_pipeline.h"
50 
51 #include "IMB_colormanagement.h"
52 #include "IMB_imbuf.h"
53 #include "IMB_imbuf_types.h"
54 
55 #include "WM_api.h"
56 #include "WM_types.h"
57 
58 #include "ED_object.h"
59 #include "ED_screen.h"
60 #include "ED_uvedit.h"
61 
62 #include "object_intern.h"
63 
64 /* prototypes */
65 static void bake_set_props(wmOperator *op, Scene *scene);
66 
67 typedef struct BakeAPIRender {
68  /* Data to work on. */
74 
75  /* Baking settings. */
77 
80  int margin;
82 
83  bool is_clear;
85  bool is_cage;
86 
91 
94 
95  /* Settings for external image saving. */
100  int width;
101  int height;
102  const char *identifier;
103 
104  /* Baking render session. */
106 
107  /* Progress Callbacks. */
108  float *progress;
109  short *do_update;
110 
111  /* Operator state. */
113  int result;
116 
117 /* callbacks */
118 
119 static void bake_progress_update(void *bjv, float progress)
120 {
121  BakeAPIRender *bj = bjv;
122 
123  if (bj->progress && *bj->progress != progress) {
124  *bj->progress = progress;
125 
126  /* make jobs timer to send notifier */
127  *(bj->do_update) = true;
128  }
129 }
130 
132 static int bake_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
133 {
134  /* no running blender, remove handler and pass through */
137  }
138 
139  /* running render */
140  switch (event->type) {
141  case EVT_ESCKEY: {
142  G.is_break = true;
143  return OPERATOR_RUNNING_MODAL;
144  }
145  }
146  return OPERATOR_PASS_THROUGH;
147 }
148 
153 static int bake_break(void *UNUSED(rjv))
154 {
155  if (G.is_break) {
156  return 1;
157  }
158  return 0;
159 }
160 
162 {
163  if (area && area->spacetype == SPACE_IMAGE) { /* in case the user changed while baking */
164  SpaceImage *sima = area->spacedata.first;
165  if (sima) {
166  sima->image = image;
167  }
168  }
169 }
170 
172  const int image_tile_number,
173  BakePixel pixel_array[],
174  float *buffer,
175  const int width,
176  const int height,
177  const int margin,
178  const char margin_type,
179  const bool is_clear,
180  const bool is_noncolor,
181  Mesh const *mesh_eval,
182  char const *uv_layer,
183  const float uv_offset[2])
184 {
185  ImBuf *ibuf;
186  void *lock;
187  bool is_float;
188  char *mask_buffer = NULL;
189  const size_t pixels_num = (size_t)width * (size_t)height;
190 
191  ImageUser iuser;
192  BKE_imageuser_default(&iuser);
193  iuser.tile = image_tile_number;
194  ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock);
195 
196  if (!ibuf) {
197  return false;
198  }
199 
200  if (margin > 0 || !is_clear) {
201  mask_buffer = MEM_callocN(sizeof(char) * pixels_num, "Bake Mask");
202  RE_bake_mask_fill(pixel_array, pixels_num, mask_buffer);
203  }
204 
205  is_float = (ibuf->rect_float != NULL);
206 
207  /* colormanagement conversions */
208  if (!is_noncolor) {
209  const char *from_colorspace;
210  const char *to_colorspace;
211 
213 
214  if (is_float) {
215  to_colorspace = IMB_colormanagement_get_float_colorspace(ibuf);
216  }
217  else {
218  to_colorspace = IMB_colormanagement_get_rect_colorspace(ibuf);
219  }
220 
221  if (from_colorspace != to_colorspace) {
223  buffer, ibuf->x, ibuf->y, ibuf->channels, from_colorspace, to_colorspace, false);
224  }
225  }
226 
227  /* populates the ImBuf */
228  if (is_clear) {
229  if (is_float) {
231  buffer,
232  ibuf->channels,
235  false,
236  ibuf->x,
237  ibuf->y,
238  ibuf->x,
239  ibuf->x);
240  }
241  else {
243  buffer,
244  ibuf->channels,
245  ibuf->dither,
248  false,
249  ibuf->x,
250  ibuf->y,
251  ibuf->x,
252  ibuf->x);
253  }
254  }
255  else {
256  if (is_float) {
258  buffer,
259  ibuf->channels,
260  ibuf->x,
261  ibuf->y,
262  ibuf->x,
263  ibuf->x,
264  mask_buffer);
265  }
266  else {
268  buffer,
269  ibuf->channels,
270  ibuf->dither,
271  false,
272  ibuf->x,
273  ibuf->y,
274  ibuf->x,
275  ibuf->x,
276  mask_buffer);
277  }
278  }
279 
280  /* margins */
281  if (margin > 0) {
282  RE_bake_margin(ibuf, mask_buffer, margin, margin_type, mesh_eval, uv_layer, uv_offset);
283  }
284 
287 
288  if (ibuf->rect_float) {
289  ibuf->userflags |= IB_RECT_INVALID;
290  }
291 
292  /* force mipmap recalc */
293  if (ibuf->mipmap[0]) {
294  ibuf->userflags |= IB_MIPMAP_INVALID;
295  imb_freemipmapImBuf(ibuf);
296  }
297 
299 
300  if (mask_buffer) {
301  MEM_freeN(mask_buffer);
302  }
303 
304  return true;
305 }
306 
307 /* force OpenGL reload */
308 static void bake_targets_refresh(BakeTargets *targets)
309 {
310  for (int i = 0; i < targets->images_num; i++) {
311  Image *ima = targets->images[i].image;
312 
313  if (ima) {
316  DEG_id_tag_update(&ima->id, 0);
317  }
318  }
319 }
320 
321 static bool write_external_bake_pixels(const char *filepath,
322  BakePixel pixel_array[],
323  float *buffer,
324  const int width,
325  const int height,
326  const int margin,
327  const int margin_type,
328  ImageFormatData const *im_format,
329  const bool is_noncolor,
330  Mesh const *mesh_eval,
331  char const *uv_layer,
332  const float uv_offset[2])
333 {
334  ImBuf *ibuf = NULL;
335  bool ok = false;
336  bool is_float;
337 
338  is_float = im_format->depth > 8;
339 
340  /* create a new ImBuf */
341  ibuf = IMB_allocImBuf(width, height, im_format->planes, (is_float ? IB_rectfloat : IB_rect));
342 
343  if (!ibuf) {
344  return false;
345  }
346 
347  /* populates the ImBuf */
348  if (is_float) {
350  buffer,
351  ibuf->channels,
354  false,
355  ibuf->x,
356  ibuf->y,
357  ibuf->x,
358  ibuf->x);
359  }
360  else {
361  if (!is_noncolor) {
362  const char *from_colorspace = IMB_colormanagement_role_colorspace_name_get(
364  const char *to_colorspace = IMB_colormanagement_get_rect_colorspace(ibuf);
366  buffer, ibuf->x, ibuf->y, ibuf->channels, from_colorspace, to_colorspace, false);
367  }
368 
370  buffer,
371  ibuf->channels,
372  ibuf->dither,
375  false,
376  ibuf->x,
377  ibuf->y,
378  ibuf->x,
379  ibuf->x);
380  }
381 
382  /* margins */
383  if (margin > 0) {
384  char *mask_buffer = NULL;
385  const size_t pixels_num = (size_t)width * (size_t)height;
386 
387  mask_buffer = MEM_callocN(sizeof(char) * pixels_num, "Bake Mask");
388  RE_bake_mask_fill(pixel_array, pixels_num, mask_buffer);
389  RE_bake_margin(ibuf, mask_buffer, margin, margin_type, mesh_eval, uv_layer, uv_offset);
390 
391  if (mask_buffer) {
392  MEM_freeN(mask_buffer);
393  }
394  }
395 
396  if ((ok = BKE_imbuf_write(ibuf, filepath, im_format))) {
397 #ifndef WIN32
398  chmod(filepath, S_IRUSR | S_IWUSR);
399 #endif
400  // printf("%s saving bake map: '%s'\n", __func__, filepath);
401  }
402 
403  /* garbage collection */
404  IMB_freeImBuf(ibuf);
405 
406  return ok;
407 }
408 
409 static bool is_noncolor_pass(eScenePassType pass_type)
410 {
411  return ELEM(pass_type,
412  SCE_PASS_Z,
417  SCE_PASS_UV,
419 }
420 
421 /* if all is good tag image and return true */
422 static bool bake_object_check(ViewLayer *view_layer,
423  Object *ob,
424  const eBakeTarget target,
425  ReportList *reports)
426 {
427  Base *base = BKE_view_layer_base_find(view_layer, ob);
428 
429  if (base == NULL) {
430  BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is not in view layer", ob->id.name + 2);
431  return false;
432  }
433 
434  if (!(base->flag & BASE_ENABLED_RENDER)) {
435  BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is not enabled for rendering", ob->id.name + 2);
436  return false;
437  }
438 
439  if (ob->type != OB_MESH) {
440  BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is not a mesh", ob->id.name + 2);
441  return false;
442  }
443 
444  Mesh *me = (Mesh *)ob->data;
445 
446  if (me->totpoly == 0) {
447  BKE_reportf(reports, RPT_ERROR, "No faces found in the object \"%s\"", ob->id.name + 2);
448  return false;
449  }
450 
451  if (target == R_BAKE_TARGET_VERTEX_COLORS) {
453  BKE_reportf(reports,
454  RPT_ERROR,
455  "Mesh does not have an active color attribute \"%s\"",
456  me->id.name + 2);
457  return false;
458  }
459  }
460  else if (target == R_BAKE_TARGET_IMAGE_TEXTURES) {
462  BKE_reportf(
463  reports, RPT_ERROR, "No active UV layer found in the object \"%s\"", ob->id.name + 2);
464  return false;
465  }
466 
467  for (int i = 0; i < ob->totcol; i++) {
468  bNodeTree *ntree = NULL;
469  bNode *node = NULL;
470  const int mat_nr = i + 1;
471  Image *image;
472  ED_object_get_active_image(ob, mat_nr, &image, NULL, &node, &ntree);
473 
474  if (image) {
475 
476  if (node) {
478  /* we don't return false since this may be a false positive
479  * this can't be RPT_ERROR though, otherwise it prevents
480  * multiple highpoly objects to be baked at once */
481  BKE_reportf(reports,
482  RPT_INFO,
483  "Circular dependency for image \"%s\" from object \"%s\"",
484  image->id.name + 2,
485  ob->id.name + 2);
486  }
487  }
488 
489  LISTBASE_FOREACH (ImageTile *, tile, &image->tiles) {
490  ImageUser iuser;
491  BKE_imageuser_default(&iuser);
492  iuser.tile = tile->tile_number;
493 
494  void *lock;
495  ImBuf *ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock);
496 
497  if (ibuf) {
499  }
500  else {
501  BKE_reportf(reports,
502  RPT_ERROR,
503  "Uninitialized image \"%s\" from object \"%s\"",
504  image->id.name + 2,
505  ob->id.name + 2);
506 
508  return false;
509  }
510  }
511  }
512  else {
513  Material *mat = BKE_object_material_get(ob, mat_nr);
514  if (mat != NULL) {
515  BKE_reportf(reports,
516  RPT_INFO,
517  "No active image found in material \"%s\" (%d) for object \"%s\"",
518  mat->id.name + 2,
519  i,
520  ob->id.name + 2);
521  }
522  else {
523  BKE_reportf(reports,
524  RPT_INFO,
525  "No active image found in material slot (%d) for object \"%s\"",
526  i,
527  ob->id.name + 2);
528  }
529  continue;
530  }
531 
532  image->id.tag |= LIB_TAG_DOIT;
533  }
534  }
535 
536  return true;
537 }
538 
540  const int pass_filter,
541  ReportList *reports)
542 {
543  switch (pass_type) {
544  case SCE_PASS_COMBINED:
545  if ((pass_filter & R_BAKE_PASS_FILTER_EMIT) != 0) {
546  return true;
547  }
548 
549  if (((pass_filter & R_BAKE_PASS_FILTER_DIRECT) != 0) ||
550  ((pass_filter & R_BAKE_PASS_FILTER_INDIRECT) != 0)) {
551  if (((pass_filter & R_BAKE_PASS_FILTER_DIFFUSE) != 0) ||
552  ((pass_filter & R_BAKE_PASS_FILTER_GLOSSY) != 0) ||
553  ((pass_filter & R_BAKE_PASS_FILTER_TRANSM) != 0) ||
554  ((pass_filter & R_BAKE_PASS_FILTER_SUBSURFACE) != 0)) {
555  return true;
556  }
557 
558  BKE_report(reports,
559  RPT_ERROR,
560  "Combined bake pass requires Emit, or a light pass with "
561  "Direct or Indirect contributions enabled");
562 
563  return false;
564  }
565  BKE_report(reports,
566  RPT_ERROR,
567  "Combined bake pass requires Emit, or a light pass with "
568  "Direct or Indirect contributions enabled");
569  return false;
574  if (((pass_filter & R_BAKE_PASS_FILTER_COLOR) != 0) ||
575  ((pass_filter & R_BAKE_PASS_FILTER_DIRECT) != 0) ||
576  ((pass_filter & R_BAKE_PASS_FILTER_INDIRECT) != 0)) {
577  return true;
578  }
579  else {
580  BKE_report(reports,
581  RPT_ERROR,
582  "Bake pass requires Direct, Indirect, or Color contributions to be enabled");
583  return false;
584  }
585  break;
586  default:
587  return true;
588  break;
589  }
590 }
591 
592 /* before even getting in the bake function we check for some basic errors */
593 static bool bake_objects_check(Main *bmain,
594  ViewLayer *view_layer,
595  Object *ob,
596  ListBase *selected_objects,
597  ReportList *reports,
598  const bool is_selected_to_active,
599  const eBakeTarget target)
600 {
601  CollectionPointerLink *link;
602 
603  /* error handling and tag (in case multiple materials share the same image) */
604  BKE_main_id_tag_idcode(bmain, ID_IM, LIB_TAG_DOIT, false);
605 
606  if (is_selected_to_active) {
607  int tot_objects = 0;
608 
609  if (!bake_object_check(view_layer, ob, target, reports)) {
610  return false;
611  }
612 
613  for (link = selected_objects->first; link; link = link->next) {
614  Object *ob_iter = (Object *)link->ptr.data;
615 
616  if (ob_iter == ob) {
617  continue;
618  }
619 
620  if (ELEM(ob_iter->type, OB_MESH, OB_FONT, OB_CURVES_LEGACY, OB_SURF, OB_MBALL) == false) {
621  BKE_reportf(reports,
622  RPT_ERROR,
623  "Object \"%s\" is not a mesh or can't be converted to a mesh (Curve, Text, "
624  "Surface or Metaball)",
625  ob_iter->id.name + 2);
626  return false;
627  }
628  tot_objects += 1;
629  }
630 
631  if (tot_objects == 0) {
632  BKE_report(reports, RPT_ERROR, "No valid selected objects");
633  return false;
634  }
635  }
636  else {
637  if (BLI_listbase_is_empty(selected_objects)) {
638  BKE_report(reports, RPT_ERROR, "No valid selected objects");
639  return false;
640  }
641 
642  for (link = selected_objects->first; link; link = link->next) {
643  if (!bake_object_check(view_layer, link->ptr.data, target, reports)) {
644  return false;
645  }
646  }
647  }
648  return true;
649 }
650 
651 /* it needs to be called after bake_objects_check since the image tagging happens there */
652 static void bake_targets_clear(Main *bmain, const bool is_tangent)
653 {
654  Image *image;
655  for (image = bmain->images.first; image; image = image->id.next) {
656  if ((image->id.tag & LIB_TAG_DOIT) != 0) {
657  RE_bake_ibuf_clear(image, is_tangent);
658  }
659  }
660 }
661 
662 /* create new mesh with edit mode changes and modifiers applied */
664  Object *object,
665  const bool preserve_origindex)
666 {
667  Mesh *me = BKE_mesh_new_from_object(depsgraph, object, false, preserve_origindex);
668 
669  if (me->flag & ME_AUTOSMOOTH) {
670  BKE_mesh_split_faces(me, true);
671  }
672 
673  return me;
674 }
675 
676 /* Image Bake Targets */
677 
679  BakeTargets *targets,
680  Object *ob,
681  ReportList *reports)
682 {
683  int materials_num = ob->totcol;
684 
685  if (materials_num == 0) {
686  if (bkr->save_mode == R_BAKE_SAVE_INTERNAL) {
687  BKE_report(
688  reports, RPT_ERROR, "No active image found, add a material or bake to an external file");
689  return false;
690  }
691  if (bkr->is_split_materials) {
692  BKE_report(
693  reports,
694  RPT_ERROR,
695  "No active image found, add a material or bake without the Split Materials option");
696  return false;
697  }
698  }
699 
700  /* Allocate material mapping. */
701  targets->materials_num = materials_num;
702  targets->material_to_image = MEM_callocN(sizeof(Image *) * targets->materials_num,
703  "BakeTargets.material_to_image");
704 
705  /* Error handling and tag (in case multiple materials share the same image). */
707 
708  targets->images = NULL;
709 
710  for (int i = 0; i < materials_num; i++) {
711  Image *image;
713 
714  targets->material_to_image[i] = image;
715 
716  /* Some materials have no image, we just ignore those cases.
717  * Also setup each image only once. */
718  if (image && !(image->id.tag & LIB_TAG_DOIT)) {
719  LISTBASE_FOREACH (ImageTile *, tile, &image->tiles) {
720  /* Add bake image. */
721  targets->images = MEM_recallocN(targets->images,
722  sizeof(BakeImage) * (targets->images_num + 1));
723  targets->images[targets->images_num].image = image;
724  targets->images[targets->images_num].tile_number = tile->tile_number;
725  targets->images_num++;
726  }
727 
728  image->id.tag |= LIB_TAG_DOIT;
729  }
730  }
731 
732  return true;
733 }
734 
736  BakeTargets *targets,
737  Object *ob,
738  ReportList *reports)
739 {
740  if (!bake_targets_init_image_textures(bkr, targets, ob, reports)) {
741  return false;
742  }
743 
744  /* Saving to image datablocks. */
745  for (int i = 0; i < targets->images_num; i++) {
746  BakeImage *bk_image = &targets->images[i];
747 
748  ImageUser iuser;
749  BKE_imageuser_default(&iuser);
750  iuser.tile = bk_image->tile_number;
751 
752  void *lock;
753  ImBuf *ibuf = BKE_image_acquire_ibuf(bk_image->image, &iuser, &lock);
754 
755  if (ibuf) {
756  bk_image->width = ibuf->x;
757  bk_image->height = ibuf->y;
758  bk_image->offset = targets->pixels_num;
759  BKE_image_get_tile_uv(bk_image->image, bk_image->tile_number, bk_image->uv_offset);
760 
761  targets->pixels_num += (size_t)ibuf->x * (size_t)ibuf->y;
762  }
763  else {
764  BKE_image_release_ibuf(bk_image->image, ibuf, lock);
765  BKE_reportf(reports, RPT_ERROR, "Uninitialized image %s", bk_image->image->id.name + 2);
766  return false;
767  }
768  BKE_image_release_ibuf(bk_image->image, ibuf, lock);
769  }
770 
771  return true;
772 }
773 
775  BakeTargets *targets,
776  Object *ob,
777  BakePixel *pixel_array,
778  ReportList *reports,
779  Mesh *mesh_eval)
780 {
781  bool all_ok = true;
782 
783  for (int i = 0; i < targets->images_num; i++) {
784  BakeImage *bk_image = &targets->images[i];
785  const bool ok = write_internal_bake_pixels(bk_image->image,
786  bk_image->tile_number,
787  pixel_array + bk_image->offset,
788  targets->result +
789  bk_image->offset * targets->channels_num,
790  bk_image->width,
791  bk_image->height,
792  bkr->margin,
793  bkr->margin_type,
794  bkr->is_clear,
795  targets->is_noncolor,
796  mesh_eval,
797  bkr->uv_layer,
798  bk_image->uv_offset);
799 
800  /* might be read by UI to set active image for display */
801  bake_update_image(bkr->area, bk_image->image);
802 
803  if (!ok) {
804  BKE_reportf(reports,
805  RPT_ERROR,
806  "Problem saving the bake map internally for object \"%s\"",
807  ob->id.name + 2);
808  all_ok = false;
809  }
810  else {
811  BKE_report(
812  reports, RPT_INFO, "Baking map saved to internal image, save it externally or pack it");
813  }
814  }
815 
816  return all_ok;
817 }
818 
820  BakeTargets *targets,
821  Object *ob,
822  ReportList *reports)
823 {
824  if (!bake_targets_init_image_textures(bkr, targets, ob, reports)) {
825  return false;
826  }
827 
828  /* Saving to disk. */
829  for (int i = 0; i < targets->images_num; i++) {
830  BakeImage *bk_image = &targets->images[i];
831 
832  bk_image->width = bkr->width;
833  bk_image->height = bkr->height;
834  bk_image->offset = targets->pixels_num;
835 
836  targets->pixels_num += (size_t)bkr->width * (size_t)bkr->height;
837 
838  if (!bkr->is_split_materials) {
839  break;
840  }
841  }
842 
843  if (!bkr->is_split_materials) {
844  /* saving a single image */
845  for (int i = 0; i < targets->materials_num; i++) {
846  targets->material_to_image[i] = targets->images[0].image;
847  }
848  }
849 
850  return true;
851 }
852 
854  BakeTargets *targets,
855  Object *ob,
856  Object *ob_eval,
857  Mesh *mesh_eval,
858  BakePixel *pixel_array,
859  ReportList *reports)
860 {
861  bool all_ok = true;
862 
863  for (int i = 0; i < targets->images_num; i++) {
864  BakeImage *bk_image = &targets->images[i];
865 
866  BakeData *bake = &bkr->scene->r.bake;
867  char name[FILE_MAX];
868 
870  bkr->filepath,
872  0,
873  bake->im_format.imtype,
874  true,
875  false,
876  NULL);
877 
878  if (bkr->is_automatic_name) {
879  BLI_path_suffix(name, FILE_MAX, ob->id.name + 2, "_");
880  BLI_path_suffix(name, FILE_MAX, bkr->identifier, "_");
881  }
882 
883  if (bkr->is_split_materials) {
884  if (ob_eval->mat[i]) {
885  BLI_path_suffix(name, FILE_MAX, ob_eval->mat[i]->id.name + 2, "_");
886  }
887  else if (mesh_eval->mat[i]) {
888  BLI_path_suffix(name, FILE_MAX, mesh_eval->mat[i]->id.name + 2, "_");
889  }
890  else {
891  /* if everything else fails, use the material index */
892  char tmp[5];
893  sprintf(tmp, "%d", i % 1000);
894  BLI_path_suffix(name, FILE_MAX, tmp, "_");
895  }
896  }
897 
898  if (bk_image->tile_number) {
899  char tmp[FILE_MAX];
900  SNPRINTF(tmp, "%d", bk_image->tile_number);
901  BLI_path_suffix(name, FILE_MAX, tmp, "_");
902  }
903 
904  /* save it externally */
905  const bool ok = write_external_bake_pixels(name,
906  pixel_array + bk_image->offset,
907  targets->result +
908  bk_image->offset * targets->channels_num,
909  bk_image->width,
910  bk_image->height,
911  bkr->margin,
912  bkr->margin_type,
913  &bake->im_format,
914  targets->is_noncolor,
915  mesh_eval,
916  bkr->uv_layer,
917  bk_image->uv_offset);
918 
919  if (!ok) {
920  BKE_reportf(reports, RPT_ERROR, "Problem saving baked map in \"%s\"", name);
921  all_ok = false;
922  }
923  else {
924  BKE_reportf(reports, RPT_INFO, "Baking map written to \"%s\"", name);
925  }
926 
927  if (!bkr->is_split_materials) {
928  break;
929  }
930  }
931 
932  return all_ok;
933 }
934 
935 /* Vertex Color Bake Targets */
936 
938  BakeTargets *targets,
939  Object *ob,
940  ReportList *reports)
941 {
942  if (ob->type != OB_MESH) {
943  BKE_report(reports, RPT_ERROR, "Color attribute baking is only supported for mesh objects");
944  return false;
945  }
946 
947  Mesh *me = ob->data;
949  BKE_report(reports, RPT_ERROR, "No active color attribute to bake to");
950  return false;
951  }
952 
953  /* Ensure mesh and editmesh topology are in sync. */
954  ED_object_editmode_load(bmain, ob);
955 
956  targets->images = MEM_callocN(sizeof(BakeImage), "BakeTargets.images");
957  targets->images_num = 1;
958 
959  targets->material_to_image = MEM_callocN(sizeof(int) * ob->totcol,
960  "BakeTargets.material_to_image");
961  targets->materials_num = ob->totcol;
962 
963  BakeImage *bk_image = &targets->images[0];
964  bk_image->width = me->totloop;
965  bk_image->height = 1;
966  bk_image->offset = 0;
967  bk_image->image = NULL;
968 
969  targets->pixels_num = bk_image->width * bk_image->height;
970 
971  return true;
972 }
973 
974 static int find_original_loop(const Mesh *me_orig,
975  const int *vert_origindex,
976  const int *poly_origindex,
977  const int poly_eval,
978  const int vert_eval)
979 {
980  /* Get original vertex and polygon index. There is currently no loop mapping
981  * in modifier stack evaluation. */
982  const int vert_orig = vert_origindex[vert_eval];
983  const int poly_orig = poly_origindex[poly_eval];
984 
985  if (vert_orig == ORIGINDEX_NONE || poly_orig == ORIGINDEX_NONE) {
986  return ORIGINDEX_NONE;
987  }
988 
989  /* Find matching loop with original vertex in original polygon. */
990  MPoly *mpoly_orig = me_orig->mpoly + poly_orig;
991  MLoop *mloop_orig = me_orig->mloop + mpoly_orig->loopstart;
992  for (int j = 0; j < mpoly_orig->totloop; ++j, ++mloop_orig) {
993  if (mloop_orig->v == vert_orig) {
994  return mpoly_orig->loopstart + j;
995  }
996  }
997 
998  return ORIGINDEX_NONE;
999 }
1000 
1002  Object *ob,
1003  Mesh *me_eval,
1004  BakePixel *pixel_array)
1005 {
1006  Mesh *me = ob->data;
1007  const int pixels_num = targets->pixels_num;
1008 
1009  /* Initialize blank pixels. */
1010  for (int i = 0; i < pixels_num; i++) {
1011  BakePixel *pixel = &pixel_array[i];
1012 
1013  pixel->primitive_id = -1;
1014  pixel->object_id = 0;
1015  pixel->seed = 0;
1016  pixel->du_dx = 0.0f;
1017  pixel->du_dy = 0.0f;
1018  pixel->dv_dx = 0.0f;
1019  pixel->dv_dy = 0.0f;
1020  pixel->uv[0] = 0.0f;
1021  pixel->uv[1] = 0.0f;
1022  }
1023 
1024  /* Populate through adjacent triangles, first triangle wins. */
1025  const int tottri = poly_to_tri_count(me_eval->totpoly, me_eval->totloop);
1026  MLoopTri *looptri = MEM_mallocN(sizeof(*looptri) * tottri, __func__);
1027 
1029  me_eval->mloop, me_eval->mpoly, me_eval->mvert, me_eval->totloop, me_eval->totpoly, looptri);
1030 
1031  /* For mapping back to original mesh in case there are modifiers. */
1032  const int *vert_origindex = CustomData_get_layer(&me_eval->vdata, CD_ORIGINDEX);
1033  const int *poly_origindex = CustomData_get_layer(&me_eval->pdata, CD_ORIGINDEX);
1034 
1035  for (int i = 0; i < tottri; i++) {
1036  const MLoopTri *lt = &looptri[i];
1037 
1038  for (int j = 0; j < 3; j++) {
1039  unsigned int l = lt->tri[j];
1040  unsigned int v = me_eval->mloop[l].v;
1041 
1042  /* Map back to original loop if there are modifiers. */
1043  if (vert_origindex != NULL && poly_origindex != NULL) {
1044  l = find_original_loop(me, vert_origindex, poly_origindex, lt->poly, v);
1045  if (l == ORIGINDEX_NONE || l >= me->totloop) {
1046  continue;
1047  }
1048  }
1049 
1050  BakePixel *pixel = &pixel_array[l];
1051 
1052  if (pixel->primitive_id != -1) {
1053  continue;
1054  }
1055 
1056  pixel->primitive_id = i;
1057 
1058  /* Seed is the vertex, so that sampling noise is coherent for the same
1059  * vertex, but different corners can still have different normals,
1060  * materials and UVs. */
1061  pixel->seed = v;
1062 
1063  /* Barycentric coordinates. */
1064  if (j == 0) {
1065  pixel->uv[0] = 1.0f;
1066  pixel->uv[1] = 0.0f;
1067  }
1068  else if (j == 1) {
1069  pixel->uv[0] = 0.0f;
1070  pixel->uv[1] = 1.0f;
1071  }
1072  else if (j == 2) {
1073  pixel->uv[0] = 0.0f;
1074  pixel->uv[1] = 0.0f;
1075  }
1076  }
1077  }
1078 
1079  MEM_freeN(looptri);
1080 }
1081 
1082 static void bake_result_add_to_rgba(float rgba[4], const float *result, const int channels_num)
1083 {
1084  if (channels_num == 4) {
1085  add_v4_v4(rgba, result);
1086  }
1087  else if (channels_num == 3) {
1088  add_v3_v3(rgba, result);
1089  rgba[3] += 1.0f;
1090  }
1091  else {
1092  rgba[0] += result[0];
1093  rgba[1] += result[0];
1094  rgba[2] += result[0];
1095  rgba[3] += 1.0f;
1096  }
1097 }
1098 
1099 static void convert_float_color_to_byte_color(const MPropCol *float_colors,
1100  const int num,
1101  const bool is_noncolor,
1102  MLoopCol *byte_colors)
1103 {
1104  if (is_noncolor) {
1105  for (int i = 0; i < num; i++) {
1106  unit_float_to_uchar_clamp_v4(&byte_colors->r, float_colors[i].color);
1107  }
1108  }
1109  else {
1110  for (int i = 0; i < num; i++) {
1111  linearrgb_to_srgb_uchar4(&byte_colors[i].r, float_colors[i].color);
1112  }
1113  }
1114 }
1115 
1117 {
1118  Mesh *me = ob->data;
1119  BMEditMesh *em = me->edit_mesh;
1120  CustomDataLayer *active_color_layer = BKE_id_attributes_active_color_get(&me->id);
1121  BLI_assert(active_color_layer != NULL);
1122  const eAttrDomain domain = BKE_id_attribute_domain(&me->id, active_color_layer);
1123 
1124  const int channels_num = targets->channels_num;
1125  const bool is_noncolor = targets->is_noncolor;
1126  const float *result = targets->result;
1127 
1128  if (domain == ATTR_DOMAIN_POINT) {
1129  const int totvert = me->totvert;
1130  const int totloop = me->totloop;
1131 
1132  MPropCol *mcol = MEM_malloc_arrayN(totvert, sizeof(MPropCol), __func__);
1133 
1134  /* Accumulate float vertex colors in scene linear color space. */
1135  int *num_loops_for_vertex = MEM_callocN(sizeof(int) * me->totvert, "num_loops_for_vertex");
1136  memset(mcol, 0, sizeof(MPropCol) * me->totvert);
1137 
1138  MLoop *mloop = me->mloop;
1139  for (int i = 0; i < totloop; i++, mloop++) {
1140  const int v = mloop->v;
1141  bake_result_add_to_rgba(mcol[v].color, &result[i * channels_num], channels_num);
1142  num_loops_for_vertex[v]++;
1143  }
1144 
1145  /* Normalize for number of loops. */
1146  for (int i = 0; i < totvert; i++) {
1147  if (num_loops_for_vertex[i] > 0) {
1148  mul_v4_fl(mcol[i].color, 1.0f / num_loops_for_vertex[i]);
1149  }
1150  }
1151 
1152  if (em) {
1153  /* Copy to bmesh. */
1154  const int active_color_offset = CustomData_get_offset_named(
1155  &em->bm->vdata, active_color_layer->type, active_color_layer->name);
1156  BMVert *v;
1157  BMIter viter;
1158  int i = 0;
1159  BM_ITER_MESH (v, &viter, em->bm, BM_VERTS_OF_MESH) {
1160  void *data = BM_ELEM_CD_GET_VOID_P(v, active_color_offset);
1161  if (active_color_layer->type == CD_PROP_COLOR) {
1162  memcpy(data, &mcol[i], sizeof(MPropCol));
1163  }
1164  else {
1165  convert_float_color_to_byte_color(&mcol[i], 1, is_noncolor, data);
1166  }
1167  i++;
1168  }
1169  }
1170  else {
1171  /* Copy to mesh. */
1172  if (active_color_layer->type == CD_PROP_COLOR) {
1173  memcpy(active_color_layer->data, mcol, sizeof(MPropCol) * me->totvert);
1174  }
1175  else {
1176  convert_float_color_to_byte_color(mcol, totvert, is_noncolor, active_color_layer->data);
1177  }
1178  }
1179 
1180  MEM_freeN(mcol);
1181 
1182  MEM_SAFE_FREE(num_loops_for_vertex);
1183  }
1184  else if (domain == ATTR_DOMAIN_CORNER) {
1185  if (em) {
1186  /* Copy to bmesh. */
1187  const int active_color_offset = CustomData_get_offset_named(
1188  &em->bm->ldata, active_color_layer->type, active_color_layer->name);
1189  BMFace *f;
1190  BMIter fiter;
1191  int i = 0;
1192  BM_ITER_MESH (f, &fiter, em->bm, BM_FACES_OF_MESH) {
1193  BMLoop *l;
1194  BMIter liter;
1195  BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
1196  MPropCol color;
1197  zero_v4(color.color);
1198  bake_result_add_to_rgba(color.color, &result[i * channels_num], channels_num);
1199  i++;
1200 
1201  void *data = BM_ELEM_CD_GET_VOID_P(l, active_color_offset);
1202  if (active_color_layer->type == CD_PROP_COLOR) {
1203  memcpy(data, &color, sizeof(MPropCol));
1204  }
1205  else {
1206  convert_float_color_to_byte_color(&color, 1, is_noncolor, data);
1207  }
1208  }
1209  }
1210  }
1211  else {
1212  /* Copy to mesh. */
1213  if (active_color_layer->type == CD_PROP_COLOR) {
1214  MPropCol *colors = active_color_layer->data;
1215  for (int i = 0; i < me->totloop; i++) {
1216  zero_v4(colors[i].color);
1217  bake_result_add_to_rgba(colors[i].color, &result[i * channels_num], channels_num);
1218  }
1219  }
1220  else {
1221  MLoopCol *colors = active_color_layer->data;
1222  for (int i = 0; i < me->totloop; i++) {
1223  MPropCol color;
1224  zero_v4(color.color);
1225  bake_result_add_to_rgba(color.color, &result[i * channels_num], channels_num);
1226  convert_float_color_to_byte_color(&color, 1, is_noncolor, &colors[i]);
1227  }
1228  }
1229  }
1230  }
1231 
1233 
1234  return true;
1235 }
1236 
1237 /* Bake Targets */
1238 
1239 static bool bake_targets_init(const BakeAPIRender *bkr,
1240  BakeTargets *targets,
1241  Object *ob,
1242  Object *ob_eval,
1243  ReportList *reports)
1244 {
1245  if (bkr->target == R_BAKE_TARGET_IMAGE_TEXTURES) {
1246  if (bkr->save_mode == R_BAKE_SAVE_INTERNAL) {
1247  if (!bake_targets_init_internal(bkr, targets, ob_eval, reports)) {
1248  return false;
1249  }
1250  }
1251  else if (bkr->save_mode == R_BAKE_SAVE_EXTERNAL) {
1252  if (!bake_targets_init_external(bkr, targets, ob_eval, reports)) {
1253  return false;
1254  }
1255  }
1256  }
1257  else if (bkr->target == R_BAKE_TARGET_VERTEX_COLORS) {
1258  if (!bake_targets_init_vertex_colors(bkr->main, targets, ob, reports)) {
1259  return false;
1260  }
1261  }
1262 
1263  if (targets->pixels_num == 0) {
1264  return false;
1265  }
1266 
1267  targets->is_noncolor = is_noncolor_pass(bkr->pass_type);
1268  targets->channels_num = RE_pass_depth(bkr->pass_type);
1269  targets->result = MEM_callocN(sizeof(float) * targets->channels_num * targets->pixels_num,
1270  "bake return pixels");
1271 
1272  return true;
1273 }
1274 
1276  BakeTargets *targets,
1277  Object *ob,
1278  Mesh *me_eval,
1279  BakePixel *pixel_array)
1280 {
1281  if (bkr->target == R_BAKE_TARGET_VERTEX_COLORS) {
1282  bake_targets_populate_pixels_color_attributes(targets, ob, me_eval, pixel_array);
1283  }
1284  else {
1285  RE_bake_pixels_populate(me_eval, pixel_array, targets->pixels_num, targets, bkr->uv_layer);
1286  }
1287 }
1288 
1289 static bool bake_targets_output(const BakeAPIRender *bkr,
1290  BakeTargets *targets,
1291  Object *ob,
1292  Object *ob_eval,
1293  Mesh *me_eval,
1294  BakePixel *pixel_array,
1295  ReportList *reports)
1296 {
1297  if (bkr->target == R_BAKE_TARGET_IMAGE_TEXTURES) {
1298  if (bkr->save_mode == R_BAKE_SAVE_INTERNAL) {
1299  return bake_targets_output_internal(bkr, targets, ob, pixel_array, reports, me_eval);
1300  }
1301  if (bkr->save_mode == R_BAKE_SAVE_EXTERNAL) {
1303  bkr, targets, ob, ob_eval, me_eval, pixel_array, reports);
1304  }
1305  }
1306  else if (bkr->target == R_BAKE_TARGET_VERTEX_COLORS) {
1307  return bake_targets_output_vertex_colors(targets, ob);
1308  }
1309 
1310  return false;
1311 }
1312 
1313 static void bake_targets_free(BakeTargets *targets)
1314 {
1315  MEM_SAFE_FREE(targets->images);
1316  MEM_SAFE_FREE(targets->material_to_image);
1317  MEM_SAFE_FREE(targets->result);
1318 }
1319 
1320 /* Main Bake Logic */
1321 
1322 static int bake(const BakeAPIRender *bkr,
1323  Object *ob_low,
1324  const ListBase *selected_objects,
1325  ReportList *reports)
1326 {
1327  Render *re = bkr->render;
1328  Main *bmain = bkr->main;
1329  Scene *scene = bkr->scene;
1330  ViewLayer *view_layer = bkr->view_layer;
1331 
1332  /* We build a depsgraph for the baking,
1333  * so we don't need to change the original data to adjust visibility and modifiers. */
1334  Depsgraph *depsgraph = DEG_graph_new(bmain, scene, view_layer, DAG_EVAL_RENDER);
1336 
1337  int op_result = OPERATOR_CANCELLED;
1338  bool ok = false;
1339 
1340  Object *ob_cage = NULL;
1341  Object *ob_cage_eval = NULL;
1342  Object *ob_low_eval = NULL;
1343 
1344  BakeHighPolyData *highpoly = NULL;
1345  int tot_highpoly = 0;
1346 
1347  Mesh *me_low_eval = NULL;
1348  Mesh *me_cage_eval = NULL;
1349 
1350  MultiresModifierData *mmd_low = NULL;
1351  int mmd_flags_low = 0;
1352 
1353  BakePixel *pixel_array_low = NULL;
1354  BakePixel *pixel_array_high = NULL;
1355 
1356  BakeTargets targets = {NULL};
1357 
1358  const bool preserve_origindex = (bkr->target == R_BAKE_TARGET_VERTEX_COLORS);
1359 
1361 
1362  if (!RE_bake_has_engine(re)) {
1363  BKE_report(reports, RPT_ERROR, "Current render engine does not support baking");
1364  goto cleanup;
1365  }
1366 
1367  if (bkr->uv_layer[0] != '\0') {
1368  Mesh *me = (Mesh *)ob_low->data;
1369  if (CustomData_get_named_layer(&me->ldata, CD_MLOOPUV, bkr->uv_layer) == -1) {
1370  BKE_reportf(reports,
1371  RPT_ERROR,
1372  "No UV layer named \"%s\" found in the object \"%s\"",
1373  bkr->uv_layer,
1374  ob_low->id.name + 2);
1375  goto cleanup;
1376  }
1377  }
1378 
1379  if (bkr->is_selected_to_active) {
1380  CollectionPointerLink *link;
1381  tot_highpoly = 0;
1382 
1383  for (link = selected_objects->first; link; link = link->next) {
1384  Object *ob_iter = link->ptr.data;
1385 
1386  if (ob_iter == ob_low) {
1387  continue;
1388  }
1389 
1390  tot_highpoly++;
1391  }
1392 
1393  if (bkr->is_cage && bkr->custom_cage[0] != '\0') {
1394  ob_cage = BLI_findstring(&bmain->objects, bkr->custom_cage, offsetof(ID, name) + 2);
1395 
1396  if (ob_cage == NULL || ob_cage->type != OB_MESH) {
1397  BKE_report(reports, RPT_ERROR, "No valid cage object");
1398  goto cleanup;
1399  }
1400  else {
1401  ob_cage_eval = DEG_get_evaluated_object(depsgraph, ob_cage);
1402  ob_cage_eval->visibility_flag |= OB_HIDE_RENDER;
1404  }
1405  }
1406  }
1407 
1408  /* for multires bake, use linear UV subdivision to match low res UVs */
1410  !bkr->is_selected_to_active) {
1412  if (mmd_low) {
1413  mmd_flags_low = mmd_low->flags;
1414  mmd_low->uv_smooth = SUBSURF_UV_SMOOTH_NONE;
1415  }
1416  }
1417 
1418  /* Make sure depsgraph is up to date. */
1420  ob_low_eval = DEG_get_evaluated_object(depsgraph, ob_low);
1421 
1422  /* get the mesh as it arrives in the renderer */
1423  me_low_eval = bake_mesh_new_from_object(depsgraph, ob_low_eval, preserve_origindex);
1424 
1425  /* Initialize bake targets. */
1426  if (!bake_targets_init(bkr, &targets, ob_low, ob_low_eval, reports)) {
1427  goto cleanup;
1428  }
1429 
1430  /* Populate the pixel array with the face data. Except if we use a cage, then
1431  * it is populated later with the cage mesh (smoothed version of the mesh). */
1432  pixel_array_low = MEM_mallocN(sizeof(BakePixel) * targets.pixels_num, "bake pixels low poly");
1433  if ((bkr->is_selected_to_active && (ob_cage == NULL) && bkr->is_cage) == false) {
1434  bake_targets_populate_pixels(bkr, &targets, ob_low, me_low_eval, pixel_array_low);
1435  }
1436 
1437  if (bkr->is_selected_to_active) {
1438  CollectionPointerLink *link;
1439  int i = 0;
1440 
1441  /* prepare cage mesh */
1442  if (ob_cage) {
1443  me_cage_eval = bake_mesh_new_from_object(depsgraph, ob_cage_eval, preserve_origindex);
1444  if ((me_low_eval->totpoly != me_cage_eval->totpoly) ||
1445  (me_low_eval->totloop != me_cage_eval->totloop)) {
1446  BKE_report(reports,
1447  RPT_ERROR,
1448  "Invalid cage object, the cage mesh must have the same number "
1449  "of faces as the active object");
1450  goto cleanup;
1451  }
1452  }
1453  else if (bkr->is_cage) {
1454  bool is_changed = false;
1455 
1456  ModifierData *md = ob_low_eval->modifiers.first;
1457  while (md) {
1458  ModifierData *md_next = md->next;
1459 
1460  /* Edge Split cannot be applied in the cage,
1461  * the cage is supposed to have interpolated normals
1462  * between the faces unless the geometry is physically
1463  * split. So we create a copy of the low poly mesh without
1464  * the eventual edge split. */
1465 
1466  if (md->type == eModifierType_EdgeSplit) {
1467  BLI_remlink(&ob_low_eval->modifiers, md);
1468  BKE_modifier_free(md);
1469  is_changed = true;
1470  }
1471  md = md_next;
1472  }
1473 
1474  if (is_changed) {
1475  /* Make sure object is evaluated with the new modifier settings.
1476  *
1477  * NOTE: Since the dependency graph was fully evaluated prior to bake, and we only made
1478  * single modification to this object all the possible dependencies for evaluation are
1479  * already up to date. This means we can do a cheap single object update
1480  * (as an opposite of full depsgraph update). */
1481  BKE_object_eval_reset(ob_low_eval);
1483  }
1484 
1485  me_cage_eval = BKE_mesh_new_from_object(NULL, ob_low_eval, false, preserve_origindex);
1486  bake_targets_populate_pixels(bkr, &targets, ob_low, me_cage_eval, pixel_array_low);
1487  }
1488 
1489  highpoly = MEM_callocN(sizeof(BakeHighPolyData) * tot_highpoly, "bake high poly objects");
1490 
1491  /* populate highpoly array */
1492  for (link = selected_objects->first; link; link = link->next) {
1493  Object *ob_iter = link->ptr.data;
1494 
1495  if (ob_iter == ob_low) {
1496  continue;
1497  }
1498 
1499  /* initialize highpoly_data */
1500  highpoly[i].ob = ob_iter;
1501  highpoly[i].ob_eval = DEG_get_evaluated_object(depsgraph, ob_iter);
1502  highpoly[i].ob_eval->visibility_flag &= ~OB_HIDE_RENDER;
1504  highpoly[i].me = BKE_mesh_new_from_object(NULL, highpoly[i].ob_eval, false, false);
1505 
1506  /* Low-poly to high-poly transformation matrix. */
1507  copy_m4_m4(highpoly[i].obmat, highpoly[i].ob->obmat);
1508  invert_m4_m4(highpoly[i].imat, highpoly[i].obmat);
1509 
1510  highpoly[i].is_flip_object = is_negative_m4(highpoly[i].ob->obmat);
1511 
1512  i++;
1513  }
1514 
1515  BLI_assert(i == tot_highpoly);
1516 
1517  if (ob_cage != NULL) {
1518  ob_cage_eval->visibility_flag |= OB_HIDE_RENDER;
1520  }
1521  ob_low_eval->visibility_flag |= OB_HIDE_RENDER;
1523 
1524  /* populate the pixel arrays with the corresponding face data for each high poly object */
1525  pixel_array_high = MEM_mallocN(sizeof(BakePixel) * targets.pixels_num,
1526  "bake pixels high poly");
1527 
1528  if (!RE_bake_pixels_populate_from_objects(me_low_eval,
1529  pixel_array_low,
1530  pixel_array_high,
1531  highpoly,
1532  tot_highpoly,
1533  targets.pixels_num,
1534  ob_cage != NULL,
1535  bkr->cage_extrusion,
1536  bkr->max_ray_distance,
1537  ob_low_eval->obmat,
1538  (ob_cage ? ob_cage->obmat : ob_low_eval->obmat),
1539  me_cage_eval)) {
1540  BKE_report(reports, RPT_ERROR, "Error handling selected objects");
1541  goto cleanup;
1542  }
1543 
1544  /* the baking itself */
1545  for (i = 0; i < tot_highpoly; i++) {
1546  ok = RE_bake_engine(re,
1547  depsgraph,
1548  highpoly[i].ob,
1549  i,
1550  pixel_array_high,
1551  &targets,
1552  bkr->pass_type,
1553  bkr->pass_filter,
1554  targets.result);
1555  if (!ok) {
1556  BKE_reportf(
1557  reports, RPT_ERROR, "Error baking from object \"%s\"", highpoly[i].ob->id.name + 2);
1558  goto cleanup;
1559  }
1560  }
1561  }
1562  else {
1563  /* If low poly is not renderable it should have failed long ago. */
1564  BLI_assert((ob_low_eval->visibility_flag & OB_HIDE_RENDER) == 0);
1565 
1566  if (RE_bake_has_engine(re)) {
1567  ok = RE_bake_engine(re,
1568  depsgraph,
1569  ob_low_eval,
1570  0,
1571  pixel_array_low,
1572  &targets,
1573  bkr->pass_type,
1574  bkr->pass_filter,
1575  targets.result);
1576  }
1577  else {
1578  BKE_report(reports, RPT_ERROR, "Current render engine does not support baking");
1579  goto cleanup;
1580  }
1581  }
1582 
1583  /* normal space conversion
1584  * the normals are expected to be in world space, +X +Y +Z */
1585  if (ok && bkr->pass_type == SCE_PASS_NORMAL) {
1586  switch (bkr->normal_space) {
1587  case R_BAKE_SPACE_WORLD: {
1588  /* Cycles internal format */
1589  if ((bkr->normal_swizzle[0] == R_BAKE_POSX) && (bkr->normal_swizzle[1] == R_BAKE_POSY) &&
1590  (bkr->normal_swizzle[2] == R_BAKE_POSZ)) {
1591  break;
1592  }
1593  RE_bake_normal_world_to_world(pixel_array_low,
1594  targets.pixels_num,
1595  targets.channels_num,
1596  targets.result,
1597  bkr->normal_swizzle);
1598  break;
1599  }
1600  case R_BAKE_SPACE_OBJECT: {
1601  RE_bake_normal_world_to_object(pixel_array_low,
1602  targets.pixels_num,
1603  targets.channels_num,
1604  targets.result,
1605  ob_low_eval,
1606  bkr->normal_swizzle);
1607  break;
1608  }
1609  case R_BAKE_SPACE_TANGENT: {
1610  if (bkr->is_selected_to_active) {
1611  RE_bake_normal_world_to_tangent(pixel_array_low,
1612  targets.pixels_num,
1613  targets.channels_num,
1614  targets.result,
1615  me_low_eval,
1616  bkr->normal_swizzle,
1617  ob_low_eval->obmat);
1618  }
1619  else {
1620  /* From multi-resolution. */
1621  Mesh *me_nores = NULL;
1622  ModifierData *md = NULL;
1623  int mode;
1624 
1625  BKE_object_eval_reset(ob_low_eval);
1627 
1628  if (md) {
1629  mode = md->mode;
1630  md->mode &= ~eModifierMode_Render;
1631 
1632  /* Evaluate modifiers again. */
1633  me_nores = BKE_mesh_new_from_object(NULL, ob_low_eval, false, false);
1634  bake_targets_populate_pixels(bkr, &targets, ob_low, me_nores, pixel_array_low);
1635  }
1636 
1637  RE_bake_normal_world_to_tangent(pixel_array_low,
1638  targets.pixels_num,
1639  targets.channels_num,
1640  targets.result,
1641  (me_nores) ? me_nores : me_low_eval,
1642  bkr->normal_swizzle,
1643  ob_low_eval->obmat);
1644 
1645  if (md) {
1646  BKE_id_free(NULL, &me_nores->id);
1647  md->mode = mode;
1648  }
1649  }
1650  break;
1651  }
1652  default:
1653  break;
1654  }
1655  }
1656 
1657  if (!ok) {
1658  BKE_reportf(reports, RPT_ERROR, "Problem baking object \"%s\"", ob_low->id.name + 2);
1659  op_result = OPERATOR_CANCELLED;
1660  }
1661  else {
1662  /* save the results */
1663  if (bake_targets_output(
1664  bkr, &targets, ob_low, ob_low_eval, me_low_eval, pixel_array_low, reports)) {
1665  op_result = OPERATOR_FINISHED;
1666  }
1667  else {
1668  op_result = OPERATOR_CANCELLED;
1669  }
1670  }
1671 
1672  bake_targets_refresh(&targets);
1673 
1674 cleanup:
1675 
1676  if (highpoly) {
1677  for (int i = 0; i < tot_highpoly; i++) {
1678  if (highpoly[i].me != NULL) {
1679  BKE_id_free(NULL, &highpoly[i].me->id);
1680  }
1681  }
1682  MEM_freeN(highpoly);
1683  }
1684 
1685  if (mmd_low) {
1686  mmd_low->flags = mmd_flags_low;
1687  }
1688 
1689  if (pixel_array_low) {
1690  MEM_freeN(pixel_array_low);
1691  }
1692 
1693  if (pixel_array_high) {
1694  MEM_freeN(pixel_array_high);
1695  }
1696 
1697  bake_targets_free(&targets);
1698 
1699  if (me_low_eval != NULL) {
1700  BKE_id_free(NULL, &me_low_eval->id);
1701  }
1702 
1703  if (me_cage_eval != NULL) {
1704  BKE_id_free(NULL, &me_cage_eval->id);
1705  }
1706 
1708 
1709  return op_result;
1710 }
1711 
1712 /* Bake Operator */
1713 
1715 {
1716  bScreen *screen = CTX_wm_screen(C);
1717 
1718  bkr->ob = CTX_data_active_object(C);
1719  bkr->main = CTX_data_main(C);
1721  bkr->scene = CTX_data_scene(C);
1722  bkr->area = screen ? BKE_screen_find_big_area(screen, SPACE_IMAGE, 10) : NULL;
1723 
1724  bkr->pass_type = RNA_enum_get(op->ptr, "type");
1725  bkr->pass_filter = RNA_enum_get(op->ptr, "pass_filter");
1726  bkr->margin = RNA_int_get(op->ptr, "margin");
1727  bkr->margin_type = RNA_enum_get(op->ptr, "margin_type");
1728 
1729  bkr->save_mode = (eBakeSaveMode)RNA_enum_get(op->ptr, "save_mode");
1730  bkr->target = (eBakeTarget)RNA_enum_get(op->ptr, "target");
1731 
1732  bkr->is_clear = RNA_boolean_get(op->ptr, "use_clear");
1734  bkr->save_mode == R_BAKE_SAVE_EXTERNAL) &&
1735  RNA_boolean_get(op->ptr, "use_split_materials");
1736  bkr->is_automatic_name = RNA_boolean_get(op->ptr, "use_automatic_name");
1737  bkr->is_selected_to_active = RNA_boolean_get(op->ptr, "use_selected_to_active");
1738  bkr->is_cage = RNA_boolean_get(op->ptr, "use_cage");
1739  bkr->cage_extrusion = RNA_float_get(op->ptr, "cage_extrusion");
1740  bkr->max_ray_distance = RNA_float_get(op->ptr, "max_ray_distance");
1741 
1742  bkr->normal_space = RNA_enum_get(op->ptr, "normal_space");
1743  bkr->normal_swizzle[0] = RNA_enum_get(op->ptr, "normal_r");
1744  bkr->normal_swizzle[1] = RNA_enum_get(op->ptr, "normal_g");
1745  bkr->normal_swizzle[2] = RNA_enum_get(op->ptr, "normal_b");
1746 
1747  bkr->width = RNA_int_get(op->ptr, "width");
1748  bkr->height = RNA_int_get(op->ptr, "height");
1749  bkr->identifier = "";
1750 
1751  RNA_string_get(op->ptr, "uv_layer", bkr->uv_layer);
1752 
1753  RNA_string_get(op->ptr, "cage_object", bkr->custom_cage);
1754 
1755  if (bkr->save_mode == R_BAKE_SAVE_EXTERNAL && bkr->is_automatic_name) {
1756  PropertyRNA *prop = RNA_struct_find_property(op->ptr, "type");
1757  RNA_property_enum_identifier(C, op->ptr, prop, bkr->pass_type, &bkr->identifier);
1758  }
1759 
1761 
1762  bkr->reports = op->reports;
1763 
1764  bkr->result = OPERATOR_CANCELLED;
1765 
1766  bkr->render = RE_NewSceneRender(bkr->scene);
1767 
1768  /* XXX hack to force saving to always be internal. Whether (and how) to support
1769  * external saving will be addressed later */
1770  if (bkr->save_mode == R_BAKE_SAVE_EXTERNAL) {
1772  }
1773 
1774  if (((bkr->pass_type == SCE_PASS_NORMAL) && (bkr->normal_space == R_BAKE_SPACE_TANGENT)) ||
1775  bkr->pass_type == SCE_PASS_UV) {
1776  bkr->margin_type = R_BAKE_EXTEND;
1777  }
1778 }
1779 
1780 static int bake_exec(bContext *C, wmOperator *op)
1781 {
1782  Render *re;
1783  int result = OPERATOR_CANCELLED;
1784  BakeAPIRender bkr = {NULL};
1786 
1787  G.is_break = false;
1788  G.is_rendering = true;
1789 
1790  bake_set_props(op, scene);
1791 
1792  bake_init_api_data(op, C, &bkr);
1793  re = bkr.render;
1794 
1795  /* setup new render */
1797 
1798  if (!bake_pass_filter_check(bkr.pass_type, bkr.pass_filter, bkr.reports)) {
1799  goto finally;
1800  }
1801 
1802  if (!bake_objects_check(bkr.main,
1803  bkr.view_layer,
1804  bkr.ob,
1805  &bkr.selected_objects,
1806  bkr.reports,
1808  bkr.target)) {
1809  goto finally;
1810  }
1811 
1812  if (bkr.is_clear) {
1813  const bool is_tangent = ((bkr.pass_type == SCE_PASS_NORMAL) &&
1815  bake_targets_clear(bkr.main, is_tangent);
1816  }
1817 
1818  RE_SetReports(re, bkr.reports);
1819 
1820  if (bkr.is_selected_to_active) {
1821  result = bake(&bkr, bkr.ob, &bkr.selected_objects, bkr.reports);
1822  }
1823  else {
1824  CollectionPointerLink *link;
1826  for (link = bkr.selected_objects.first; link; link = link->next) {
1827  Object *ob_iter = link->ptr.data;
1828  result = bake(&bkr, ob_iter, NULL, bkr.reports);
1829  }
1830  }
1831 
1832  RE_SetReports(re, NULL);
1833 
1834 finally:
1835  G.is_rendering = false;
1837  return result;
1838 }
1839 
1840 static void bake_startjob(void *bkv, short *UNUSED(stop), short *do_update, float *progress)
1841 {
1842  BakeAPIRender *bkr = (BakeAPIRender *)bkv;
1843 
1844  /* setup new render */
1845  bkr->do_update = do_update;
1846  bkr->progress = progress;
1847 
1848  RE_SetReports(bkr->render, bkr->reports);
1849 
1850  if (!bake_pass_filter_check(bkr->pass_type, bkr->pass_filter, bkr->reports)) {
1851  bkr->result = OPERATOR_CANCELLED;
1852  return;
1853  }
1854 
1855  if (!bake_objects_check(bkr->main,
1856  bkr->view_layer,
1857  bkr->ob,
1858  &bkr->selected_objects,
1859  bkr->reports,
1860  bkr->is_selected_to_active,
1861  bkr->target)) {
1862  bkr->result = OPERATOR_CANCELLED;
1863  return;
1864  }
1865 
1866  if (bkr->is_clear) {
1867  const bool is_tangent = ((bkr->pass_type == SCE_PASS_NORMAL) &&
1869  bake_targets_clear(bkr->main, is_tangent);
1870  }
1871 
1872  if (bkr->is_selected_to_active) {
1873  bkr->result = bake(bkr, bkr->ob, &bkr->selected_objects, bkr->reports);
1874  }
1875  else {
1876  CollectionPointerLink *link;
1878  for (link = bkr->selected_objects.first; link; link = link->next) {
1879  Object *ob_iter = link->ptr.data;
1880  bkr->result = bake(bkr, ob_iter, NULL, bkr->reports);
1881 
1882  if (bkr->result == OPERATOR_CANCELLED) {
1883  return;
1884  }
1885  }
1886  }
1887 
1888  RE_SetReports(bkr->render, NULL);
1889 }
1890 
1891 static void bake_job_complete(void *bkv)
1892 {
1893  BakeAPIRender *bkr = (BakeAPIRender *)bkv;
1895 }
1896 static void bake_job_canceled(void *bkv)
1897 {
1898  BakeAPIRender *bkr = (BakeAPIRender *)bkv;
1900 }
1901 
1902 static void bake_freejob(void *bkv)
1903 {
1904  BakeAPIRender *bkr = (BakeAPIRender *)bkv;
1905 
1907  MEM_freeN(bkr);
1908 
1909  G.is_rendering = false;
1910 }
1911 
1913 {
1914  PropertyRNA *prop;
1915  BakeData *bake = &scene->r.bake;
1916 
1917  prop = RNA_struct_find_property(op->ptr, "filepath");
1918  if (!RNA_property_is_set(op->ptr, prop)) {
1919  RNA_property_string_set(op->ptr, prop, bake->filepath);
1920  }
1921 
1922  prop = RNA_struct_find_property(op->ptr, "width");
1923  if (!RNA_property_is_set(op->ptr, prop)) {
1924  RNA_property_int_set(op->ptr, prop, bake->width);
1925  }
1926 
1927  prop = RNA_struct_find_property(op->ptr, "height");
1928  if (!RNA_property_is_set(op->ptr, prop)) {
1929  RNA_property_int_set(op->ptr, prop, bake->width);
1930  }
1931 
1932  prop = RNA_struct_find_property(op->ptr, "margin");
1933  if (!RNA_property_is_set(op->ptr, prop)) {
1934  RNA_property_int_set(op->ptr, prop, bake->margin);
1935  }
1936 
1937  prop = RNA_struct_find_property(op->ptr, "margin_type");
1938  if (!RNA_property_is_set(op->ptr, prop)) {
1939  RNA_property_enum_set(op->ptr, prop, bake->margin_type);
1940  }
1941 
1942  prop = RNA_struct_find_property(op->ptr, "use_selected_to_active");
1943  if (!RNA_property_is_set(op->ptr, prop)) {
1944  RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_TO_ACTIVE) != 0);
1945  }
1946 
1947  prop = RNA_struct_find_property(op->ptr, "max_ray_distance");
1948  if (!RNA_property_is_set(op->ptr, prop)) {
1949  RNA_property_float_set(op->ptr, prop, bake->max_ray_distance);
1950  }
1951 
1952  prop = RNA_struct_find_property(op->ptr, "cage_extrusion");
1953  if (!RNA_property_is_set(op->ptr, prop)) {
1954  RNA_property_float_set(op->ptr, prop, bake->cage_extrusion);
1955  }
1956 
1957  prop = RNA_struct_find_property(op->ptr, "cage_object");
1958  if (!RNA_property_is_set(op->ptr, prop)) {
1960  op->ptr, prop, (bake->cage_object) ? bake->cage_object->id.name + 2 : "");
1961  }
1962 
1963  prop = RNA_struct_find_property(op->ptr, "normal_space");
1964  if (!RNA_property_is_set(op->ptr, prop)) {
1965  RNA_property_enum_set(op->ptr, prop, bake->normal_space);
1966  }
1967 
1968  prop = RNA_struct_find_property(op->ptr, "normal_r");
1969  if (!RNA_property_is_set(op->ptr, prop)) {
1970  RNA_property_enum_set(op->ptr, prop, bake->normal_swizzle[0]);
1971  }
1972 
1973  prop = RNA_struct_find_property(op->ptr, "normal_g");
1974  if (!RNA_property_is_set(op->ptr, prop)) {
1975  RNA_property_enum_set(op->ptr, prop, bake->normal_swizzle[1]);
1976  }
1977 
1978  prop = RNA_struct_find_property(op->ptr, "normal_b");
1979  if (!RNA_property_is_set(op->ptr, prop)) {
1980  RNA_property_enum_set(op->ptr, prop, bake->normal_swizzle[2]);
1981  }
1982 
1983  prop = RNA_struct_find_property(op->ptr, "target");
1984  if (!RNA_property_is_set(op->ptr, prop)) {
1985  RNA_property_enum_set(op->ptr, prop, bake->target);
1986  }
1987 
1988  prop = RNA_struct_find_property(op->ptr, "save_mode");
1989  if (!RNA_property_is_set(op->ptr, prop)) {
1990  RNA_property_enum_set(op->ptr, prop, bake->save_mode);
1991  }
1992 
1993  prop = RNA_struct_find_property(op->ptr, "use_clear");
1994  if (!RNA_property_is_set(op->ptr, prop)) {
1995  RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_CLEAR) != 0);
1996  }
1997 
1998  prop = RNA_struct_find_property(op->ptr, "use_cage");
1999  if (!RNA_property_is_set(op->ptr, prop)) {
2000  RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_CAGE) != 0);
2001  }
2002 
2003  prop = RNA_struct_find_property(op->ptr, "use_split_materials");
2004  if (!RNA_property_is_set(op->ptr, prop)) {
2005  RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_SPLIT_MAT) != 0);
2006  }
2007 
2008  prop = RNA_struct_find_property(op->ptr, "use_automatic_name");
2009  if (!RNA_property_is_set(op->ptr, prop)) {
2010  RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_AUTO_NAME) != 0);
2011  }
2012 
2013  prop = RNA_struct_find_property(op->ptr, "pass_filter");
2014  if (!RNA_property_is_set(op->ptr, prop)) {
2015  RNA_property_enum_set(op->ptr, prop, bake->pass_filter);
2016  }
2017 }
2018 
2019 static int bake_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
2020 {
2021  wmJob *wm_job;
2022  BakeAPIRender *bkr;
2023  Render *re;
2025 
2026  bake_set_props(op, scene);
2027 
2028  /* only one render job at a time */
2030  return OPERATOR_CANCELLED;
2031  }
2032 
2033  bkr = MEM_mallocN(sizeof(BakeAPIRender), "render bake");
2034 
2035  /* init bake render */
2036  bake_init_api_data(op, C, bkr);
2038  re = bkr->render;
2039 
2040  /* setup new render */
2043 
2044  /* setup job */
2045  wm_job = WM_jobs_get(CTX_wm_manager(C),
2046  CTX_wm_window(C),
2047  scene,
2048  "Texture Bake",
2051  WM_jobs_customdata_set(wm_job, bkr, bake_freejob);
2052  /* TODO: only draw bake image, can we enforce this. */
2053  WM_jobs_timer(
2054  wm_job, 0.5, (bkr->target == R_BAKE_TARGET_VERTEX_COLORS) ? NC_GEOM | ND_DATA : NC_IMAGE, 0);
2057 
2058  G.is_break = false;
2059  G.is_rendering = true;
2060 
2061  WM_jobs_start(CTX_wm_manager(C), wm_job);
2062 
2063  WM_cursor_wait(false);
2064 
2065  /* add modal handler for ESC */
2067 
2069  return OPERATOR_RUNNING_MODAL;
2070 }
2071 
2073 {
2074  PropertyRNA *prop;
2075 
2076  /* identifiers */
2077  ot->name = "Bake";
2078  ot->description = "Bake image textures of selected objects";
2079  ot->idname = "OBJECT_OT_bake";
2080 
2081  /* api callbacks */
2082  ot->exec = bake_exec;
2083  ot->modal = bake_modal;
2084  ot->invoke = bake_invoke;
2086 
2087  RNA_def_enum(
2088  ot->srna,
2089  "type",
2092  "Type",
2093  "Type of pass to bake, some of them may not be supported by the current render engine");
2094  prop = RNA_def_enum(ot->srna,
2095  "pass_filter",
2098  "Pass Filter",
2099  "Filter to combined, diffuse, glossy, transmission and subsurface passes");
2102  "filepath",
2103  NULL,
2104  FILE_MAX,
2105  "File Path",
2106  "Image filepath to use when saving externally");
2107  RNA_def_int(ot->srna,
2108  "width",
2109  512,
2110  1,
2111  INT_MAX,
2112  "Width",
2113  "Horizontal dimension of the baking map (external only)",
2114  64,
2115  4096);
2116  RNA_def_int(ot->srna,
2117  "height",
2118  512,
2119  1,
2120  INT_MAX,
2121  "Height",
2122  "Vertical dimension of the baking map (external only)",
2123  64,
2124  4096);
2125  RNA_def_int(ot->srna,
2126  "margin",
2127  16,
2128  0,
2129  INT_MAX,
2130  "Margin",
2131  "Extends the baked result as a post process filter",
2132  0,
2133  64);
2134  RNA_def_enum(ot->srna,
2135  "margin_type",
2137  R_BAKE_EXTEND,
2138  "Margin Type",
2139  "Which algorithm to use to generate the margin");
2141  "use_selected_to_active",
2142  false,
2143  "Selected to Active",
2144  "Bake shading on the surface of selected objects to the active object");
2146  "max_ray_distance",
2147  0.0f,
2148  0.0f,
2149  FLT_MAX,
2150  "Max Ray Distance",
2151  "The maximum ray distance for matching points between the active and selected "
2152  "objects. If zero, there is no limit",
2153  0.0f,
2154  1.0f);
2156  "cage_extrusion",
2157  0.0f,
2158  0.0f,
2159  FLT_MAX,
2160  "Cage Extrusion",
2161  "Inflate the active object by the specified distance for baking. This helps "
2162  "matching to points nearer to the outside of the selected object meshes",
2163  0.0f,
2164  1.0f);
2166  "cage_object",
2167  NULL,
2168  MAX_NAME,
2169  "Cage Object",
2170  "Object to use as cage, instead of calculating the cage from the active object "
2171  "with cage extrusion");
2172  RNA_def_enum(ot->srna,
2173  "normal_space",
2176  "Normal Space",
2177  "Choose normal space for baking");
2178  RNA_def_enum(ot->srna,
2179  "normal_r",
2181  R_BAKE_POSX,
2182  "R",
2183  "Axis to bake in red channel");
2184  RNA_def_enum(ot->srna,
2185  "normal_g",
2187  R_BAKE_POSY,
2188  "G",
2189  "Axis to bake in green channel");
2190  RNA_def_enum(ot->srna,
2191  "normal_b",
2193  R_BAKE_POSZ,
2194  "B",
2195  "Axis to bake in blue channel");
2196  RNA_def_enum(ot->srna,
2197  "target",
2200  "Target",
2201  "Where to output the baked map");
2202  RNA_def_enum(ot->srna,
2203  "save_mode",
2206  "Save Mode",
2207  "Where to save baked image textures");
2209  "use_clear",
2210  false,
2211  "Clear",
2212  "Clear images before baking (only for internal saving)");
2213  RNA_def_boolean(ot->srna, "use_cage", false, "Cage", "Cast rays to active object from a cage");
2215  ot->srna,
2216  "use_split_materials",
2217  false,
2218  "Split Materials",
2219  "Split baked maps per material, using material name in output file (external only)");
2221  "use_automatic_name",
2222  false,
2223  "Automatic Name",
2224  "Automatically name the output file with the pass type");
2226  "uv_layer",
2227  NULL,
2229  "UV Layer",
2230  "UV layer to override active");
2231 }
Generic geometry attributes built on CustomData.
eAttrDomain
Definition: BKE_attribute.h:25
@ ATTR_DOMAIN_POINT
Definition: BKE_attribute.h:27
@ ATTR_DOMAIN_CORNER
Definition: BKE_attribute.h:30
struct CustomDataLayer * BKE_id_attributes_active_color_get(const struct ID *id)
eAttrDomain BKE_id_attribute_domain(const struct ID *id, const struct CustomDataLayer *layer)
@ BKE_CB_EVT_OBJECT_BAKE_CANCEL
@ BKE_CB_EVT_OBJECT_BAKE_COMPLETE
@ BKE_CB_EVT_OBJECT_BAKE_PRE
void BKE_callback_exec_id(struct Main *bmain, struct ID *id, eCbEvent evt)
Definition: callbacks.c:46
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1090
int CTX_data_selected_objects(const bContext *C, ListBase *list)
Definition: context.c:1323
struct wmWindowManager * CTX_wm_manager(const bContext *C)
Definition: context.c:713
struct ViewLayer * CTX_data_view_layer(const bContext *C)
Definition: context.c:1100
struct Object * CTX_data_active_object(const bContext *C)
Definition: context.c:1353
struct bScreen * CTX_wm_screen(const bContext *C)
Definition: context.c:733
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1074
struct wmWindow * CTX_wm_window(const bContext *C)
Definition: context.c:723
int CustomData_get_active_layer_index(const struct CustomData *data, int type)
int CustomData_get_offset_named(const CustomData *data, int type, const char *name)
Definition: customdata.cc:3419
#define ORIGINDEX_NONE
void * CustomData_get_layer(const struct CustomData *data, int type)
int CustomData_get_named_layer(const struct CustomData *data, int type, const char *name)
void BKE_image_release_ibuf(struct Image *ima, struct ImBuf *ibuf, void *lock)
void BKE_image_get_tile_uv(const struct Image *ima, const int tile_number, float r_uv[2])
int BKE_imbuf_write(struct ImBuf *ibuf, const char *name, const struct ImageFormatData *imf)
struct ImBuf * BKE_image_acquire_ibuf(struct Image *ima, struct ImageUser *iuser, void **r_lock)
void BKE_image_partial_update_mark_full_update(struct Image *image)
Mark the whole image to be updated.
void BKE_image_free_gputextures(struct Image *ima)
Definition: image_gpu.cc:516
void BKE_image_mark_dirty(struct Image *image, struct ImBuf *ibuf)
void BKE_imageuser_default(struct ImageUser *iuser)
void BKE_image_path_from_imtype(char *string, const char *base, const char *relbase, int frame, char imtype, bool use_ext, bool use_frames, const char *suffix)
struct Base * BKE_view_layer_base_find(struct ViewLayer *view_layer, struct Object *ob)
Definition: layer.c:379
void BKE_main_id_tag_idcode(struct Main *mainvar, short type, int tag, bool value)
Definition: lib_id.c:920
void BKE_id_free(struct Main *bmain, void *idv)
const char * BKE_main_blendfile_path(const struct Main *bmain) ATTR_NONNULL()
General operations, lookup, etc. for materials.
struct Material * BKE_object_material_get(struct Object *ob, short act)
Definition: material.c:687
void BKE_mesh_recalc_looptri(const struct MLoop *mloop, const struct MPoly *mpoly, const struct MVert *mvert, int totloop, int totpoly, struct MLoopTri *mlooptri)
struct Mesh * BKE_mesh_new_from_object(struct Depsgraph *depsgraph, struct Object *object, bool preserve_all_data_layers, bool preserve_origindex)
void BKE_mesh_split_faces(struct Mesh *mesh, bool free_loop_normals)
Definition: mesh.cc:2121
void BKE_modifier_free(struct ModifierData *md)
struct ModifierData * BKE_modifiers_findby_type(const struct Object *ob, ModifierType type)
bool BKE_node_is_connected_to_output(struct bNodeTree *ntree, struct bNode *node)
Definition: node_common.cc:405
General operations, lookup, etc. for blender objects.
void BKE_object_handle_data_update(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob)
void BKE_object_eval_reset(struct Object *ob_eval)
Definition: object_update.c:54
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition: report.c:83
void BKE_scene_graph_update_tagged(struct Depsgraph *depsgraph, struct Main *bmain)
Definition: scene.cc:2648
struct ARegion struct ARegion struct ScrArea struct ScrArea * BKE_screen_find_big_area(struct bScreen *screen, int spacetype, short min)
Definition: screen.c:937
#define BLI_assert(a)
Definition: BLI_assert.h:46
File and directory operations.
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:269
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:466
void void BLI_INLINE bool BLI_listbase_is_single(const struct ListBase *lb)
Definition: BLI_listbase.h:265
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:100
void * BLI_findstring(const struct ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE void linearrgb_to_srgb_uchar4(unsigned char srgb[4], const float linear[4])
MINLINE int poly_to_tri_count(int poly_count, int corner_count)
bool invert_m4_m4(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1287
void copy_m4_m4(float m1[4][4], const float m2[4][4])
Definition: math_matrix.c:77
bool is_negative_m4(const float mat[4][4])
Definition: math_matrix.c:2509
MINLINE void mul_v4_fl(float r[4], float f)
MINLINE void add_v4_v4(float r[4], const float a[4])
MINLINE void zero_v4(float r[4])
MINLINE void add_v3_v3(float r[3], const float a[3])
#define FILE_MAX
bool BLI_path_suffix(char *string, size_t maxlen, const char *suffix, const char *sep) ATTR_NONNULL()
Definition: path_util.c:588
#define SNPRINTF(dst, format,...)
Definition: BLI_string.h:485
unsigned char uchar
Definition: BLI_sys_types.h:70
#define UNUSED(x)
#define ELEM(...)
Depsgraph * DEG_graph_new(struct Main *bmain, struct Scene *scene, struct ViewLayer *view_layer, eEvaluationMode mode)
Definition: depsgraph.cc:267
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
@ DAG_EVAL_RENDER
Definition: DEG_depsgraph.h:46
void DEG_graph_free(Depsgraph *graph)
Definition: depsgraph.cc:295
void DEG_id_tag_update(struct ID *id, int flag)
void DEG_graph_build_from_view_layer(struct Depsgraph *graph)
struct Object * DEG_get_evaluated_object(const struct Depsgraph *depsgraph, struct Object *object)
@ ID_RECALC_GEOMETRY
Definition: DNA_ID.h:791
@ LIB_TAG_DOIT
Definition: DNA_ID.h:707
@ ID_IM
Definition: DNA_ID_enums.h:53
#define MAX_CUSTOMDATA_LAYER_NAME
@ CD_ORIGINDEX
@ CD_PROP_COLOR
@ CD_MLOOPUV
#define MAX_NAME
Definition: DNA_defs.h:48
@ BASE_ENABLED_RENDER
@ BASE_VISIBLE_DEPSGRAPH
@ ME_AUTOSMOOTH
@ eModifierMode_Render
@ eModifierType_EdgeSplit
@ eModifierType_Multires
@ SUBSURF_UV_SMOOTH_NONE
Object is a sort of wrapper for general info.
@ OB_HIDE_RENDER
@ OB_MBALL
@ OB_SURF
@ OB_FONT
@ OB_MESH
@ OB_CURVES_LEGACY
#define R_BAKE_CLEAR
#define R_BAKE_SPACE_OBJECT
#define R_BAKE_SPACE_WORLD
eBakeTarget
@ R_BAKE_TARGET_VERTEX_COLORS
@ R_BAKE_TARGET_IMAGE_TEXTURES
eBakeNormalSwizzle
@ R_BAKE_POSY
@ R_BAKE_POSZ
@ R_BAKE_POSX
eBakeMarginType
@ R_BAKE_EXTEND
#define R_BAKE_SPACE_TANGENT
#define R_BAKE_AUTO_NAME
#define R_BAKE_CAGE
#define R_BAKE_SPLIT_MAT
#define R_BAKE_TO_ACTIVE
eBakeSaveMode
@ R_BAKE_SAVE_EXTERNAL
@ R_BAKE_SAVE_INTERNAL
@ R_BAKE_PASS_FILTER_DIFFUSE
@ R_BAKE_PASS_FILTER_NONE
@ R_BAKE_PASS_FILTER_COLOR
@ R_BAKE_PASS_FILTER_SUBSURFACE
@ R_BAKE_PASS_FILTER_INDIRECT
@ R_BAKE_PASS_FILTER_DIRECT
@ R_BAKE_PASS_FILTER_GLOSSY
@ R_BAKE_PASS_FILTER_EMIT
@ R_BAKE_PASS_FILTER_TRANSM
eScenePassType
@ SCE_PASS_NORMAL
@ SCE_PASS_DIFFUSE_COLOR
@ SCE_PASS_POSITION
@ SCE_PASS_UV
@ SCE_PASS_SUBSURFACE_COLOR
@ SCE_PASS_GLOSSY_COLOR
@ SCE_PASS_INDEXMA
@ SCE_PASS_INDEXOB
@ SCE_PASS_COMBINED
@ SCE_PASS_Z
@ SCE_PASS_VECTOR
@ SCE_PASS_TRANSM_COLOR
@ SPACE_IMAGE
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
@ OPERATOR_RUNNING_MODAL
@ OPERATOR_PASS_THROUGH
bool ED_object_editmode_load(struct Main *bmain, struct Object *obedit)
Definition: object_edit.c:648
bool ED_operator_object_active_editable_mesh(struct bContext *C)
Definition: screen_ops.c:413
bool ED_object_get_active_image(struct Object *ob, int mat_nr, struct Image **r_ima, struct ImageUser **r_iuser, struct bNode **r_node, struct bNodeTree **r_ntree)
Definition: uvedit_ops.c:109
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
const char * IMB_colormanagement_get_rect_colorspace(struct ImBuf *ibuf)
@ COLOR_ROLE_SCENE_LINEAR
const char * IMB_colormanagement_role_colorspace_name_get(int role)
void IMB_colormanagement_transform(float *buffer, int width, int height, int channels, const char *from_colorspace, const char *to_colorspace, bool predivide)
const char * IMB_colormanagement_get_float_colorspace(struct ImBuf *ibuf)
void IMB_buffer_float_from_float_mask(float *rect_to, const float *rect_from, int channels_from, int width, int height, int stride_to, int stride_from, char *mask)
Definition: divers.c:574
struct ImBuf * IMB_allocImBuf(unsigned int x, unsigned int y, unsigned char planes, unsigned int flags)
Definition: allocimbuf.c:500
void IMB_buffer_float_from_float(float *rect_to, const float *rect_from, int channels_from, int profile_to, int profile_from, bool predivide, int width, int height, int stride_to, int stride_from)
Definition: divers.c:409
void imb_freemipmapImBuf(struct ImBuf *ibuf)
Definition: allocimbuf.c:64
void IMB_buffer_byte_from_float_mask(unsigned char *rect_to, const float *rect_from, int channels_from, float dither, bool predivide, int width, int height, int stride_to, int stride_from, char *mask)
Definition: divers.c:260
void IMB_buffer_byte_from_float(unsigned char *rect_to, const float *rect_from, int channels_from, float dither, int profile_to, int profile_from, bool predivide, int width, int height, int stride_to, int stride_from)
Definition: divers.c:94
Contains defines and structs used throughout the imbuf module.
@ IB_RECT_INVALID
@ IB_MIPMAP_INVALID
@ IB_DISPLAY_BUFFER_INVALID
#define IB_PROFILE_SRGB
#define IB_PROFILE_LINEAR_RGB
@ IB_rectfloat
@ IB_rect
Read Guarded memory(de)allocation.
#define MEM_recallocN(vmemh, len)
#define MEM_SAFE_FREE(v)
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert a color
@ PROP_ENUM_FLAG
Definition: RNA_types.h:266
#define C
Definition: RandGen.cpp:25
@ WM_JOB_EXCL_RENDER
Definition: WM_api.h:1338
@ WM_JOB_PROGRESS
Definition: WM_api.h:1339
@ WM_JOB_PRIORITY
Definition: WM_api.h:1337
@ WM_JOB_TYPE_OBJECT_BAKE
Definition: WM_api.h:1356
#define NC_GEOM
Definition: WM_types.h:343
#define ND_RENDER_RESULT
Definition: WM_types.h:394
#define ND_DATA
Definition: WM_types.h:456
#define NC_SCENE
Definition: WM_types.h:328
#define NC_IMAGE
Definition: WM_types.h:334
volatile int lock
bool RE_bake_pixels_populate_from_objects(struct Mesh *me_low, BakePixel pixel_array_from[], BakePixel pixel_array_to[], BakeHighPolyData highpoly[], const int tot_highpoly, const size_t pixels_num, const bool is_custom_cage, const float cage_extrusion, const float max_ray_distance, float mat_low[4][4], float mat_cage[4][4], struct Mesh *me_cage)
Definition: bake.c:535
int RE_pass_depth(const eScenePassType pass_type)
Definition: bake.c:1037
void RE_bake_pixels_populate(Mesh *me, BakePixel pixel_array[], const size_t pixels_num, const BakeTargets *targets, const char *uv_layer)
Definition: bake.c:706
void RE_bake_margin(ImBuf *ibuf, char *mask, const int margin, const char margin_type, Mesh const *me, char const *uv_layer, const float uv_offset[2])
Definition: bake.c:144
void RE_bake_ibuf_clear(Image *image, const bool is_tangent)
Definition: bake.c:1012
void RE_bake_normal_world_to_world(const BakePixel pixel_array[], const size_t pixels_num, const int depth, float result[], const eBakeNormalSwizzle normal_swizzle[3])
Definition: bake.c:988
void RE_bake_normal_world_to_object(const BakePixel pixel_array[], const size_t pixels_num, const int depth, float result[], struct Object *ob, const eBakeNormalSwizzle normal_swizzle[3])
Definition: bake.c:956
void RE_bake_mask_fill(const BakePixel pixel_array[], const size_t pixels_num, char *mask)
Definition: bake.c:129
void RE_bake_normal_world_to_tangent(const BakePixel pixel_array[], const size_t pixels_num, const int depth, float result[], Mesh *me, const eBakeNormalSwizzle normal_swizzle[3], float mat[4][4])
Definition: bake.c:831
#define BM_ELEM_CD_GET_VOID_P(ele, offset)
Definition: bmesh_class.h:541
#define BM_ITER_ELEM(ele, iter, data, itype)
#define BM_ITER_MESH(ele, iter, bm, itype)
@ BM_VERTS_OF_MESH
@ BM_FACES_OF_MESH
@ BM_LOOPS_OF_FACE
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert * v
OperationNode * node
Scene scene
const Depsgraph * depsgraph
depth_tx normal_tx diffuse_light_tx specular_light_tx volume_light_tx environment_tx ambient_occlusion_tx aov_value_tx in_weight_img image(1, GPU_R32F, Qualifier::WRITE, ImageType::FLOAT_2D_ARRAY, "out_weight_img") .image(3
bNodeTree * ntree
bool RE_bake_engine(Render *re, Depsgraph *depsgraph, Object *object, const int object_id, const BakePixel pixel_array[], const BakeTargets *targets, const eScenePassType pass_type, const int pass_filter, float result[])
Definition: engine.c:819
bool RE_bake_has_engine(const Render *re)
Definition: engine.c:813
void RE_bake_engine_set_engine_parameters(Render *re, Main *bmain, Scene *scene)
Definition: engine.c:806
void IMB_freeImBuf(ImBuf *UNUSED(ibuf))
ccl_global float * buffer
ccl_global const KernelWorkTile * tile
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:34
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
#define unit_float_to_uchar_clamp_v4(v1, v2)
#define G(x, y, z)
static void area(int d1, int d2, int e1, int e2, float weights[2])
static const pxr::TfToken rgba("rgba", pxr::TfToken::Immortal)
static int bake_exec(bContext *C, wmOperator *op)
static Mesh * bake_mesh_new_from_object(Depsgraph *depsgraph, Object *object, const bool preserve_origindex)
static void bake_init_api_data(wmOperator *op, bContext *C, BakeAPIRender *bkr)
static bool bake_targets_output_vertex_colors(BakeTargets *targets, Object *ob)
void OBJECT_OT_bake(wmOperatorType *ot)
static bool bake_targets_output(const BakeAPIRender *bkr, BakeTargets *targets, Object *ob, Object *ob_eval, Mesh *me_eval, BakePixel *pixel_array, ReportList *reports)
struct BakeAPIRender BakeAPIRender
static int find_original_loop(const Mesh *me_orig, const int *vert_origindex, const int *poly_origindex, const int poly_eval, const int vert_eval)
static void convert_float_color_to_byte_color(const MPropCol *float_colors, const int num, const bool is_noncolor, MLoopCol *byte_colors)
static void bake_targets_populate_pixels(const BakeAPIRender *bkr, BakeTargets *targets, Object *ob, Mesh *me_eval, BakePixel *pixel_array)
static bool bake_object_check(ViewLayer *view_layer, Object *ob, const eBakeTarget target, ReportList *reports)
static bool write_external_bake_pixels(const char *filepath, BakePixel pixel_array[], float *buffer, const int width, const int height, const int margin, const int margin_type, ImageFormatData const *im_format, const bool is_noncolor, Mesh const *mesh_eval, char const *uv_layer, const float uv_offset[2])
static bool bake_targets_init_image_textures(const BakeAPIRender *bkr, BakeTargets *targets, Object *ob, ReportList *reports)
static int bake(const BakeAPIRender *bkr, Object *ob_low, const ListBase *selected_objects, ReportList *reports)
static void bake_update_image(ScrArea *area, Image *image)
static void bake_job_canceled(void *bkv)
static bool bake_targets_init(const BakeAPIRender *bkr, BakeTargets *targets, Object *ob, Object *ob_eval, ReportList *reports)
static bool bake_targets_init_internal(const BakeAPIRender *bkr, BakeTargets *targets, Object *ob, ReportList *reports)
static void bake_job_complete(void *bkv)
static bool bake_objects_check(Main *bmain, ViewLayer *view_layer, Object *ob, ListBase *selected_objects, ReportList *reports, const bool is_selected_to_active, const eBakeTarget target)
static void bake_progress_update(void *bjv, float progress)
static void bake_startjob(void *bkv, short *UNUSED(stop), short *do_update, float *progress)
static void bake_targets_populate_pixels_color_attributes(BakeTargets *targets, Object *ob, Mesh *me_eval, BakePixel *pixel_array)
static bool bake_targets_output_internal(const BakeAPIRender *bkr, BakeTargets *targets, Object *ob, BakePixel *pixel_array, ReportList *reports, Mesh *mesh_eval)
static int bake_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
static int bake_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
static int bake_break(void *UNUSED(rjv))
static void bake_targets_refresh(BakeTargets *targets)
static bool is_noncolor_pass(eScenePassType pass_type)
static bool bake_targets_output_external(const BakeAPIRender *bkr, BakeTargets *targets, Object *ob, Object *ob_eval, Mesh *mesh_eval, BakePixel *pixel_array, ReportList *reports)
static void bake_set_props(wmOperator *op, Scene *scene)
static bool bake_pass_filter_check(eScenePassType pass_type, const int pass_filter, ReportList *reports)
static void bake_freejob(void *bkv)
static void bake_targets_clear(Main *bmain, const bool is_tangent)
static void bake_targets_free(BakeTargets *targets)
static bool write_internal_bake_pixels(Image *image, const int image_tile_number, BakePixel pixel_array[], float *buffer, const int width, const int height, const int margin, const char margin_type, const bool is_clear, const bool is_noncolor, Mesh const *mesh_eval, char const *uv_layer, const float uv_offset[2])
static void bake_result_add_to_rgba(float rgba[4], const float *result, const int channels_num)
static bool bake_targets_init_vertex_colors(Main *bmain, BakeTargets *targets, Object *ob, ReportList *reports)
static bool bake_targets_init_external(const BakeAPIRender *bkr, BakeTargets *targets, Object *ob, ReportList *reports)
void RE_progress_cb(Render *re, void *handle, void(*f)(void *handle, float))
Definition: pipeline.c:879
Render * RE_NewSceneRender(const Scene *scene)
Definition: pipeline.c:558
void RE_test_break_cb(Render *re, void *handle, int(*f)(void *handle))
Definition: pipeline.c:891
void RE_SetReports(Render *re, ReportList *reports)
Definition: pipeline.c:1753
void RNA_property_int_set(PointerRNA *ptr, PropertyRNA *prop, int value)
Definition: rna_access.c:2449
bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:5271
void RNA_property_enum_set(PointerRNA *ptr, PropertyRNA *prop, int value)
Definition: rna_access.c:3421
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:717
void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
Definition: rna_access.c:5116
int RNA_int_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4910
void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, bool value)
Definition: rna_access.c:2180
float RNA_float_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4957
bool RNA_property_enum_identifier(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **identifier)
Definition: rna_access.c:1759
void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value)
Definition: rna_access.c:2790
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4863
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:5004
void RNA_property_string_set(PointerRNA *ptr, PropertyRNA *prop, const char *value)
Definition: rna_access.c:3239
PropertyRNA * RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, float default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
Definition: rna_define.c:3836
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, bool default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3493
PropertyRNA * RNA_def_string_file_path(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, int maxlen, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3711
PropertyRNA * RNA_def_string(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, int maxlen, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3687
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
Definition: rna_define.c:1490
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, int default_value, int hardmin, int hardmax, const char *ui_name, const char *ui_description, int softmin, int softmax)
Definition: rna_define.c:3597
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3783
const EnumPropertyItem rna_enum_bake_pass_type_items[]
Definition: rna_render.c:65
const EnumPropertyItem rna_enum_normal_swizzle_items[]
Definition: rna_scene.c:430
const EnumPropertyItem rna_enum_bake_pass_filter_type_items[]
Definition: rna_scene.c:547
const EnumPropertyItem rna_enum_bake_save_mode_items[]
Definition: rna_scene.c:464
const EnumPropertyItem rna_enum_bake_margin_type_items[]
Definition: rna_scene.c:440
const EnumPropertyItem rna_enum_bake_target_items[]
Definition: rna_scene.c:450
const EnumPropertyItem rna_enum_normal_space_items[]
Definition: rna_scene.c:424
struct BMesh * bm
Definition: BKE_editmesh.h:40
CustomData vdata
Definition: bmesh_class.h:337
CustomData ldata
Definition: bmesh_class.h:337
ViewLayer * view_layer
eBakeNormalSwizzle normal_swizzle[3]
char uv_layer[MAX_CUSTOMDATA_LAYER_NAME]
eBakeTarget target
char custom_cage[MAX_NAME]
eBakeSaveMode save_mode
float max_ray_distance
eBakeMarginType margin_type
ListBase selected_objects
eScenePassType pass_type
bool is_selected_to_active
char filepath[FILE_MAX]
const char * identifier
ReportList * reports
struct Mesh * me
Definition: RE_bake.h:63
struct Object * ob
Definition: RE_bake.h:61
struct Object * ob_eval
Definition: RE_bake.h:62
float obmat[4][4]
Definition: RE_bake.h:66
bool is_flip_object
Definition: RE_bake.h:64
int height
Definition: RE_bake.h:27
int tile_number
Definition: RE_bake.h:24
size_t offset
Definition: RE_bake.h:28
struct Image * image
Definition: RE_bake.h:23
float uv_offset[2]
Definition: RE_bake.h:25
int width
Definition: RE_bake.h:26
float dv_dx
Definition: RE_bake.h:57
float du_dx
Definition: RE_bake.h:56
int seed
Definition: RE_bake.h:54
float du_dy
Definition: RE_bake.h:56
float uv[2]
Definition: RE_bake.h:55
float dv_dy
Definition: RE_bake.h:57
int object_id
Definition: RE_bake.h:53
int primitive_id
Definition: RE_bake.h:53
struct Image ** material_to_image
Definition: RE_bake.h:40
float * result
Definition: RE_bake.h:44
bool is_noncolor
Definition: RE_bake.h:49
int pixels_num
Definition: RE_bake.h:45
int materials_num
Definition: RE_bake.h:41
int channels_num
Definition: RE_bake.h:46
int images_num
Definition: RE_bake.h:37
BakeImage * images
Definition: RE_bake.h:36
short flag
Definition: DNA_ID.h:368
char name[66]
Definition: DNA_ID.h:378
struct ImBuf * mipmap[IMB_MIPMAP_LEVELS]
int channels
int userflags
float dither
unsigned int * rect
float * rect_float
void * first
Definition: DNA_listBase.h:31
unsigned char r
unsigned int poly
unsigned int tri[3]
unsigned int v
float color[4]
Definition: BKE_main.h:121
ListBase images
Definition: BKE_main.h:176
ListBase objects
Definition: BKE_main.h:170
struct BMEditMesh * edit_mesh
CustomData vdata
struct MVert * mvert
uint16_t flag
struct Material ** mat
int totvert
struct MLoop * mloop
CustomData pdata
int totpoly
int totloop
struct MPoly * mpoly
CustomData ldata
struct ModifierData * next
short base_flag
ListBase modifiers
struct Material ** mat
short visibility_flag
float obmat[4][4]
void * data
void * data
Definition: RNA_types.h:38
struct BakeData bake
struct RenderData r
struct Image * image
short type
Definition: WM_types.h:678
Definition: wm_jobs.c:57
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:919
const char * name
Definition: WM_types.h:888
int(* modal)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:935
const char * idname
Definition: WM_types.h:890
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:943
struct StructRNA * srna
Definition: WM_types.h:969
const char * description
Definition: WM_types.h:893
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:903
struct ReportList * reports
struct PointerRNA * ptr
void WM_cursor_wait(bool val)
Definition: wm_cursors.c:209
wmEventHandler_Op * WM_event_add_modal_handler(bContext *C, wmOperator *op)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
@ EVT_ESCKEY
wmOperatorType * ot
Definition: wm_files.c:3479
void WM_jobs_start(wmWindowManager *wm, wmJob *wm_job)
Definition: wm_jobs.c:437
void WM_jobs_callbacks_ex(wmJob *wm_job, wm_jobs_start_callback startjob, void(*initjob)(void *), void(*update)(void *), void(*endjob)(void *), void(*completed)(void *), void(*canceled)(void *))
Definition: wm_jobs.c:360
bool WM_jobs_test(const wmWindowManager *wm, const void *owner, int job_type)
Definition: wm_jobs.c:214
void WM_jobs_customdata_set(wmJob *wm_job, void *customdata, void(*free)(void *))
Definition: wm_jobs.c:323
void WM_jobs_timer(wmJob *wm_job, double timestep, unsigned int note, unsigned int endnote)
Definition: wm_jobs.c:339
wmJob * WM_jobs_get(wmWindowManager *wm, wmWindow *win, const void *owner, const char *name, int flag, int job_type)
Definition: wm_jobs.c:184