Blender  V2.93
object_bake_api.c
Go to the documentation of this file.
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 
24 #include "MEM_guardedalloc.h"
25 
26 #include "DNA_material_types.h"
27 #include "DNA_mesh_types.h"
28 #include "DNA_meshdata_types.h"
29 #include "DNA_object_types.h"
30 
31 #include "RNA_access.h"
32 #include "RNA_define.h"
33 #include "RNA_enum_types.h"
34 
35 #include "BLI_fileops.h"
36 #include "BLI_listbase.h"
37 #include "BLI_path_util.h"
38 
39 #include "BKE_context.h"
40 #include "BKE_global.h"
41 #include "BKE_image.h"
42 #include "BKE_layer.h"
43 #include "BKE_lib_id.h"
44 #include "BKE_main.h"
45 #include "BKE_material.h"
46 #include "BKE_mesh.h"
47 #include "BKE_mesh_mapping.h"
48 #include "BKE_modifier.h"
49 #include "BKE_node.h"
50 #include "BKE_object.h"
51 #include "BKE_report.h"
52 #include "BKE_scene.h"
53 #include "BKE_screen.h"
54 
55 #include "DEG_depsgraph.h"
56 #include "DEG_depsgraph_build.h"
57 #include "DEG_depsgraph_query.h"
58 
59 #include "RE_engine.h"
60 #include "RE_pipeline.h"
61 
62 #include "IMB_colormanagement.h"
63 #include "IMB_imbuf.h"
64 #include "IMB_imbuf_types.h"
65 
66 #include "WM_api.h"
67 #include "WM_types.h"
68 
69 #include "ED_object.h"
70 #include "ED_screen.h"
71 #include "ED_uvedit.h"
72 
73 #include "object_intern.h"
74 
75 /* prototypes */
76 static void bake_set_props(wmOperator *op, Scene *scene);
77 
78 typedef struct BakeAPIRender {
79  /* Data to work on. */
85 
86  /* Baking settings. */
88 
91  int margin;
92 
93  bool is_clear;
95  bool is_cage;
96 
101 
104 
105  /* Settings for external image saving. */
110  int width;
111  int height;
112  const char *identifier;
113 
114  /* Baking render session. */
116 
117  /* Progress Callbacks. */
118  float *progress;
119  short *do_update;
120 
121  /* Operator state. */
123  int result;
126 
127 /* callbacks */
128 
129 static void bake_progress_update(void *bjv, float progress)
130 {
131  BakeAPIRender *bj = bjv;
132 
133  if (bj->progress && *bj->progress != progress) {
134  *bj->progress = progress;
135 
136  /* make jobs timer to send notifier */
137  *(bj->do_update) = true;
138  }
139 }
140 
141 /* catch esc */
142 static int bake_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
143 {
144  /* no running blender, remove handler and pass through */
147  }
148 
149  /* running render */
150  switch (event->type) {
151  case EVT_ESCKEY: {
152  G.is_break = true;
153  return OPERATOR_RUNNING_MODAL;
154  }
155  }
156  return OPERATOR_PASS_THROUGH;
157 }
158 
163 static int bake_break(void *UNUSED(rjv))
164 {
165  if (G.is_break) {
166  return 1;
167  }
168  return 0;
169 }
170 
171 static void bake_update_image(ScrArea *area, Image *image)
172 {
173  if (area && area->spacetype == SPACE_IMAGE) { /* in case the user changed while baking */
174  SpaceImage *sima = area->spacedata.first;
175  if (sima) {
176  sima->image = image;
177  }
178  }
179 }
180 
182  BakePixel pixel_array[],
183  float *buffer,
184  const int width,
185  const int height,
186  const int margin,
187  const bool is_clear,
188  const bool is_noncolor)
189 {
190  ImBuf *ibuf;
191  void *lock;
192  bool is_float;
193  char *mask_buffer = NULL;
194  const size_t num_pixels = (size_t)width * (size_t)height;
195 
196  ibuf = BKE_image_acquire_ibuf(image, NULL, &lock);
197 
198  if (!ibuf) {
199  return false;
200  }
201 
202  if (margin > 0 || !is_clear) {
203  mask_buffer = MEM_callocN(sizeof(char) * num_pixels, "Bake Mask");
204  RE_bake_mask_fill(pixel_array, num_pixels, mask_buffer);
205  }
206 
207  is_float = (ibuf->rect_float != NULL);
208 
209  /* colormanagement conversions */
210  if (!is_noncolor) {
211  const char *from_colorspace;
212  const char *to_colorspace;
213 
215 
216  if (is_float) {
217  to_colorspace = IMB_colormanagement_get_float_colorspace(ibuf);
218  }
219  else {
220  to_colorspace = IMB_colormanagement_get_rect_colorspace(ibuf);
221  }
222 
223  if (from_colorspace != to_colorspace) {
225  buffer, ibuf->x, ibuf->y, ibuf->channels, from_colorspace, to_colorspace, false);
226  }
227  }
228 
229  /* populates the ImBuf */
230  if (is_clear) {
231  if (is_float) {
233  buffer,
234  ibuf->channels,
237  false,
238  ibuf->x,
239  ibuf->y,
240  ibuf->x,
241  ibuf->x);
242  }
243  else {
245  buffer,
246  ibuf->channels,
247  ibuf->dither,
250  false,
251  ibuf->x,
252  ibuf->y,
253  ibuf->x,
254  ibuf->x);
255  }
256  }
257  else {
258  if (is_float) {
260  buffer,
261  ibuf->channels,
262  ibuf->x,
263  ibuf->y,
264  ibuf->x,
265  ibuf->x,
266  mask_buffer);
267  }
268  else {
270  buffer,
271  ibuf->channels,
272  ibuf->dither,
273  false,
274  ibuf->x,
275  ibuf->y,
276  ibuf->x,
277  ibuf->x,
278  mask_buffer);
279  }
280  }
281 
282  /* margins */
283  if (margin > 0) {
284  RE_bake_margin(ibuf, mask_buffer, margin);
285  }
286 
288  BKE_image_mark_dirty(image, ibuf);
289 
290  if (ibuf->rect_float) {
291  ibuf->userflags |= IB_RECT_INVALID;
292  }
293 
294  /* force mipmap recalc */
295  if (ibuf->mipmap[0]) {
296  ibuf->userflags |= IB_MIPMAP_INVALID;
297  imb_freemipmapImBuf(ibuf);
298  }
299 
300  BKE_image_release_ibuf(image, ibuf, NULL);
301 
302  if (mask_buffer) {
303  MEM_freeN(mask_buffer);
304  }
305 
306  return true;
307 }
308 
309 /* force OpenGL reload */
310 static void bake_targets_refresh(BakeTargets *targets)
311 {
312  for (int i = 0; i < targets->num_images; i++) {
313  Image *ima = targets->images[i].image;
314 
315  if (ima) {
316  LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
317  if (tile->ok == IMA_OK_LOADED) {
319  DEG_id_tag_update(&ima->id, 0);
320  break;
321  }
322  }
323  }
324  }
325 }
326 
327 static bool write_external_bake_pixels(const char *filepath,
328  BakePixel pixel_array[],
329  float *buffer,
330  const int width,
331  const int height,
332  const int margin,
333  ImageFormatData *im_format,
334  const bool is_noncolor)
335 {
336  ImBuf *ibuf = NULL;
337  bool ok = false;
338  bool is_float;
339 
340  is_float = im_format->depth > 8;
341 
342  /* create a new ImBuf */
343  ibuf = IMB_allocImBuf(width, height, im_format->planes, (is_float ? IB_rectfloat : IB_rect));
344 
345  if (!ibuf) {
346  return false;
347  }
348 
349  /* populates the ImBuf */
350  if (is_float) {
352  buffer,
353  ibuf->channels,
356  false,
357  ibuf->x,
358  ibuf->y,
359  ibuf->x,
360  ibuf->x);
361  }
362  else {
363  if (!is_noncolor) {
364  const char *from_colorspace = IMB_colormanagement_role_colorspace_name_get(
366  const char *to_colorspace = IMB_colormanagement_get_rect_colorspace(ibuf);
368  buffer, ibuf->x, ibuf->y, ibuf->channels, from_colorspace, to_colorspace, false);
369  }
370 
372  buffer,
373  ibuf->channels,
374  ibuf->dither,
377  false,
378  ibuf->x,
379  ibuf->y,
380  ibuf->x,
381  ibuf->x);
382  }
383 
384  /* margins */
385  if (margin > 0) {
386  char *mask_buffer = NULL;
387  const size_t num_pixels = (size_t)width * (size_t)height;
388 
389  mask_buffer = MEM_callocN(sizeof(char) * num_pixels, "Bake Mask");
390  RE_bake_mask_fill(pixel_array, num_pixels, mask_buffer);
391  RE_bake_margin(ibuf, mask_buffer, margin);
392 
393  if (mask_buffer) {
394  MEM_freeN(mask_buffer);
395  }
396  }
397 
398  if ((ok = BKE_imbuf_write(ibuf, filepath, im_format))) {
399 #ifndef WIN32
400  chmod(filepath, S_IRUSR | S_IWUSR);
401 #endif
402  // printf("%s saving bake map: '%s'\n", __func__, filepath);
403  }
404 
405  /* garbage collection */
406  IMB_freeImBuf(ibuf);
407 
408  return ok;
409 }
410 
411 static bool is_noncolor_pass(eScenePassType pass_type)
412 {
413  return ELEM(pass_type,
414  SCE_PASS_Z,
418  SCE_PASS_UV,
421 }
422 
423 /* if all is good tag image and return true */
424 static bool bake_object_check(ViewLayer *view_layer,
425  Object *ob,
426  const eBakeTarget target,
427  ReportList *reports)
428 {
429  Base *base = BKE_view_layer_base_find(view_layer, ob);
430 
431  if (base == NULL) {
432  BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is not in view layer", ob->id.name + 2);
433  return false;
434  }
435 
436  if (!(base->flag & BASE_ENABLED_RENDER)) {
437  BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is not enabled for rendering", ob->id.name + 2);
438  return false;
439  }
440 
441  if (ob->type != OB_MESH) {
442  BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is not a mesh", ob->id.name + 2);
443  return false;
444  }
445 
446  Mesh *me = (Mesh *)ob->data;
447 
448  if (me->totpoly == 0) {
449  BKE_reportf(reports, RPT_ERROR, "No faces found in the object \"%s\"", ob->id.name + 2);
450  return false;
451  }
452 
453  if (target == R_BAKE_TARGET_VERTEX_COLORS) {
454  MPropCol *mcol = CustomData_get_layer(&me->vdata, CD_PROP_COLOR);
455  const bool mcol_valid = (mcol != NULL && U.experimental.use_sculpt_vertex_colors);
456  MLoopCol *mloopcol = CustomData_get_layer(&me->ldata, CD_MLOOPCOL);
457  if (mloopcol == NULL && !mcol_valid) {
458  BKE_reportf(reports,
459  RPT_ERROR,
460  "No vertex colors layer found in the object \"%s\"",
461  ob->id.name + 2);
462  return false;
463  }
464  }
465  else if (target == R_BAKE_TARGET_IMAGE_TEXTURES) {
467  BKE_reportf(
468  reports, RPT_ERROR, "No active UV layer found in the object \"%s\"", ob->id.name + 2);
469  return false;
470  }
471 
472  for (int i = 0; i < ob->totcol; i++) {
473  bNodeTree *ntree = NULL;
474  bNode *node = NULL;
475  const int mat_nr = i + 1;
476  Image *image;
477  ED_object_get_active_image(ob, mat_nr, &image, NULL, &node, &ntree);
478 
479  if (image) {
480  ImBuf *ibuf;
481 
482  if (node) {
484  /* we don't return false since this may be a false positive
485  * this can't be RPT_ERROR though, otherwise it prevents
486  * multiple highpoly objects to be baked at once */
487  BKE_reportf(reports,
488  RPT_INFO,
489  "Circular dependency for image \"%s\" from object \"%s\"",
490  image->id.name + 2,
491  ob->id.name + 2);
492  }
493  }
494 
495  void *lock;
496  ibuf = BKE_image_acquire_ibuf(image, NULL, &lock);
497 
498  if (ibuf) {
499  BKE_image_release_ibuf(image, ibuf, lock);
500  }
501  else {
502  BKE_reportf(reports,
503  RPT_ERROR,
504  "Uninitialized image \"%s\" from object \"%s\"",
505  image->id.name + 2,
506  ob->id.name + 2);
507 
508  BKE_image_release_ibuf(image, ibuf, lock);
509  return false;
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  if ((pass_filter & R_BAKE_PASS_FILTER_AO) != 0) {
559  BKE_report(
560  reports,
561  RPT_ERROR,
562  "Combined bake pass Ambient Occlusion contribution requires an enabled light pass "
563  "(bake the Ambient Occlusion pass type instead)");
564  }
565  else {
566  BKE_report(reports,
567  RPT_ERROR,
568  "Combined bake pass requires Emit, or a light pass with "
569  "Direct or Indirect contributions enabled");
570  }
571 
572  return false;
573  }
574  BKE_report(reports,
575  RPT_ERROR,
576  "Combined bake pass requires Emit, or a light pass with "
577  "Direct or Indirect contributions enabled");
578  return false;
583  if (((pass_filter & R_BAKE_PASS_FILTER_COLOR) != 0) ||
584  ((pass_filter & R_BAKE_PASS_FILTER_DIRECT) != 0) ||
585  ((pass_filter & R_BAKE_PASS_FILTER_INDIRECT) != 0)) {
586  return true;
587  }
588  else {
589  BKE_report(reports,
590  RPT_ERROR,
591  "Bake pass requires Direct, Indirect, or Color contributions to be enabled");
592  return false;
593  }
594  break;
595  default:
596  return true;
597  break;
598  }
599 }
600 
601 /* before even getting in the bake function we check for some basic errors */
602 static bool bake_objects_check(Main *bmain,
603  ViewLayer *view_layer,
604  Object *ob,
605  ListBase *selected_objects,
606  ReportList *reports,
607  const bool is_selected_to_active,
608  const eBakeTarget target)
609 {
610  CollectionPointerLink *link;
611 
612  /* error handling and tag (in case multiple materials share the same image) */
613  BKE_main_id_tag_idcode(bmain, ID_IM, LIB_TAG_DOIT, false);
614 
615  if (is_selected_to_active) {
616  int tot_objects = 0;
617 
618  if (!bake_object_check(view_layer, ob, target, reports)) {
619  return false;
620  }
621 
622  for (link = selected_objects->first; link; link = link->next) {
623  Object *ob_iter = (Object *)link->ptr.data;
624 
625  if (ob_iter == ob) {
626  continue;
627  }
628 
629  if (ELEM(ob_iter->type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL) == false) {
630  BKE_reportf(reports,
631  RPT_ERROR,
632  "Object \"%s\" is not a mesh or can't be converted to a mesh (Curve, Text, "
633  "Surface or Metaball)",
634  ob_iter->id.name + 2);
635  return false;
636  }
637  tot_objects += 1;
638  }
639 
640  if (tot_objects == 0) {
641  BKE_report(reports, RPT_ERROR, "No valid selected objects");
642  return false;
643  }
644  }
645  else {
646  if (BLI_listbase_is_empty(selected_objects)) {
647  BKE_report(reports, RPT_ERROR, "No valid selected objects");
648  return false;
649  }
650 
651  for (link = selected_objects->first; link; link = link->next) {
652  if (!bake_object_check(view_layer, link->ptr.data, target, reports)) {
653  return false;
654  }
655  }
656  }
657  return true;
658 }
659 
660 /* it needs to be called after bake_objects_check since the image tagging happens there */
661 static void bake_targets_clear(Main *bmain, const bool is_tangent)
662 {
663  Image *image;
664  for (image = bmain->images.first; image; image = image->id.next) {
665  if ((image->id.tag & LIB_TAG_DOIT) != 0) {
666  RE_bake_ibuf_clear(image, is_tangent);
667  }
668  }
669 }
670 
671 /* create new mesh with edit mode changes and modifiers applied */
673  Object *object,
674  const bool preserve_origindex)
675 {
676  Mesh *me = BKE_mesh_new_from_object(depsgraph, object, false, preserve_origindex);
677 
678  if (me->flag & ME_AUTOSMOOTH) {
679  BKE_mesh_split_faces(me, true);
680  }
681 
682  return me;
683 }
684 
685 /* Image Bake Targets */
686 
688  BakeTargets *targets,
689  Object *ob,
690  ReportList *reports)
691 {
692  int num_materials = ob->totcol;
693 
694  if (num_materials == 0) {
695  if (bkr->save_mode == R_BAKE_SAVE_INTERNAL) {
696  BKE_report(
697  reports, RPT_ERROR, "No active image found, add a material or bake to an external file");
698  return false;
699  }
700  if (bkr->is_split_materials) {
701  BKE_report(
702  reports,
703  RPT_ERROR,
704  "No active image found, add a material or bake without the Split Materials option");
705  return false;
706  }
707  }
708 
709  /* Overallocate in case there is more materials than images. */
710  targets->num_materials = num_materials;
711  targets->images = MEM_callocN(sizeof(BakeImage) * targets->num_materials, "BakeTargets.images");
712  targets->material_to_image = MEM_callocN(sizeof(int) * targets->num_materials,
713  "BakeTargets.material_to_image");
714 
715  /* Error handling and tag (in case multiple materials share the same image). */
717 
718  for (int i = 0; i < num_materials; i++) {
719  Image *image;
720  ED_object_get_active_image(ob, i + 1, &image, NULL, NULL, NULL);
721 
722  /* Some materials have no image, we just ignore those cases. */
723  if (image == NULL) {
724  targets->material_to_image[i] = -1;
725  }
726  else if (image->id.tag & LIB_TAG_DOIT) {
727  for (int j = 0; j < i; j++) {
728  if (targets->images[j].image == image) {
729  targets->material_to_image[i] = j;
730  break;
731  }
732  }
733  }
734  else {
735  targets->material_to_image[i] = targets->num_images;
736  targets->images[targets->num_images].image = image;
737  image->id.tag |= LIB_TAG_DOIT;
738  targets->num_images++;
739  }
740  }
741 
742  return true;
743 }
744 
746  BakeTargets *targets,
747  Object *ob,
748  ReportList *reports)
749 {
750  if (!bake_targets_init_image_textures(bkr, targets, ob, reports)) {
751  return false;
752  }
753 
754  /* Saving to image datablocks. */
755  for (int i = 0; i < targets->num_images; i++) {
756  BakeImage *bk_image = &targets->images[i];
757  void *lock;
758  ImBuf *ibuf = BKE_image_acquire_ibuf(bk_image->image, NULL, &lock);
759 
760  if (ibuf) {
761  bk_image->width = ibuf->x;
762  bk_image->height = ibuf->y;
763  bk_image->offset = targets->num_pixels;
764 
765  targets->num_pixels += (size_t)ibuf->x * (size_t)ibuf->y;
766  }
767  else {
768  BKE_image_release_ibuf(bk_image->image, ibuf, lock);
769  BKE_reportf(reports, RPT_ERROR, "Uninitialized image %s", bk_image->image->id.name + 2);
770  return false;
771  }
772  BKE_image_release_ibuf(bk_image->image, ibuf, lock);
773  }
774 
775  return true;
776 }
777 
779  BakeTargets *targets,
780  Object *ob,
781  BakePixel *pixel_array,
782  ReportList *reports)
783 {
784  bool all_ok = true;
785 
786  for (int i = 0; i < targets->num_images; i++) {
787  BakeImage *bk_image = &targets->images[i];
788  const bool ok = write_internal_bake_pixels(bk_image->image,
789  pixel_array + bk_image->offset,
790  targets->result +
791  bk_image->offset * targets->num_channels,
792  bk_image->width,
793  bk_image->height,
794  bkr->margin,
795  bkr->is_clear,
796  targets->is_noncolor);
797 
798  /* might be read by UI to set active image for display */
799  bake_update_image(bkr->area, bk_image->image);
800 
801  if (!ok) {
802  BKE_reportf(reports,
803  RPT_ERROR,
804  "Problem saving the bake map internally for object \"%s\"",
805  ob->id.name + 2);
806  all_ok = false;
807  }
808  else {
809  BKE_report(
810  reports, RPT_INFO, "Baking map saved to internal image, save it externally or pack it");
811  }
812  }
813 
814  return all_ok;
815 }
816 
818  BakeTargets *targets,
819  Object *ob,
820  ReportList *reports)
821 {
822  if (!bake_targets_init_image_textures(bkr, targets, ob, reports)) {
823  return false;
824  }
825 
826  /* Saving to disk. */
827  for (int i = 0; i < targets->num_images; i++) {
828  BakeImage *bk_image = &targets->images[i];
829 
830  bk_image->width = bkr->width;
831  bk_image->height = bkr->height;
832  bk_image->offset = targets->num_pixels;
833  bk_image->image = NULL;
834 
835  targets->num_pixels += (size_t)bkr->width * (size_t)bkr->height;
836 
837  if (!bkr->is_split_materials) {
838  break;
839  }
840  }
841 
842  if (!bkr->is_split_materials) {
843  /* saving a single image */
844  for (int i = 0; i < targets->num_materials; i++) {
845  targets->material_to_image[i] = 0;
846  }
847  }
848 
849  return true;
850 }
851 
853  BakeTargets *targets,
854  Object *ob,
855  Object *ob_eval,
856  Mesh *me,
857  BakePixel *pixel_array,
858  ReportList *reports)
859 {
860  bool all_ok = true;
861 
862  for (int i = 0; i < targets->num_images; i++) {
863  BakeImage *bk_image = &targets->images[i];
864 
865  BakeData *bake = &bkr->scene->r.bake;
866  char name[FILE_MAX];
867 
869  bkr->filepath,
871  0,
872  bake->im_format.imtype,
873  true,
874  false,
875  NULL);
876 
877  if (bkr->is_automatic_name) {
878  BLI_path_suffix(name, FILE_MAX, ob->id.name + 2, "_");
879  BLI_path_suffix(name, FILE_MAX, bkr->identifier, "_");
880  }
881 
882  if (bkr->is_split_materials) {
883  if (bk_image->image) {
884  BLI_path_suffix(name, FILE_MAX, bk_image->image->id.name + 2, "_");
885  }
886  else {
887  if (ob_eval->mat[i]) {
888  BLI_path_suffix(name, FILE_MAX, ob_eval->mat[i]->id.name + 2, "_");
889  }
890  else if (me->mat[i]) {
891  BLI_path_suffix(name, FILE_MAX, me->mat[i]->id.name + 2, "_");
892  }
893  else {
894  /* if everything else fails, use the material index */
895  char tmp[5];
896  sprintf(tmp, "%d", i % 1000);
897  BLI_path_suffix(name, FILE_MAX, tmp, "_");
898  }
899  }
900  }
901 
902  /* save it externally */
903  const bool ok = write_external_bake_pixels(name,
904  pixel_array + bk_image->offset,
905  targets->result +
906  bk_image->offset * targets->num_channels,
907  bk_image->width,
908  bk_image->height,
909  bkr->margin,
910  &bake->im_format,
911  targets->is_noncolor);
912 
913  if (!ok) {
914  BKE_reportf(reports, RPT_ERROR, "Problem saving baked map in \"%s\"", name);
915  all_ok = false;
916  }
917  else {
918  BKE_reportf(reports, RPT_INFO, "Baking map written to \"%s\"", name);
919  }
920 
921  if (!bkr->is_split_materials) {
922  break;
923  }
924  }
925 
926  return all_ok;
927 }
928 
929 /* Vertex Color Bake Targets */
930 
931 static bool bake_targets_init_vertex_colors(BakeTargets *targets, Object *ob, ReportList *reports)
932 {
933  if (ob->type != OB_MESH) {
934  BKE_report(
935  reports, RPT_ERROR, "Vertex color baking not support with object types other than mesh");
936  return false;
937  }
938 
939  Mesh *me = ob->data;
940  MPropCol *mcol = CustomData_get_layer(&me->vdata, CD_PROP_COLOR);
941  const bool mcol_valid = (mcol != NULL && U.experimental.use_sculpt_vertex_colors);
942  MLoopCol *mloopcol = CustomData_get_layer(&me->ldata, CD_MLOOPCOL);
943  if (mloopcol == NULL && !mcol_valid) {
944  BKE_report(reports, RPT_ERROR, "No vertex colors layer found to bake to");
945  return false;
946  }
947 
948  targets->images = MEM_callocN(sizeof(BakeImage), "BakeTargets.images");
949  targets->num_images = 1;
950 
951  targets->material_to_image = MEM_callocN(sizeof(int) * ob->totcol,
952  "BakeTargets.material_to_image");
953  targets->num_materials = ob->totcol;
954 
955  BakeImage *bk_image = &targets->images[0];
956  bk_image->width = me->totloop;
957  bk_image->height = 1;
958  bk_image->offset = 0;
959  bk_image->image = NULL;
960 
961  targets->num_pixels = bk_image->width * bk_image->height;
962 
963  return true;
964 }
965 
966 static int find_original_loop(const Mesh *me_orig,
967  const int *vert_origindex,
968  const int *poly_origindex,
969  const int poly_eval,
970  const int vert_eval)
971 {
972  /* Get original vertex and polygon index. There is currently no loop mapping
973  * in modifier stack evaluation. */
974  const int vert_orig = vert_origindex[vert_eval];
975  const int poly_orig = poly_origindex[poly_eval];
976 
977  if (vert_orig == ORIGINDEX_NONE || poly_orig == ORIGINDEX_NONE) {
978  return ORIGINDEX_NONE;
979  }
980 
981  /* Find matching loop with original vertex in original polygon. */
982  MPoly *mpoly_orig = me_orig->mpoly + poly_orig;
983  MLoop *mloop_orig = me_orig->mloop + mpoly_orig->loopstart;
984  for (int j = 0; j < mpoly_orig->totloop; ++j, ++mloop_orig) {
985  if (mloop_orig->v == vert_orig) {
986  return mpoly_orig->loopstart + j;
987  }
988  }
989 
990  return ORIGINDEX_NONE;
991 }
992 
994  Object *ob,
995  Mesh *me_eval,
996  BakePixel *pixel_array)
997 {
998  Mesh *me = ob->data;
999  const int num_pixels = targets->num_pixels;
1000 
1001  /* Initialize blank pixels. */
1002  for (int i = 0; i < num_pixels; i++) {
1003  BakePixel *pixel = &pixel_array[i];
1004 
1005  pixel->primitive_id = -1;
1006  pixel->object_id = 0;
1007  pixel->seed = 0;
1008  pixel->du_dx = 0.0f;
1009  pixel->du_dy = 0.0f;
1010  pixel->dv_dx = 0.0f;
1011  pixel->dv_dy = 0.0f;
1012  pixel->uv[0] = 0.0f;
1013  pixel->uv[1] = 0.0f;
1014  }
1015 
1016  /* Populate through adjacent triangles, first triangle wins. */
1017  const int tottri = poly_to_tri_count(me_eval->totpoly, me_eval->totloop);
1018  MLoopTri *looptri = MEM_mallocN(sizeof(*looptri) * tottri, __func__);
1019 
1021  me_eval->mloop, me_eval->mpoly, me_eval->mvert, me_eval->totloop, me_eval->totpoly, looptri);
1022 
1023  /* For mapping back to original mesh in case there are modifiers. */
1024  const int *vert_origindex = CustomData_get_layer(&me_eval->vdata, CD_ORIGINDEX);
1025  const int *poly_origindex = CustomData_get_layer(&me_eval->pdata, CD_ORIGINDEX);
1026 
1027  for (int i = 0; i < tottri; i++) {
1028  const MLoopTri *lt = &looptri[i];
1029 
1030  for (int j = 0; j < 3; j++) {
1031  unsigned int l = lt->tri[j];
1032  unsigned int v = me_eval->mloop[l].v;
1033 
1034  /* Map back to original loop if there are modifiers. */
1035  if (vert_origindex != NULL && poly_origindex != NULL) {
1036  l = find_original_loop(me, vert_origindex, poly_origindex, lt->poly, v);
1037  if (l == ORIGINDEX_NONE || l >= me->totloop) {
1038  continue;
1039  }
1040  }
1041 
1042  BakePixel *pixel = &pixel_array[l];
1043 
1044  if (pixel->primitive_id != -1) {
1045  continue;
1046  }
1047 
1048  pixel->primitive_id = i;
1049 
1050  /* Seed is the vertex, so that sampling noise is coherent for the same
1051  * vertex, but different corners can still have different normals,
1052  * materials and UVs. */
1053  pixel->seed = v;
1054 
1055  /* Barycentric coordinates, nudged a bit to avoid precision issues that
1056  * may happen when exactly at the vertex coordinate. */
1057  if (j == 0) {
1058  pixel->uv[0] = 1.0f - FLT_EPSILON;
1059  pixel->uv[1] = FLT_EPSILON / 2.0f;
1060  }
1061  else if (j == 1) {
1062  pixel->uv[0] = FLT_EPSILON / 2.0f;
1063  pixel->uv[1] = 1.0f - FLT_EPSILON;
1064  }
1065  else if (j == 2) {
1066  pixel->uv[0] = FLT_EPSILON / 2.0f;
1067  pixel->uv[1] = FLT_EPSILON / 2.0f;
1068  }
1069  }
1070  }
1071 
1072  MEM_freeN(looptri);
1073 }
1074 
1075 static void bake_result_add_to_rgba(float rgba[4], const float *result, const int num_channels)
1076 {
1077  if (num_channels == 4) {
1078  add_v4_v4(rgba, result);
1079  }
1080  else if (num_channels == 3) {
1081  add_v3_v3(rgba, result);
1082  rgba[3] += 1.0f;
1083  }
1084  else {
1085  rgba[0] += result[0];
1086  rgba[1] += result[0];
1087  rgba[2] += result[0];
1088  rgba[3] += 1.0f;
1089  }
1090 }
1091 
1093 {
1094  Mesh *me = ob->data;
1095  MPropCol *mcol = CustomData_get_layer(&me->vdata, CD_PROP_COLOR);
1096  const bool mcol_valid = (mcol != NULL && U.experimental.use_sculpt_vertex_colors);
1097  MLoopCol *mloopcol = CustomData_get_layer(&me->ldata, CD_MLOOPCOL);
1098  const int num_channels = targets->num_channels;
1099  const float *result = targets->result;
1100 
1101  if (mcol_valid) {
1102  const int totvert = me->totvert;
1103  const int totloop = me->totloop;
1104 
1105  /* Accumulate float vertex colors in scene linear color space. */
1106  int *num_loops_for_vertex = MEM_callocN(sizeof(int) * me->totvert, "num_loops_for_vertex");
1107  memset(mcol, 0, sizeof(MPropCol) * me->totvert);
1108 
1109  MLoop *mloop = me->mloop;
1110  for (int i = 0; i < totloop; i++, mloop++) {
1111  const int v = mloop->v;
1112  bake_result_add_to_rgba(mcol[v].color, &result[i * num_channels], num_channels);
1113  num_loops_for_vertex[v]++;
1114  }
1115 
1116  /* Normalize for number of loops. */
1117  for (int i = 0; i < totvert; i++) {
1118  if (num_loops_for_vertex[i] > 0) {
1119  mul_v4_fl(mcol[i].color, 1.0f / num_loops_for_vertex[i]);
1120  }
1121  }
1122 
1123  MEM_SAFE_FREE(num_loops_for_vertex);
1124  }
1125  else {
1126  /* Byte loop colors in sRGB colors space. */
1127  MLoop *mloop = me->mloop;
1128  const int totloop = me->totloop;
1129  const bool is_noncolor = targets->is_noncolor;
1130 
1131  for (int i = 0; i < totloop; i++, mloop++, mloopcol++) {
1132  float rgba[4];
1133  zero_v4(rgba);
1134  bake_result_add_to_rgba(rgba, &result[i * num_channels], num_channels);
1135 
1136  if (is_noncolor) {
1137  unit_float_to_uchar_clamp_v4(&mloopcol->r, rgba);
1138  }
1139  else {
1140  linearrgb_to_srgb_uchar4(&mloopcol->r, rgba);
1141  }
1142  }
1143  }
1144 
1146 
1147  return true;
1148 }
1149 
1150 /* Bake Targets */
1151 
1152 static bool bake_targets_init(const BakeAPIRender *bkr,
1153  BakeTargets *targets,
1154  Object *ob,
1155  Object *ob_eval,
1156  ReportList *reports)
1157 {
1158  if (bkr->target == R_BAKE_TARGET_IMAGE_TEXTURES) {
1159  if (bkr->save_mode == R_BAKE_SAVE_INTERNAL) {
1160  if (!bake_targets_init_internal(bkr, targets, ob_eval, reports)) {
1161  return false;
1162  }
1163  }
1164  else if (bkr->save_mode == R_BAKE_SAVE_EXTERNAL) {
1165  if (!bake_targets_init_external(bkr, targets, ob_eval, reports)) {
1166  return false;
1167  }
1168  }
1169  }
1170  else if (bkr->target == R_BAKE_TARGET_VERTEX_COLORS) {
1171  if (!bake_targets_init_vertex_colors(targets, ob, reports)) {
1172  return false;
1173  }
1174  }
1175 
1176  if (targets->num_pixels == 0) {
1177  return false;
1178  }
1179 
1180  targets->is_noncolor = is_noncolor_pass(bkr->pass_type);
1181  targets->num_channels = RE_pass_depth(bkr->pass_type);
1182  targets->result = MEM_callocN(sizeof(float) * targets->num_channels * targets->num_pixels,
1183  "bake return pixels");
1184 
1185  return true;
1186 }
1187 
1189  BakeTargets *targets,
1190  Object *ob,
1191  Mesh *me_eval,
1192  BakePixel *pixel_array)
1193 {
1194  if (bkr->target == R_BAKE_TARGET_VERTEX_COLORS) {
1195  bake_targets_populate_pixels_vertex_colors(targets, ob, me_eval, pixel_array);
1196  }
1197  else {
1198  RE_bake_pixels_populate(me_eval, pixel_array, targets->num_pixels, targets, bkr->uv_layer);
1199  }
1200 }
1201 
1202 static bool bake_targets_output(const BakeAPIRender *bkr,
1203  BakeTargets *targets,
1204  Object *ob,
1205  Object *ob_eval,
1206  Mesh *me_eval,
1207  BakePixel *pixel_array,
1208  ReportList *reports)
1209 {
1210  if (bkr->target == R_BAKE_TARGET_IMAGE_TEXTURES) {
1211  if (bkr->save_mode == R_BAKE_SAVE_INTERNAL) {
1212  return bake_targets_output_internal(bkr, targets, ob, pixel_array, reports);
1213  }
1214  if (bkr->save_mode == R_BAKE_SAVE_EXTERNAL) {
1216  bkr, targets, ob, ob_eval, me_eval, pixel_array, reports);
1217  }
1218  }
1219  else if (bkr->target == R_BAKE_TARGET_VERTEX_COLORS) {
1220  return bake_targets_output_vertex_colors(targets, ob);
1221  }
1222 
1223  return false;
1224 }
1225 
1226 static void bake_targets_free(BakeTargets *targets)
1227 {
1228  MEM_SAFE_FREE(targets->images);
1229  MEM_SAFE_FREE(targets->material_to_image);
1230  MEM_SAFE_FREE(targets->result);
1231 }
1232 
1233 /* Main Bake Logic */
1234 
1235 static int bake(const BakeAPIRender *bkr,
1236  Object *ob_low,
1237  const ListBase *selected_objects,
1238  ReportList *reports)
1239 {
1240  Render *re = bkr->render;
1241  Main *bmain = bkr->main;
1242  Scene *scene = bkr->scene;
1243  ViewLayer *view_layer = bkr->view_layer;
1244 
1245  /* We build a depsgraph for the baking,
1246  * so we don't need to change the original data to adjust visibility and modifiers. */
1247  Depsgraph *depsgraph = DEG_graph_new(bmain, scene, view_layer, DAG_EVAL_RENDER);
1249 
1250  int op_result = OPERATOR_CANCELLED;
1251  bool ok = false;
1252 
1253  Object *ob_cage = NULL;
1254  Object *ob_cage_eval = NULL;
1255  Object *ob_low_eval = NULL;
1256 
1257  BakeHighPolyData *highpoly = NULL;
1258  int tot_highpoly = 0;
1259 
1260  Mesh *me_low_eval = NULL;
1261  Mesh *me_cage_eval = NULL;
1262 
1263  MultiresModifierData *mmd_low = NULL;
1264  int mmd_flags_low = 0;
1265 
1266  BakePixel *pixel_array_low = NULL;
1267  BakePixel *pixel_array_high = NULL;
1268 
1269  BakeTargets targets = {NULL};
1270 
1271  const bool preserve_origindex = (bkr->target == R_BAKE_TARGET_VERTEX_COLORS);
1272 
1274 
1275  if (!RE_bake_has_engine(re)) {
1276  BKE_report(reports, RPT_ERROR, "Current render engine does not support baking");
1277  goto cleanup;
1278  }
1279 
1280  if (bkr->uv_layer[0] != '\0') {
1281  Mesh *me = (Mesh *)ob_low->data;
1282  if (CustomData_get_named_layer(&me->ldata, CD_MLOOPUV, bkr->uv_layer) == -1) {
1283  BKE_reportf(reports,
1284  RPT_ERROR,
1285  "No UV layer named \"%s\" found in the object \"%s\"",
1286  bkr->uv_layer,
1287  ob_low->id.name + 2);
1288  goto cleanup;
1289  }
1290  }
1291 
1292  if (bkr->is_selected_to_active) {
1293  CollectionPointerLink *link;
1294  tot_highpoly = 0;
1295 
1296  for (link = selected_objects->first; link; link = link->next) {
1297  Object *ob_iter = link->ptr.data;
1298 
1299  if (ob_iter == ob_low) {
1300  continue;
1301  }
1302 
1303  tot_highpoly++;
1304  }
1305 
1306  if (bkr->is_cage && bkr->custom_cage[0] != '\0') {
1307  ob_cage = BLI_findstring(&bmain->objects, bkr->custom_cage, offsetof(ID, name) + 2);
1308 
1309  if (ob_cage == NULL || ob_cage->type != OB_MESH) {
1310  BKE_report(reports, RPT_ERROR, "No valid cage object");
1311  goto cleanup;
1312  }
1313  else {
1314  ob_cage_eval = DEG_get_evaluated_object(depsgraph, ob_cage);
1315  ob_cage_eval->restrictflag |= OB_RESTRICT_RENDER;
1317  }
1318  }
1319  }
1320 
1321  /* for multires bake, use linear UV subdivision to match low res UVs */
1323  !bkr->is_selected_to_active) {
1325  if (mmd_low) {
1326  mmd_flags_low = mmd_low->flags;
1327  mmd_low->uv_smooth = SUBSURF_UV_SMOOTH_NONE;
1328  }
1329  }
1330 
1331  /* Make sure depsgraph is up to date. */
1333  ob_low_eval = DEG_get_evaluated_object(depsgraph, ob_low);
1334 
1335  /* get the mesh as it arrives in the renderer */
1336  me_low_eval = bake_mesh_new_from_object(depsgraph, ob_low_eval, preserve_origindex);
1337 
1338  /* Initialize bake targets. */
1339  if (!bake_targets_init(bkr, &targets, ob_low, ob_low_eval, reports)) {
1340  goto cleanup;
1341  }
1342 
1343  /* Populate the pixel array with the face data. Except if we use a cage, then
1344  * it is populated later with the cage mesh (smoothed version of the mesh). */
1345  pixel_array_low = MEM_mallocN(sizeof(BakePixel) * targets.num_pixels, "bake pixels low poly");
1346  if ((bkr->is_selected_to_active && (ob_cage == NULL) && bkr->is_cage) == false) {
1347  bake_targets_populate_pixels(bkr, &targets, ob_low, me_low_eval, pixel_array_low);
1348  }
1349 
1350  if (bkr->is_selected_to_active) {
1351  CollectionPointerLink *link;
1352  int i = 0;
1353 
1354  /* prepare cage mesh */
1355  if (ob_cage) {
1356  me_cage_eval = bake_mesh_new_from_object(depsgraph, ob_cage_eval, preserve_origindex);
1357  if ((me_low_eval->totpoly != me_cage_eval->totpoly) ||
1358  (me_low_eval->totloop != me_cage_eval->totloop)) {
1359  BKE_report(reports,
1360  RPT_ERROR,
1361  "Invalid cage object, the cage mesh must have the same number "
1362  "of faces as the active object");
1363  goto cleanup;
1364  }
1365  }
1366  else if (bkr->is_cage) {
1367  bool is_changed = false;
1368 
1369  ModifierData *md = ob_low_eval->modifiers.first;
1370  while (md) {
1371  ModifierData *md_next = md->next;
1372 
1373  /* Edge Split cannot be applied in the cage,
1374  * the cage is supposed to have interpolated normals
1375  * between the faces unless the geometry is physically
1376  * split. So we create a copy of the low poly mesh without
1377  * the eventual edge split.*/
1378 
1379  if (md->type == eModifierType_EdgeSplit) {
1380  BLI_remlink(&ob_low_eval->modifiers, md);
1381  BKE_modifier_free(md);
1382  is_changed = true;
1383  }
1384  md = md_next;
1385  }
1386 
1387  if (is_changed) {
1388  /* Make sure object is evaluated with the new modifier settings.
1389  *
1390  * NOTE: Since the dependency graph was fully evaluated prior to bake, and we only made
1391  * single modification to this object all the possible dependencies for evaluation are
1392  * already up to date. This means we can do a cheap single object update
1393  * (as an opposite of full depsgraph update). */
1394  BKE_object_eval_reset(ob_low_eval);
1396  }
1397 
1398  me_cage_eval = BKE_mesh_new_from_object(NULL, ob_low_eval, false, preserve_origindex);
1399  bake_targets_populate_pixels(bkr, &targets, ob_low, me_cage_eval, pixel_array_low);
1400  }
1401 
1402  highpoly = MEM_callocN(sizeof(BakeHighPolyData) * tot_highpoly, "bake high poly objects");
1403 
1404  /* populate highpoly array */
1405  for (link = selected_objects->first; link; link = link->next) {
1406  Object *ob_iter = link->ptr.data;
1407 
1408  if (ob_iter == ob_low) {
1409  continue;
1410  }
1411 
1412  /* initialize highpoly_data */
1413  highpoly[i].ob = ob_iter;
1414  highpoly[i].ob_eval = DEG_get_evaluated_object(depsgraph, ob_iter);
1415  highpoly[i].ob_eval->restrictflag &= ~OB_RESTRICT_RENDER;
1417  highpoly[i].me = BKE_mesh_new_from_object(NULL, highpoly[i].ob_eval, false, false);
1418 
1419  /* Low-poly to high-poly transformation matrix. */
1420  copy_m4_m4(highpoly[i].obmat, highpoly[i].ob->obmat);
1421  invert_m4_m4(highpoly[i].imat, highpoly[i].obmat);
1422 
1423  highpoly[i].is_flip_object = is_negative_m4(highpoly[i].ob->obmat);
1424 
1425  i++;
1426  }
1427 
1428  BLI_assert(i == tot_highpoly);
1429 
1430  if (ob_cage != NULL) {
1431  ob_cage_eval->restrictflag |= OB_RESTRICT_RENDER;
1433  }
1434  ob_low_eval->restrictflag |= OB_RESTRICT_RENDER;
1436 
1437  /* populate the pixel arrays with the corresponding face data for each high poly object */
1438  pixel_array_high = MEM_mallocN(sizeof(BakePixel) * targets.num_pixels,
1439  "bake pixels high poly");
1440 
1441  if (!RE_bake_pixels_populate_from_objects(me_low_eval,
1442  pixel_array_low,
1443  pixel_array_high,
1444  highpoly,
1445  tot_highpoly,
1446  targets.num_pixels,
1447  ob_cage != NULL,
1448  bkr->cage_extrusion,
1449  bkr->max_ray_distance,
1450  ob_low_eval->obmat,
1451  (ob_cage ? ob_cage->obmat : ob_low_eval->obmat),
1452  me_cage_eval)) {
1453  BKE_report(reports, RPT_ERROR, "Error handling selected objects");
1454  goto cleanup;
1455  }
1456 
1457  /* the baking itself */
1458  for (i = 0; i < tot_highpoly; i++) {
1459  ok = RE_bake_engine(re,
1460  depsgraph,
1461  highpoly[i].ob,
1462  i,
1463  pixel_array_high,
1464  &targets,
1465  bkr->pass_type,
1466  bkr->pass_filter,
1467  targets.result);
1468  if (!ok) {
1469  BKE_reportf(
1470  reports, RPT_ERROR, "Error baking from object \"%s\"", highpoly[i].ob->id.name + 2);
1471  goto cleanup;
1472  }
1473  }
1474  }
1475  else {
1476  /* If low poly is not renderable it should have failed long ago. */
1477  BLI_assert((ob_low_eval->restrictflag & OB_RESTRICT_RENDER) == 0);
1478 
1479  if (RE_bake_has_engine(re)) {
1480  ok = RE_bake_engine(re,
1481  depsgraph,
1482  ob_low_eval,
1483  0,
1484  pixel_array_low,
1485  &targets,
1486  bkr->pass_type,
1487  bkr->pass_filter,
1488  targets.result);
1489  }
1490  else {
1491  BKE_report(reports, RPT_ERROR, "Current render engine does not support baking");
1492  goto cleanup;
1493  }
1494  }
1495 
1496  /* normal space conversion
1497  * the normals are expected to be in world space, +X +Y +Z */
1498  if (ok && bkr->pass_type == SCE_PASS_NORMAL) {
1499  switch (bkr->normal_space) {
1500  case R_BAKE_SPACE_WORLD: {
1501  /* Cycles internal format */
1502  if ((bkr->normal_swizzle[0] == R_BAKE_POSX) && (bkr->normal_swizzle[1] == R_BAKE_POSY) &&
1503  (bkr->normal_swizzle[2] == R_BAKE_POSZ)) {
1504  break;
1505  }
1506  RE_bake_normal_world_to_world(pixel_array_low,
1507  targets.num_pixels,
1508  targets.num_channels,
1509  targets.result,
1510  bkr->normal_swizzle);
1511  break;
1512  }
1513  case R_BAKE_SPACE_OBJECT: {
1514  RE_bake_normal_world_to_object(pixel_array_low,
1515  targets.num_pixels,
1516  targets.num_channels,
1517  targets.result,
1518  ob_low_eval,
1519  bkr->normal_swizzle);
1520  break;
1521  }
1522  case R_BAKE_SPACE_TANGENT: {
1523  if (bkr->is_selected_to_active) {
1524  RE_bake_normal_world_to_tangent(pixel_array_low,
1525  targets.num_pixels,
1526  targets.num_channels,
1527  targets.result,
1528  me_low_eval,
1529  bkr->normal_swizzle,
1530  ob_low_eval->obmat);
1531  }
1532  else {
1533  /* from multiresolution */
1534  Mesh *me_nores = NULL;
1535  ModifierData *md = NULL;
1536  int mode;
1537 
1538  BKE_object_eval_reset(ob_low_eval);
1540 
1541  if (md) {
1542  mode = md->mode;
1543  md->mode &= ~eModifierMode_Render;
1544  }
1545 
1546  /* Evaluate modifiers again. */
1547  me_nores = BKE_mesh_new_from_object(NULL, ob_low_eval, false, false);
1548  bake_targets_populate_pixels(bkr, &targets, ob_low, me_nores, pixel_array_low);
1549 
1550  RE_bake_normal_world_to_tangent(pixel_array_low,
1551  targets.num_pixels,
1552  targets.num_channels,
1553  targets.result,
1554  me_nores,
1555  bkr->normal_swizzle,
1556  ob_low_eval->obmat);
1557  BKE_id_free(NULL, &me_nores->id);
1558 
1559  if (md) {
1560  md->mode = mode;
1561  }
1562  }
1563  break;
1564  }
1565  default:
1566  break;
1567  }
1568  }
1569 
1570  if (!ok) {
1571  BKE_reportf(reports, RPT_ERROR, "Problem baking object \"%s\"", ob_low->id.name + 2);
1572  op_result = OPERATOR_CANCELLED;
1573  }
1574  else {
1575  /* save the results */
1576  if (bake_targets_output(
1577  bkr, &targets, ob_low, ob_low_eval, me_low_eval, pixel_array_low, reports)) {
1578  op_result = OPERATOR_FINISHED;
1579  }
1580  else {
1581  op_result = OPERATOR_CANCELLED;
1582  }
1583  }
1584 
1585  bake_targets_refresh(&targets);
1586 
1587 cleanup:
1588 
1589  if (highpoly) {
1590  for (int i = 0; i < tot_highpoly; i++) {
1591  if (highpoly[i].me != NULL) {
1592  BKE_id_free(NULL, &highpoly[i].me->id);
1593  }
1594  }
1595  MEM_freeN(highpoly);
1596  }
1597 
1598  if (mmd_low) {
1599  mmd_low->flags = mmd_flags_low;
1600  }
1601 
1602  if (pixel_array_low) {
1603  MEM_freeN(pixel_array_low);
1604  }
1605 
1606  if (pixel_array_high) {
1607  MEM_freeN(pixel_array_high);
1608  }
1609 
1610  bake_targets_free(&targets);
1611 
1612  if (me_low_eval != NULL) {
1613  BKE_id_free(NULL, &me_low_eval->id);
1614  }
1615 
1616  if (me_cage_eval != NULL) {
1617  BKE_id_free(NULL, &me_cage_eval->id);
1618  }
1619 
1621 
1622  return op_result;
1623 }
1624 
1625 /* Bake Operator */
1626 
1628 {
1629  bScreen *screen = CTX_wm_screen(C);
1630 
1631  bkr->ob = CTX_data_active_object(C);
1632  bkr->main = CTX_data_main(C);
1634  bkr->scene = CTX_data_scene(C);
1635  bkr->area = screen ? BKE_screen_find_big_area(screen, SPACE_IMAGE, 10) : NULL;
1636 
1637  bkr->pass_type = RNA_enum_get(op->ptr, "type");
1638  bkr->pass_filter = RNA_enum_get(op->ptr, "pass_filter");
1639  bkr->margin = RNA_int_get(op->ptr, "margin");
1640 
1641  bkr->save_mode = (eBakeSaveMode)RNA_enum_get(op->ptr, "save_mode");
1642  bkr->target = (eBakeTarget)RNA_enum_get(op->ptr, "target");
1643 
1644  bkr->is_clear = RNA_boolean_get(op->ptr, "use_clear");
1646  bkr->save_mode == R_BAKE_SAVE_EXTERNAL) &&
1647  RNA_boolean_get(op->ptr, "use_split_materials");
1648  bkr->is_automatic_name = RNA_boolean_get(op->ptr, "use_automatic_name");
1649  bkr->is_selected_to_active = RNA_boolean_get(op->ptr, "use_selected_to_active");
1650  bkr->is_cage = RNA_boolean_get(op->ptr, "use_cage");
1651  bkr->cage_extrusion = RNA_float_get(op->ptr, "cage_extrusion");
1652  bkr->max_ray_distance = RNA_float_get(op->ptr, "max_ray_distance");
1653 
1654  bkr->normal_space = RNA_enum_get(op->ptr, "normal_space");
1655  bkr->normal_swizzle[0] = RNA_enum_get(op->ptr, "normal_r");
1656  bkr->normal_swizzle[1] = RNA_enum_get(op->ptr, "normal_g");
1657  bkr->normal_swizzle[2] = RNA_enum_get(op->ptr, "normal_b");
1658 
1659  bkr->width = RNA_int_get(op->ptr, "width");
1660  bkr->height = RNA_int_get(op->ptr, "height");
1661  bkr->identifier = "";
1662 
1663  RNA_string_get(op->ptr, "uv_layer", bkr->uv_layer);
1664 
1665  RNA_string_get(op->ptr, "cage_object", bkr->custom_cage);
1666 
1667  if (bkr->save_mode == R_BAKE_SAVE_EXTERNAL && bkr->is_automatic_name) {
1668  PropertyRNA *prop = RNA_struct_find_property(op->ptr, "type");
1669  RNA_property_enum_identifier(C, op->ptr, prop, bkr->pass_type, &bkr->identifier);
1670  }
1671 
1673 
1674  bkr->reports = op->reports;
1675 
1676  bkr->result = OPERATOR_CANCELLED;
1677 
1678  bkr->render = RE_NewSceneRender(bkr->scene);
1679 
1680  /* XXX hack to force saving to always be internal. Whether (and how) to support
1681  * external saving will be addressed later */
1682  if (bkr->save_mode == R_BAKE_SAVE_EXTERNAL) {
1684  }
1685 }
1686 
1687 static int bake_exec(bContext *C, wmOperator *op)
1688 {
1689  Render *re;
1690  int result = OPERATOR_CANCELLED;
1691  BakeAPIRender bkr = {NULL};
1693 
1694  G.is_break = false;
1695  G.is_rendering = true;
1696 
1697  bake_set_props(op, scene);
1698 
1699  bake_init_api_data(op, C, &bkr);
1700  re = bkr.render;
1701 
1702  /* setup new render */
1704 
1705  if (!bake_pass_filter_check(bkr.pass_type, bkr.pass_filter, bkr.reports)) {
1706  goto finally;
1707  }
1708 
1709  if (!bake_objects_check(bkr.main,
1710  bkr.view_layer,
1711  bkr.ob,
1712  &bkr.selected_objects,
1713  bkr.reports,
1715  bkr.target)) {
1716  goto finally;
1717  }
1718 
1719  if (bkr.is_clear) {
1720  const bool is_tangent = ((bkr.pass_type == SCE_PASS_NORMAL) &&
1722  bake_targets_clear(bkr.main, is_tangent);
1723  }
1724 
1725  RE_SetReports(re, bkr.reports);
1726 
1727  if (bkr.is_selected_to_active) {
1728  result = bake(&bkr, bkr.ob, &bkr.selected_objects, bkr.reports);
1729  }
1730  else {
1731  CollectionPointerLink *link;
1733  for (link = bkr.selected_objects.first; link; link = link->next) {
1734  Object *ob_iter = link->ptr.data;
1735  result = bake(&bkr, ob_iter, NULL, bkr.reports);
1736  }
1737  }
1738 
1739  RE_SetReports(re, NULL);
1740 
1741 finally:
1742  G.is_rendering = false;
1744  return result;
1745 }
1746 
1747 static void bake_startjob(void *bkv, short *UNUSED(stop), short *do_update, float *progress)
1748 {
1749  BakeAPIRender *bkr = (BakeAPIRender *)bkv;
1750 
1751  /* setup new render */
1752  bkr->do_update = do_update;
1753  bkr->progress = progress;
1754 
1755  RE_SetReports(bkr->render, bkr->reports);
1756 
1757  if (!bake_pass_filter_check(bkr->pass_type, bkr->pass_filter, bkr->reports)) {
1758  bkr->result = OPERATOR_CANCELLED;
1759  return;
1760  }
1761 
1762  if (!bake_objects_check(bkr->main,
1763  bkr->view_layer,
1764  bkr->ob,
1765  &bkr->selected_objects,
1766  bkr->reports,
1767  bkr->is_selected_to_active,
1768  bkr->target)) {
1769  bkr->result = OPERATOR_CANCELLED;
1770  return;
1771  }
1772 
1773  if (bkr->is_clear) {
1774  const bool is_tangent = ((bkr->pass_type == SCE_PASS_NORMAL) &&
1776  bake_targets_clear(bkr->main, is_tangent);
1777  }
1778 
1779  if (bkr->is_selected_to_active) {
1780  bkr->result = bake(bkr, bkr->ob, &bkr->selected_objects, bkr->reports);
1781  }
1782  else {
1783  CollectionPointerLink *link;
1785  for (link = bkr->selected_objects.first; link; link = link->next) {
1786  Object *ob_iter = link->ptr.data;
1787  bkr->result = bake(bkr, ob_iter, NULL, bkr->reports);
1788 
1789  if (bkr->result == OPERATOR_CANCELLED) {
1790  return;
1791  }
1792  }
1793  }
1794 
1795  RE_SetReports(bkr->render, NULL);
1796 }
1797 
1798 static void bake_freejob(void *bkv)
1799 {
1800  BakeAPIRender *bkr = (BakeAPIRender *)bkv;
1801 
1803  MEM_freeN(bkr);
1804 
1805  G.is_rendering = false;
1806 }
1807 
1809 {
1810  PropertyRNA *prop;
1811  BakeData *bake = &scene->r.bake;
1812 
1813  prop = RNA_struct_find_property(op->ptr, "filepath");
1814  if (!RNA_property_is_set(op->ptr, prop)) {
1815  RNA_property_string_set(op->ptr, prop, bake->filepath);
1816  }
1817 
1818  prop = RNA_struct_find_property(op->ptr, "width");
1819  if (!RNA_property_is_set(op->ptr, prop)) {
1820  RNA_property_int_set(op->ptr, prop, bake->width);
1821  }
1822 
1823  prop = RNA_struct_find_property(op->ptr, "height");
1824  if (!RNA_property_is_set(op->ptr, prop)) {
1825  RNA_property_int_set(op->ptr, prop, bake->width);
1826  }
1827 
1828  prop = RNA_struct_find_property(op->ptr, "margin");
1829  if (!RNA_property_is_set(op->ptr, prop)) {
1830  RNA_property_int_set(op->ptr, prop, bake->margin);
1831  }
1832 
1833  prop = RNA_struct_find_property(op->ptr, "use_selected_to_active");
1834  if (!RNA_property_is_set(op->ptr, prop)) {
1835  RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_TO_ACTIVE) != 0);
1836  }
1837 
1838  prop = RNA_struct_find_property(op->ptr, "max_ray_distance");
1839  if (!RNA_property_is_set(op->ptr, prop)) {
1840  RNA_property_float_set(op->ptr, prop, bake->max_ray_distance);
1841  }
1842 
1843  prop = RNA_struct_find_property(op->ptr, "cage_extrusion");
1844  if (!RNA_property_is_set(op->ptr, prop)) {
1845  RNA_property_float_set(op->ptr, prop, bake->cage_extrusion);
1846  }
1847 
1848  prop = RNA_struct_find_property(op->ptr, "cage_object");
1849  if (!RNA_property_is_set(op->ptr, prop)) {
1851  op->ptr, prop, (bake->cage_object) ? bake->cage_object->id.name + 2 : "");
1852  }
1853 
1854  prop = RNA_struct_find_property(op->ptr, "normal_space");
1855  if (!RNA_property_is_set(op->ptr, prop)) {
1856  RNA_property_enum_set(op->ptr, prop, bake->normal_space);
1857  }
1858 
1859  prop = RNA_struct_find_property(op->ptr, "normal_r");
1860  if (!RNA_property_is_set(op->ptr, prop)) {
1861  RNA_property_enum_set(op->ptr, prop, bake->normal_swizzle[0]);
1862  }
1863 
1864  prop = RNA_struct_find_property(op->ptr, "normal_g");
1865  if (!RNA_property_is_set(op->ptr, prop)) {
1866  RNA_property_enum_set(op->ptr, prop, bake->normal_swizzle[1]);
1867  }
1868 
1869  prop = RNA_struct_find_property(op->ptr, "normal_b");
1870  if (!RNA_property_is_set(op->ptr, prop)) {
1871  RNA_property_enum_set(op->ptr, prop, bake->normal_swizzle[2]);
1872  }
1873 
1874  prop = RNA_struct_find_property(op->ptr, "target");
1875  if (!RNA_property_is_set(op->ptr, prop)) {
1876  RNA_property_enum_set(op->ptr, prop, bake->target);
1877  }
1878 
1879  prop = RNA_struct_find_property(op->ptr, "save_mode");
1880  if (!RNA_property_is_set(op->ptr, prop)) {
1881  RNA_property_enum_set(op->ptr, prop, bake->save_mode);
1882  }
1883 
1884  prop = RNA_struct_find_property(op->ptr, "use_clear");
1885  if (!RNA_property_is_set(op->ptr, prop)) {
1886  RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_CLEAR) != 0);
1887  }
1888 
1889  prop = RNA_struct_find_property(op->ptr, "use_cage");
1890  if (!RNA_property_is_set(op->ptr, prop)) {
1891  RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_CAGE) != 0);
1892  }
1893 
1894  prop = RNA_struct_find_property(op->ptr, "use_split_materials");
1895  if (!RNA_property_is_set(op->ptr, prop)) {
1896  RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_SPLIT_MAT) != 0);
1897  }
1898 
1899  prop = RNA_struct_find_property(op->ptr, "use_automatic_name");
1900  if (!RNA_property_is_set(op->ptr, prop)) {
1901  RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_AUTO_NAME) != 0);
1902  }
1903 
1904  prop = RNA_struct_find_property(op->ptr, "pass_filter");
1905  if (!RNA_property_is_set(op->ptr, prop)) {
1906  RNA_property_enum_set(op->ptr, prop, bake->pass_filter);
1907  }
1908 }
1909 
1910 static int bake_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
1911 {
1912  wmJob *wm_job;
1913  BakeAPIRender *bkr;
1914  Render *re;
1916 
1917  bake_set_props(op, scene);
1918 
1919  /* only one render job at a time */
1921  return OPERATOR_CANCELLED;
1922  }
1923 
1924  bkr = MEM_mallocN(sizeof(BakeAPIRender), "render bake");
1925 
1926  /* init bake render */
1927  bake_init_api_data(op, C, bkr);
1928  re = bkr->render;
1929 
1930  /* setup new render */
1933 
1934  /* setup job */
1935  wm_job = WM_jobs_get(CTX_wm_manager(C),
1936  CTX_wm_window(C),
1937  scene,
1938  "Texture Bake",
1941  WM_jobs_customdata_set(wm_job, bkr, bake_freejob);
1942  /* TODO - only draw bake image, can we enforce this */
1943  WM_jobs_timer(
1944  wm_job, 0.5, (bkr->target == R_BAKE_TARGET_VERTEX_COLORS) ? NC_GEOM | ND_DATA : NC_IMAGE, 0);
1946 
1947  G.is_break = false;
1948  G.is_rendering = true;
1949 
1950  WM_jobs_start(CTX_wm_manager(C), wm_job);
1951 
1952  WM_cursor_wait(false);
1953 
1954  /* add modal handler for ESC */
1956 
1958  return OPERATOR_RUNNING_MODAL;
1959 }
1960 
1962 {
1963  PropertyRNA *prop;
1964 
1965  /* identifiers */
1966  ot->name = "Bake";
1967  ot->description = "Bake image textures of selected objects";
1968  ot->idname = "OBJECT_OT_bake";
1969 
1970  /* api callbacks */
1971  ot->exec = bake_exec;
1972  ot->modal = bake_modal;
1973  ot->invoke = bake_invoke;
1975 
1976  RNA_def_enum(
1977  ot->srna,
1978  "type",
1981  "Type",
1982  "Type of pass to bake, some of them may not be supported by the current render engine");
1983  prop = RNA_def_enum(ot->srna,
1984  "pass_filter",
1987  "Pass Filter",
1988  "Filter to combined, diffuse, glossy, transmission and subsurface passes");
1991  "filepath",
1992  NULL,
1993  FILE_MAX,
1994  "File Path",
1995  "Image filepath to use when saving externally");
1996  RNA_def_int(ot->srna,
1997  "width",
1998  512,
1999  1,
2000  INT_MAX,
2001  "Width",
2002  "Horizontal dimension of the baking map (external only)",
2003  64,
2004  4096);
2005  RNA_def_int(ot->srna,
2006  "height",
2007  512,
2008  1,
2009  INT_MAX,
2010  "Height",
2011  "Vertical dimension of the baking map (external only)",
2012  64,
2013  4096);
2014  RNA_def_int(ot->srna,
2015  "margin",
2016  16,
2017  0,
2018  INT_MAX,
2019  "Margin",
2020  "Extends the baked result as a post process filter",
2021  0,
2022  64);
2024  "use_selected_to_active",
2025  false,
2026  "Selected to Active",
2027  "Bake shading on the surface of selected objects to the active object");
2029  "max_ray_distance",
2030  0.0f,
2031  0.0f,
2032  FLT_MAX,
2033  "Max Ray Distance",
2034  "The maximum ray distance for matching points between the active and selected "
2035  "objects. If zero, there is no limit",
2036  0.0f,
2037  1.0f);
2039  "cage_extrusion",
2040  0.0f,
2041  0.0f,
2042  FLT_MAX,
2043  "Cage Extrusion",
2044  "Inflate the active object by the specified distance for baking. This helps "
2045  "matching to points nearer to the outside of the selected object meshes",
2046  0.0f,
2047  1.0f);
2049  "cage_object",
2050  NULL,
2051  MAX_NAME,
2052  "Cage Object",
2053  "Object to use as cage, instead of calculating the cage from the active object "
2054  "with cage extrusion");
2055  RNA_def_enum(ot->srna,
2056  "normal_space",
2059  "Normal Space",
2060  "Choose normal space for baking");
2061  RNA_def_enum(ot->srna,
2062  "normal_r",
2064  R_BAKE_POSX,
2065  "R",
2066  "Axis to bake in red channel");
2067  RNA_def_enum(ot->srna,
2068  "normal_g",
2070  R_BAKE_POSY,
2071  "G",
2072  "Axis to bake in green channel");
2073  RNA_def_enum(ot->srna,
2074  "normal_b",
2076  R_BAKE_POSZ,
2077  "B",
2078  "Axis to bake in blue channel");
2079  RNA_def_enum(ot->srna,
2080  "target",
2083  "Target",
2084  "Where to output the baked map");
2085  RNA_def_enum(ot->srna,
2086  "save_mode",
2089  "Save Mode",
2090  "Where to save baked image textures");
2092  "use_clear",
2093  false,
2094  "Clear",
2095  "Clear images before baking (only for internal saving)");
2096  RNA_def_boolean(ot->srna, "use_cage", false, "Cage", "Cast rays to active object from a cage");
2098  ot->srna,
2099  "use_split_materials",
2100  false,
2101  "Split Materials",
2102  "Split baked maps per material, using material name in output file (external only)");
2104  "use_automatic_name",
2105  false,
2106  "Automatic Name",
2107  "Automatically name the output file with the pass type");
2109  "uv_layer",
2110  NULL,
2112  "UV Layer",
2113  "UV layer to override active");
2114 }
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1034
int CTX_data_selected_objects(const bContext *C, ListBase *list)
Definition: context.c:1249
struct wmWindowManager * CTX_wm_manager(const bContext *C)
Definition: context.c:689
struct ViewLayer * CTX_data_view_layer(const bContext *C)
Definition: context.c:1044
struct Object * CTX_data_active_object(const bContext *C)
Definition: context.c:1279
struct bScreen * CTX_wm_screen(const bContext *C)
Definition: context.c:709
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1018
struct wmWindow * CTX_wm_window(const bContext *C)
Definition: context.c:699
int CustomData_get_active_layer_index(const struct CustomData *data, int type)
#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)
Definition: customdata.c:2365
void BKE_image_release_ibuf(struct Image *ima, struct ImBuf *ibuf, void *lock)
Definition: image.c:5113
#define IMA_OK_LOADED
Definition: BKE_image.h:158
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)
Definition: image.c:5100
void BKE_image_free_gputextures(struct Image *ima)
Definition: image_gpu.c:517
void BKE_image_path_from_imtype(char *string, const char *base, const char *relbase, int frame, const char imtype, const bool use_ext, const bool use_frames, const char *suffix)
Definition: image.c:3091
void BKE_image_mark_dirty(struct Image *image, struct ImBuf *ibuf)
struct Base * BKE_view_layer_base_find(struct ViewLayer *view_layer, struct Object *ob)
Definition: layer.c:394
void BKE_id_free(struct Main *bmain, void *idv)
void BKE_main_id_tag_idcode(struct Main *mainvar, const short type, const int tag, const bool value)
Definition: lib_id.c:910
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:697
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, const bool preserve_all_data_layers, const bool preserve_origindex)
void BKE_mesh_split_faces(struct Mesh *mesh, bool free_loop_normals)
Definition: mesh.c:2073
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.c:399
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:78
void BKE_report(ReportList *reports, ReportType type, const char *message)
Definition: report.c:104
void BKE_reportf(ReportList *reports, ReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
void BKE_scene_graph_update_tagged(struct Depsgraph *depsgraph, struct Main *bmain)
Definition: scene.c:2713
struct ScrArea struct ScrArea * BKE_screen_find_big_area(struct bScreen *screen, const int spacetype, const short min)
Definition: screen.c:983
#define BLI_assert(a)
Definition: BLI_assert.h:58
File and directory operations.
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:124
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:547
void void BLI_INLINE bool BLI_listbase_is_single(const struct ListBase *lb)
Definition: BLI_listbase.h:120
void * BLI_findstring(const struct ListBase *listbase, const char *id, const int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:133
MINLINE void linearrgb_to_srgb_uchar4(unsigned char srgb[4], const float linear[4])
MINLINE int poly_to_tri_count(const int poly_count, const int corner_count)
bool invert_m4_m4(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1278
void copy_m4_m4(float m1[4][4], const float m2[4][4])
Definition: math_matrix.c:95
bool is_negative_m4(const float mat[4][4])
Definition: math_matrix.c:2590
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:669
unsigned char uchar
Definition: BLI_sys_types.h:86
#define UNUSED(x)
#define ELEM(...)
Depsgraph * DEG_graph_new(struct Main *bmain, struct Scene *scene, struct ViewLayer *view_layer, eEvaluationMode mode)
Definition: depsgraph.cc:281
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
@ DAG_EVAL_RENDER
Definition: DEG_depsgraph.h:62
void DEG_graph_free(Depsgraph *graph)
Definition: depsgraph.cc:314
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:611
@ LIB_TAG_DOIT
Definition: DNA_ID.h:554
@ ID_IM
Definition: DNA_ID_enums.h:65
#define MAX_CUSTOMDATA_LAYER_NAME
@ CD_ORIGINDEX
@ CD_PROP_COLOR
@ CD_MLOOPCOL
@ CD_MLOOPUV
#define MAX_NAME
Definition: DNA_defs.h:62
@ 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_MBALL
@ OB_SURF
@ OB_FONT
@ OB_MESH
@ OB_CURVE
@ OB_RESTRICT_RENDER
#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
#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_AO
@ 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_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
@ SCE_PASS_RAYHITS
@ SPACE_IMAGE
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
@ OPERATOR_RUNNING_MODAL
@ OPERATOR_PASS_THROUGH
bool ED_operator_object_active_editable_mesh(struct bContext *C)
Definition: screen_ops.c:384
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:125
_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
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
const char * IMB_colormanagement_get_rect_colorspace(struct ImBuf *ibuf)
const char * IMB_colormanagement_role_colorspace_name_get(int role)
@ COLOR_ROLE_SCENE_LINEAR
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:597
struct ImBuf * IMB_allocImBuf(unsigned int x, unsigned int y, unsigned char planes, unsigned int flags)
Definition: allocimbuf.c:478
void IMB_freeImBuf(struct ImBuf *ibuf)
Definition: allocimbuf.c:211
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:430
void imb_freemipmapImBuf(struct ImBuf *ibuf)
Definition: allocimbuf.c:80
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:279
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:112
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_SAFE_FREE(v)
@ PROP_ENUM_FLAG
Definition: RNA_types.h:251
#define C
Definition: RandGen.cpp:39
@ WM_JOB_TYPE_OBJECT_BAKE
Definition: WM_api.h:741
@ WM_JOB_EXCL_RENDER
Definition: WM_api.h:725
@ WM_JOB_PROGRESS
Definition: WM_api.h:726
@ WM_JOB_PRIORITY
Definition: WM_api.h:724
#define NC_GEOM
Definition: WM_types.h:294
#define ND_RENDER_RESULT
Definition: WM_types.h:346
#define ND_DATA
Definition: WM_types.h:408
#define NC_SCENE
Definition: WM_types.h:279
#define NC_IMAGE
Definition: WM_types.h:285
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 num_pixels, 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:523
void RE_bake_normal_world_to_world(const BakePixel pixel_array[], const size_t num_pixels, const int depth, float result[], const eBakeNormalSwizzle normal_swizzle[3])
Definition: bake.c:984
void RE_bake_normal_world_to_object(const BakePixel pixel_array[], const size_t num_pixels, const int depth, float result[], struct Object *ob, const eBakeNormalSwizzle normal_swizzle[3])
Definition: bake.c:952
int RE_pass_depth(const eScenePassType pass_type)
Definition: bake.c:1033
void RE_bake_normal_world_to_tangent(const BakePixel pixel_array[], const size_t num_pixels, const int depth, float result[], Mesh *me, const eBakeNormalSwizzle normal_swizzle[3], float mat[4][4])
Definition: bake.c:827
void RE_bake_mask_fill(const BakePixel pixel_array[], const size_t num_pixels, char *mask)
Definition: bake.c:141
void RE_bake_ibuf_clear(Image *image, const bool is_tangent)
Definition: bake.c:1008
void RE_bake_margin(ImBuf *ibuf, char *mask, const int margin)
Definition: bake.c:156
void RE_bake_pixels_populate(Mesh *me, BakePixel pixel_array[], const size_t num_pixels, const BakeTargets *targets, const char *uv_layer)
Definition: bake.c:694
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert * v
unsigned int U
Definition: btGjkEpa3.h:78
ListBase tiles
OperationNode * node
Scene scene
const Depsgraph * depsgraph
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:744
void RE_bake_engine_set_engine_parameters(Render *re, Main *bmain, Scene *scene)
Definition: engine.c:731
bool RE_bake_has_engine(Render *re)
Definition: engine.c:738
__kernel void ccl_constant KernelData ccl_global void ccl_global char ccl_global int ccl_global char ccl_global unsigned int ccl_global float * buffer
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
#define unit_float_to_uchar_clamp_v4(v1, v2)
static void area(int d1, int d2, int e1, int e2, float weights[2])
static int bake_exec(bContext *C, wmOperator *op)
static Mesh * bake_mesh_new_from_object(Depsgraph *depsgraph, Object *object, const bool preserve_origindex)
static bool bake_targets_init_vertex_colors(BakeTargets *targets, Object *ob, ReportList *reports)
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 bool write_internal_bake_pixels(Image *image, BakePixel pixel_array[], float *buffer, const int width, const int height, const int margin, const bool is_clear, const bool is_noncolor)
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 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 bool bake_targets_output_external(const BakeAPIRender *bkr, BakeTargets *targets, Object *ob, Object *ob_eval, Mesh *me, BakePixel *pixel_array, ReportList *reports)
static void bake_update_image(ScrArea *area, Image *image)
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 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 int bake_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
static bool write_external_bake_pixels(const char *filepath, BakePixel pixel_array[], float *buffer, const int width, const int height, const int margin, ImageFormatData *im_format, const bool is_noncolor)
static int bake_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
static int bake_break(void *UNUSED(rjv))
static bool bake_targets_output_internal(const BakeAPIRender *bkr, BakeTargets *targets, Object *ob, BakePixel *pixel_array, ReportList *reports)
static void bake_targets_refresh(BakeTargets *targets)
static void bake_targets_populate_pixels_vertex_colors(BakeTargets *targets, Object *ob, Mesh *me_eval, BakePixel *pixel_array)
static bool is_noncolor_pass(eScenePassType pass_type)
static void bake_result_add_to_rgba(float rgba[4], const float *result, const int num_channels)
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 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:947
Render * RE_NewSceneRender(const Scene *scene)
Definition: pipeline.c:598
void RE_test_break_cb(Render *re, void *handle, int(*f)(void *handle))
Definition: pipeline.c:959
void RE_SetReports(Render *re, ReportList *reports)
Definition: pipeline.c:1831
void RNA_property_int_set(PointerRNA *ptr, PropertyRNA *prop, int value)
Definition: rna_access.c:2627
bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:6655
void RNA_property_enum_set(PointerRNA *ptr, PropertyRNA *prop, int value)
Definition: rna_access.c:3562
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:866
void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
Definition: rna_access.c:6514
int RNA_int_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6308
void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, bool value)
Definition: rna_access.c:2358
float RNA_float_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6355
bool RNA_property_enum_identifier(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **identifier)
Definition: rna_access.c:1925
void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value)
Definition: rna_access.c:2964
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6261
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6402
void RNA_property_string_set(PointerRNA *ptr, PropertyRNA *prop, const char *value)
Definition: rna_access.c:3401
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:3825
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, bool default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3481
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:3699
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:3675
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
Definition: rna_define.c:1512
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:3585
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:3771
const EnumPropertyItem rna_enum_bake_pass_type_items[]
Definition: rna_render.c:81
const EnumPropertyItem rna_enum_normal_swizzle_items[]
Definition: rna_scene.c:426
const EnumPropertyItem rna_enum_bake_pass_filter_type_items[]
Definition: rna_scene.c:533
const EnumPropertyItem rna_enum_bake_save_mode_items[]
Definition: rna_scene.c:450
const EnumPropertyItem rna_enum_bake_target_items[]
Definition: rna_scene.c:436
const EnumPropertyItem rna_enum_normal_space_items[]
Definition: rna_scene.c:420
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
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:71
struct Object * ob
Definition: RE_bake.h:69
struct Object * ob_eval
Definition: RE_bake.h:70
float obmat[4][4]
Definition: RE_bake.h:74
bool is_flip_object
Definition: RE_bake.h:72
int height
Definition: RE_bake.h:38
size_t offset
Definition: RE_bake.h:39
struct Image * image
Definition: RE_bake.h:36
int width
Definition: RE_bake.h:37
float dv_dx
Definition: RE_bake.h:65
float du_dx
Definition: RE_bake.h:64
int seed
Definition: RE_bake.h:62
float du_dy
Definition: RE_bake.h:64
float uv[2]
Definition: RE_bake.h:63
float dv_dy
Definition: RE_bake.h:65
int object_id
Definition: RE_bake.h:61
int primitive_id
Definition: RE_bake.h:61
int * material_to_image
Definition: RE_bake.h:48
float * result
Definition: RE_bake.h:52
bool is_noncolor
Definition: RE_bake.h:57
int num_images
Definition: RE_bake.h:45
int num_materials
Definition: RE_bake.h:49
int num_channels
Definition: RE_bake.h:54
int num_pixels
Definition: RE_bake.h:53
BakeImage * images
Definition: RE_bake.h:44
short flag
Definition: DNA_ID.h:273
int tag
Definition: DNA_ID.h:292
void * next
Definition: DNA_ID.h:274
char name[66]
Definition: DNA_ID.h:283
struct ImBuf * mipmap[IMB_MIPMAP_LEVELS]
int channels
int userflags
float dither
unsigned int * rect
float * rect_float
void * first
Definition: DNA_listBase.h:47
unsigned char r
unsigned int poly
unsigned int tri[3]
unsigned int v
Definition: BKE_main.h:116
ListBase images
Definition: BKE_main.h:154
ListBase objects
Definition: BKE_main.h:148
struct CustomData pdata ldata
struct MVert * mvert
struct Material ** mat
int totvert
short flag
struct MLoop * mloop
int totpoly
int totloop
struct MPoly * mpoly
struct ModifierData * next
short base_flag
ListBase modifiers
struct Material ** mat
float obmat[4][4]
void * data
char restrictflag
void * data
Definition: RNA_types.h:52
struct BakeData bake
struct RenderData r
struct Image * image
short type
Definition: WM_types.h:577
Definition: wm_jobs.c:73
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:752
const char * name
Definition: WM_types.h:721
int(* modal)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:768
const char * idname
Definition: WM_types.h:723
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:776
struct StructRNA * srna
Definition: WM_types.h:802
const char * description
Definition: WM_types.h:726
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:736
struct ReportList * reports
struct PointerRNA * ptr
#define G(x, y, z)
void WM_cursor_wait(bool val)
Definition: wm_cursors.c:226
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:3156
void WM_jobs_start(wmWindowManager *wm, wmJob *wm_job)
Definition: wm_jobs.c:450
wmJob * WM_jobs_get(wmWindowManager *wm, wmWindow *win, void *owner, const char *name, int flag, int job_type)
Definition: wm_jobs.c:196
bool WM_jobs_test(wmWindowManager *wm, void *owner, int job_type)
Definition: wm_jobs.c:223
void WM_jobs_callbacks(wmJob *wm_job, wm_jobs_start_callback startjob, void(*initjob)(void *), void(*update)(void *), void(*endjob)(void *))
Definition: wm_jobs.c:372
void WM_jobs_customdata_set(wmJob *wm_job, void *customdata, void(*free)(void *))
Definition: wm_jobs.c:344
void WM_jobs_timer(wmJob *wm_job, double timestep, unsigned int note, unsigned int endnote)
Definition: wm_jobs.c:360