Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2019-04-17 07:17:24 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-04-17 07:21:24 +0300
commite12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 (patch)
tree8cf3453d12edb177a218ef8009357518ec6cab6a /source/blender/editors/object/object_bake_api.c
parentb3dabc200a4b0399ec6b81f2ff2730d07b44fcaa (diff)
ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat
Diffstat (limited to 'source/blender/editors/object/object_bake_api.c')
-rw-r--r--source/blender/editors/object/object_bake_api.c2807
1 files changed, 1561 insertions, 1246 deletions
diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c
index e3e3f3d10ef..fba5a4e281e 100644
--- a/source/blender/editors/object/object_bake_api.c
+++ b/source/blender/editors/object/object_bake_api.c
@@ -21,7 +21,6 @@
* \ingroup edobj
*/
-
#include "MEM_guardedalloc.h"
#include "DNA_object_types.h"
@@ -77,517 +76,584 @@
static void bake_set_props(wmOperator *op, Scene *scene);
typedef struct BakeAPIRender {
- Object *ob;
- Main *main;
- Scene *scene;
- ViewLayer *view_layer;
- ReportList *reports;
- ListBase selected_objects;
-
- eScenePassType pass_type;
- int pass_filter;
- int margin;
-
- int save_mode;
-
- bool is_clear;
- bool is_split_materials;
- bool is_automatic_name;
- bool is_selected_to_active;
- bool is_cage;
-
- float cage_extrusion;
- int normal_space;
- eBakeNormalSwizzle normal_swizzle[3];
-
- char uv_layer[MAX_CUSTOMDATA_LAYER_NAME];
- char custom_cage[MAX_NAME];
- char filepath[FILE_MAX];
-
- int width;
- int height;
- const char *identifier;
-
- int result;
- bool ready;
-
- /* callbacks */
- Render *render;
- float *progress;
- short *do_update;
-
- /* for redrawing */
- ScrArea *sa;
+ Object *ob;
+ Main *main;
+ Scene *scene;
+ ViewLayer *view_layer;
+ ReportList *reports;
+ ListBase selected_objects;
+
+ eScenePassType pass_type;
+ int pass_filter;
+ int margin;
+
+ int save_mode;
+
+ bool is_clear;
+ bool is_split_materials;
+ bool is_automatic_name;
+ bool is_selected_to_active;
+ bool is_cage;
+
+ float cage_extrusion;
+ int normal_space;
+ eBakeNormalSwizzle normal_swizzle[3];
+
+ char uv_layer[MAX_CUSTOMDATA_LAYER_NAME];
+ char custom_cage[MAX_NAME];
+ char filepath[FILE_MAX];
+
+ int width;
+ int height;
+ const char *identifier;
+
+ int result;
+ bool ready;
+
+ /* callbacks */
+ Render *render;
+ float *progress;
+ short *do_update;
+
+ /* for redrawing */
+ ScrArea *sa;
} BakeAPIRender;
/* callbacks */
static void bake_progress_update(void *bjv, float progress)
{
- BakeAPIRender *bj = bjv;
+ BakeAPIRender *bj = bjv;
- if (bj->progress && *bj->progress != progress) {
- *bj->progress = progress;
+ if (bj->progress && *bj->progress != progress) {
+ *bj->progress = progress;
- /* make jobs timer to send notifier */
- *(bj->do_update) = true;
- }
+ /* make jobs timer to send notifier */
+ *(bj->do_update) = true;
+ }
}
/* catch esc */
static int bake_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
- /* no running blender, remove handler and pass through */
- if (0 == WM_jobs_test(CTX_wm_manager(C), CTX_data_scene(C), WM_JOB_TYPE_OBJECT_BAKE))
- return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
-
- /* running render */
- switch (event->type) {
- case ESCKEY:
- {
- G.is_break = true;
- return OPERATOR_RUNNING_MODAL;
- }
- }
- return OPERATOR_PASS_THROUGH;
+ /* no running blender, remove handler and pass through */
+ if (0 == WM_jobs_test(CTX_wm_manager(C), CTX_data_scene(C), WM_JOB_TYPE_OBJECT_BAKE))
+ return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
+
+ /* running render */
+ switch (event->type) {
+ case ESCKEY: {
+ G.is_break = true;
+ return OPERATOR_RUNNING_MODAL;
+ }
+ }
+ return OPERATOR_PASS_THROUGH;
}
/* for exec() when there is no render job
* note: this wont check for the escape key being pressed, but doing so isnt threadsafe */
static int bake_break(void *UNUSED(rjv))
{
- if (G.is_break)
- return 1;
- return 0;
+ if (G.is_break)
+ return 1;
+ return 0;
}
-
static void bake_update_image(ScrArea *sa, Image *image)
{
- if (sa && sa->spacetype == SPACE_IMAGE) { /* in case the user changed while baking */
- SpaceImage *sima = sa->spacedata.first;
- if (sima)
- sima->image = image;
- }
+ if (sa && sa->spacetype == SPACE_IMAGE) { /* in case the user changed while baking */
+ SpaceImage *sima = sa->spacedata.first;
+ if (sima)
+ sima->image = image;
+ }
}
-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 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)
{
- ImBuf *ibuf;
- void *lock;
- bool is_float;
- char *mask_buffer = NULL;
- const size_t num_pixels = (size_t)width * (size_t)height;
-
- ibuf = BKE_image_acquire_ibuf(image, NULL, &lock);
-
- if (!ibuf)
- return false;
-
- if (margin > 0 || !is_clear) {
- mask_buffer = MEM_callocN(sizeof(char) * num_pixels, "Bake Mask");
- RE_bake_mask_fill(pixel_array, num_pixels, mask_buffer);
- }
-
- is_float = (ibuf->rect_float != NULL);
-
- /* colormanagement conversions */
- if (!is_noncolor) {
- const char *from_colorspace;
- const char *to_colorspace;
-
- from_colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_SCENE_LINEAR);
-
- if (is_float)
- to_colorspace = IMB_colormanagement_get_float_colorspace(ibuf);
- else
- to_colorspace = IMB_colormanagement_get_rect_colorspace(ibuf);
-
- if (from_colorspace != to_colorspace)
- IMB_colormanagement_transform(buffer, ibuf->x, ibuf->y, ibuf->channels, from_colorspace, to_colorspace, false);
- }
-
- /* populates the ImBuf */
- if (is_clear) {
- if (is_float) {
- IMB_buffer_float_from_float(
- ibuf->rect_float, buffer, ibuf->channels,
- IB_PROFILE_LINEAR_RGB, IB_PROFILE_LINEAR_RGB, false,
- ibuf->x, ibuf->y, ibuf->x, ibuf->x);
- }
- else {
- IMB_buffer_byte_from_float(
- (unsigned char *) ibuf->rect, buffer, ibuf->channels, ibuf->dither,
- IB_PROFILE_SRGB, IB_PROFILE_SRGB,
- false, ibuf->x, ibuf->y, ibuf->x, ibuf->x);
- }
- }
- else {
- if (is_float) {
- IMB_buffer_float_from_float_mask(
- ibuf->rect_float, buffer, ibuf->channels,
- ibuf->x, ibuf->y, ibuf->x, ibuf->x, mask_buffer);
- }
- else {
- IMB_buffer_byte_from_float_mask(
- (unsigned char *) ibuf->rect, buffer, ibuf->channels, ibuf->dither,
- false, ibuf->x, ibuf->y, ibuf->x, ibuf->x, mask_buffer);
- }
- }
-
- /* margins */
- if (margin > 0)
- RE_bake_margin(ibuf, mask_buffer, margin);
-
- ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID | IB_BITMAPDIRTY;
-
- if (ibuf->rect_float)
- ibuf->userflags |= IB_RECT_INVALID;
-
- /* force mipmap recalc */
- if (ibuf->mipmap[0]) {
- ibuf->userflags |= IB_MIPMAP_INVALID;
- imb_freemipmapImBuf(ibuf);
- }
-
- BKE_image_release_ibuf(image, ibuf, NULL);
-
- if (mask_buffer)
- MEM_freeN(mask_buffer);
-
- return true;
+ ImBuf *ibuf;
+ void *lock;
+ bool is_float;
+ char *mask_buffer = NULL;
+ const size_t num_pixels = (size_t)width * (size_t)height;
+
+ ibuf = BKE_image_acquire_ibuf(image, NULL, &lock);
+
+ if (!ibuf)
+ return false;
+
+ if (margin > 0 || !is_clear) {
+ mask_buffer = MEM_callocN(sizeof(char) * num_pixels, "Bake Mask");
+ RE_bake_mask_fill(pixel_array, num_pixels, mask_buffer);
+ }
+
+ is_float = (ibuf->rect_float != NULL);
+
+ /* colormanagement conversions */
+ if (!is_noncolor) {
+ const char *from_colorspace;
+ const char *to_colorspace;
+
+ from_colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_SCENE_LINEAR);
+
+ if (is_float)
+ to_colorspace = IMB_colormanagement_get_float_colorspace(ibuf);
+ else
+ to_colorspace = IMB_colormanagement_get_rect_colorspace(ibuf);
+
+ if (from_colorspace != to_colorspace)
+ IMB_colormanagement_transform(
+ buffer, ibuf->x, ibuf->y, ibuf->channels, from_colorspace, to_colorspace, false);
+ }
+
+ /* populates the ImBuf */
+ if (is_clear) {
+ if (is_float) {
+ IMB_buffer_float_from_float(ibuf->rect_float,
+ buffer,
+ ibuf->channels,
+ IB_PROFILE_LINEAR_RGB,
+ IB_PROFILE_LINEAR_RGB,
+ false,
+ ibuf->x,
+ ibuf->y,
+ ibuf->x,
+ ibuf->x);
+ }
+ else {
+ IMB_buffer_byte_from_float((unsigned char *)ibuf->rect,
+ buffer,
+ ibuf->channels,
+ ibuf->dither,
+ IB_PROFILE_SRGB,
+ IB_PROFILE_SRGB,
+ false,
+ ibuf->x,
+ ibuf->y,
+ ibuf->x,
+ ibuf->x);
+ }
+ }
+ else {
+ if (is_float) {
+ IMB_buffer_float_from_float_mask(ibuf->rect_float,
+ buffer,
+ ibuf->channels,
+ ibuf->x,
+ ibuf->y,
+ ibuf->x,
+ ibuf->x,
+ mask_buffer);
+ }
+ else {
+ IMB_buffer_byte_from_float_mask((unsigned char *)ibuf->rect,
+ buffer,
+ ibuf->channels,
+ ibuf->dither,
+ false,
+ ibuf->x,
+ ibuf->y,
+ ibuf->x,
+ ibuf->x,
+ mask_buffer);
+ }
+ }
+
+ /* margins */
+ if (margin > 0)
+ RE_bake_margin(ibuf, mask_buffer, margin);
+
+ ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID | IB_BITMAPDIRTY;
+
+ if (ibuf->rect_float)
+ ibuf->userflags |= IB_RECT_INVALID;
+
+ /* force mipmap recalc */
+ if (ibuf->mipmap[0]) {
+ ibuf->userflags |= IB_MIPMAP_INVALID;
+ imb_freemipmapImBuf(ibuf);
+ }
+
+ BKE_image_release_ibuf(image, ibuf, NULL);
+
+ if (mask_buffer)
+ MEM_freeN(mask_buffer);
+
+ return true;
}
/* force OpenGL reload */
static void refresh_images(BakeImages *bake_images)
{
- int i;
- for (i = 0; i < bake_images->size; i++) {
- Image *ima = bake_images->data[i].image;
- if (ima->ok == IMA_OK_LOADED) {
- GPU_free_image(ima);
- DEG_id_tag_update(&ima->id, 0);
- }
- }
+ int i;
+ for (i = 0; i < bake_images->size; i++) {
+ Image *ima = bake_images->data[i].image;
+ if (ima->ok == IMA_OK_LOADED) {
+ GPU_free_image(ima);
+ DEG_id_tag_update(&ima->id, 0);
+ }
+ }
}
-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 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)
{
- ImBuf *ibuf = NULL;
- bool ok = false;
- bool is_float;
-
- is_float = im_format->depth > 8;
-
- /* create a new ImBuf */
- ibuf = IMB_allocImBuf(width, height, im_format->planes, (is_float ? IB_rectfloat : IB_rect));
-
- if (!ibuf)
- return false;
-
- /* populates the ImBuf */
- if (is_float) {
- IMB_buffer_float_from_float(
- ibuf->rect_float, buffer, ibuf->channels,
- IB_PROFILE_LINEAR_RGB, IB_PROFILE_LINEAR_RGB, false,
- ibuf->x, ibuf->y, ibuf->x, ibuf->x);
- }
- else {
- if (!is_noncolor) {
- const char *from_colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_SCENE_LINEAR);
- const char *to_colorspace = IMB_colormanagement_get_rect_colorspace(ibuf);
- IMB_colormanagement_transform(buffer, ibuf->x, ibuf->y, ibuf->channels, from_colorspace, to_colorspace, false);
- }
-
- IMB_buffer_byte_from_float(
- (unsigned char *) ibuf->rect, buffer, ibuf->channels, ibuf->dither,
- IB_PROFILE_SRGB, IB_PROFILE_SRGB,
- false, ibuf->x, ibuf->y, ibuf->x, ibuf->x);
- }
-
- /* margins */
- if (margin > 0) {
- char *mask_buffer = NULL;
- const size_t num_pixels = (size_t)width * (size_t)height;
-
- mask_buffer = MEM_callocN(sizeof(char) * num_pixels, "Bake Mask");
- RE_bake_mask_fill(pixel_array, num_pixels, mask_buffer);
- RE_bake_margin(ibuf, mask_buffer, margin);
-
- if (mask_buffer)
- MEM_freeN(mask_buffer);
- }
-
- if ((ok = BKE_imbuf_write(ibuf, filepath, im_format))) {
+ ImBuf *ibuf = NULL;
+ bool ok = false;
+ bool is_float;
+
+ is_float = im_format->depth > 8;
+
+ /* create a new ImBuf */
+ ibuf = IMB_allocImBuf(width, height, im_format->planes, (is_float ? IB_rectfloat : IB_rect));
+
+ if (!ibuf)
+ return false;
+
+ /* populates the ImBuf */
+ if (is_float) {
+ IMB_buffer_float_from_float(ibuf->rect_float,
+ buffer,
+ ibuf->channels,
+ IB_PROFILE_LINEAR_RGB,
+ IB_PROFILE_LINEAR_RGB,
+ false,
+ ibuf->x,
+ ibuf->y,
+ ibuf->x,
+ ibuf->x);
+ }
+ else {
+ if (!is_noncolor) {
+ const char *from_colorspace = IMB_colormanagement_role_colorspace_name_get(
+ COLOR_ROLE_SCENE_LINEAR);
+ const char *to_colorspace = IMB_colormanagement_get_rect_colorspace(ibuf);
+ IMB_colormanagement_transform(
+ buffer, ibuf->x, ibuf->y, ibuf->channels, from_colorspace, to_colorspace, false);
+ }
+
+ IMB_buffer_byte_from_float((unsigned char *)ibuf->rect,
+ buffer,
+ ibuf->channels,
+ ibuf->dither,
+ IB_PROFILE_SRGB,
+ IB_PROFILE_SRGB,
+ false,
+ ibuf->x,
+ ibuf->y,
+ ibuf->x,
+ ibuf->x);
+ }
+
+ /* margins */
+ if (margin > 0) {
+ char *mask_buffer = NULL;
+ const size_t num_pixels = (size_t)width * (size_t)height;
+
+ mask_buffer = MEM_callocN(sizeof(char) * num_pixels, "Bake Mask");
+ RE_bake_mask_fill(pixel_array, num_pixels, mask_buffer);
+ RE_bake_margin(ibuf, mask_buffer, margin);
+
+ if (mask_buffer)
+ MEM_freeN(mask_buffer);
+ }
+
+ if ((ok = BKE_imbuf_write(ibuf, filepath, im_format))) {
#ifndef WIN32
- chmod(filepath, S_IRUSR | S_IWUSR);
+ chmod(filepath, S_IRUSR | S_IWUSR);
#endif
- //printf("%s saving bake map: '%s'\n", __func__, filepath);
- }
+ //printf("%s saving bake map: '%s'\n", __func__, filepath);
+ }
- /* garbage collection */
- IMB_freeImBuf(ibuf);
+ /* garbage collection */
+ IMB_freeImBuf(ibuf);
- return ok;
+ return ok;
}
static bool is_noncolor_pass(eScenePassType pass_type)
{
- return ELEM(pass_type,
- SCE_PASS_Z,
- SCE_PASS_NORMAL,
- SCE_PASS_VECTOR,
- SCE_PASS_INDEXOB,
- SCE_PASS_UV,
- SCE_PASS_RAYHITS,
- SCE_PASS_INDEXMA);
+ return ELEM(pass_type,
+ SCE_PASS_Z,
+ SCE_PASS_NORMAL,
+ SCE_PASS_VECTOR,
+ SCE_PASS_INDEXOB,
+ SCE_PASS_UV,
+ SCE_PASS_RAYHITS,
+ SCE_PASS_INDEXMA);
}
/* if all is good tag image and return true */
static bool bake_object_check(ViewLayer *view_layer, Object *ob, ReportList *reports)
{
- Image *image;
- Base *base = BKE_view_layer_base_find(view_layer, ob);
- void *lock;
- int i;
-
- if (base == NULL) {
- BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is not in view layer", ob->id.name + 2);
- return false;
- }
-
- if (!(base->flag & BASE_ENABLED_RENDER)) {
- BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is not enabled for rendering", ob->id.name + 2);
- return false;
- }
-
-
- if (ob->type != OB_MESH) {
- BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is not a mesh", ob->id.name + 2);
- return false;
- }
- else {
- Mesh *me = (Mesh *)ob->data;
-
- if (CustomData_get_active_layer_index(&me->ldata, CD_MLOOPUV) == -1) {
- BKE_reportf(reports, RPT_ERROR,
- "No active UV layer found in the object \"%s\"", ob->id.name + 2);
- return false;
- }
- }
-
- for (i = 0; i < ob->totcol; i++) {
- bNodeTree *ntree = NULL;
- bNode *node = NULL;
- ED_object_get_active_image(ob, i + 1, &image, NULL, &node, &ntree);
-
- if (image) {
- ImBuf *ibuf;
-
- if (node) {
- if (BKE_node_is_connected_to_output(ntree, node)) {
- /* we don't return false since this may be a false positive
- * this can't be RPT_ERROR though, otherwise it prevents
- * multiple highpoly objects to be baked at once */
- BKE_reportf(reports, RPT_INFO,
- "Circular dependency for image \"%s\" from object \"%s\"",
- image->id.name + 2, ob->id.name + 2);
- }
- }
-
- ibuf = BKE_image_acquire_ibuf(image, NULL, &lock);
-
- if (ibuf) {
- BKE_image_release_ibuf(image, ibuf, lock);
- }
- else {
- BKE_reportf(reports, RPT_ERROR,
- "Uninitialized image \"%s\" from object \"%s\"",
- image->id.name + 2, ob->id.name + 2);
-
- BKE_image_release_ibuf(image, ibuf, lock);
- return false;
- }
- }
- else {
- Material *mat = give_current_material(ob, i);
- if (mat != NULL) {
- BKE_reportf(reports, RPT_INFO,
- "No active image found in material \"%s\" (%d) for object \"%s\"",
- mat->id.name + 2, i, ob->id.name + 2);
- }
- else {
- BKE_reportf(reports, RPT_INFO,
- "No active image found in material slot (%d) for object \"%s\"",
- i, ob->id.name + 2);
- }
- continue;
- }
-
- image->id.tag |= LIB_TAG_DOIT;
- }
- return true;
+ Image *image;
+ Base *base = BKE_view_layer_base_find(view_layer, ob);
+ void *lock;
+ int i;
+
+ if (base == NULL) {
+ BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is not in view layer", ob->id.name + 2);
+ return false;
+ }
+
+ if (!(base->flag & BASE_ENABLED_RENDER)) {
+ BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is not enabled for rendering", ob->id.name + 2);
+ return false;
+ }
+
+ if (ob->type != OB_MESH) {
+ BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is not a mesh", ob->id.name + 2);
+ return false;
+ }
+ else {
+ Mesh *me = (Mesh *)ob->data;
+
+ if (CustomData_get_active_layer_index(&me->ldata, CD_MLOOPUV) == -1) {
+ BKE_reportf(
+ reports, RPT_ERROR, "No active UV layer found in the object \"%s\"", ob->id.name + 2);
+ return false;
+ }
+ }
+
+ for (i = 0; i < ob->totcol; i++) {
+ bNodeTree *ntree = NULL;
+ bNode *node = NULL;
+ ED_object_get_active_image(ob, i + 1, &image, NULL, &node, &ntree);
+
+ if (image) {
+ ImBuf *ibuf;
+
+ if (node) {
+ if (BKE_node_is_connected_to_output(ntree, node)) {
+ /* we don't return false since this may be a false positive
+ * this can't be RPT_ERROR though, otherwise it prevents
+ * multiple highpoly objects to be baked at once */
+ BKE_reportf(reports,
+ RPT_INFO,
+ "Circular dependency for image \"%s\" from object \"%s\"",
+ image->id.name + 2,
+ ob->id.name + 2);
+ }
+ }
+
+ ibuf = BKE_image_acquire_ibuf(image, NULL, &lock);
+
+ if (ibuf) {
+ BKE_image_release_ibuf(image, ibuf, lock);
+ }
+ else {
+ BKE_reportf(reports,
+ RPT_ERROR,
+ "Uninitialized image \"%s\" from object \"%s\"",
+ image->id.name + 2,
+ ob->id.name + 2);
+
+ BKE_image_release_ibuf(image, ibuf, lock);
+ return false;
+ }
+ }
+ else {
+ Material *mat = give_current_material(ob, i);
+ if (mat != NULL) {
+ BKE_reportf(reports,
+ RPT_INFO,
+ "No active image found in material \"%s\" (%d) for object \"%s\"",
+ mat->id.name + 2,
+ i,
+ ob->id.name + 2);
+ }
+ else {
+ BKE_reportf(reports,
+ RPT_INFO,
+ "No active image found in material slot (%d) for object \"%s\"",
+ i,
+ ob->id.name + 2);
+ }
+ continue;
+ }
+
+ image->id.tag |= LIB_TAG_DOIT;
+ }
+ return true;
}
-static bool bake_pass_filter_check(eScenePassType pass_type, const int pass_filter, ReportList *reports)
+static bool bake_pass_filter_check(eScenePassType pass_type,
+ const int pass_filter,
+ ReportList *reports)
{
- switch (pass_type) {
- case SCE_PASS_COMBINED:
- if ((pass_filter & R_BAKE_PASS_FILTER_EMIT) != 0) {
- return true;
- }
-
- if (((pass_filter & R_BAKE_PASS_FILTER_DIRECT) != 0) ||
- ((pass_filter & R_BAKE_PASS_FILTER_INDIRECT) != 0))
- {
- if (((pass_filter & R_BAKE_PASS_FILTER_DIFFUSE) != 0) ||
- ((pass_filter & R_BAKE_PASS_FILTER_GLOSSY) != 0) ||
- ((pass_filter & R_BAKE_PASS_FILTER_TRANSM) != 0) ||
- ((pass_filter & R_BAKE_PASS_FILTER_SUBSURFACE) != 0))
- {
- return true;
- }
-
- if ((pass_filter & R_BAKE_PASS_FILTER_AO) != 0) {
- BKE_report(reports, RPT_ERROR,
- "Combined bake pass Ambient Occlusion contribution requires an enabled light pass "
- "(bake the Ambient Occlusion pass type instead)");
- }
- else {
- BKE_report(reports, RPT_ERROR,
- "Combined bake pass requires Emit, or a light pass with "
- "Direct or Indirect contributions enabled");
- }
-
- return false;
- }
- else {
- BKE_report(reports, RPT_ERROR,
- "Combined bake pass requires Emit, or a light pass with "
- "Direct or Indirect contributions enabled");
- return false;
- }
- break;
- case SCE_PASS_DIFFUSE_COLOR:
- case SCE_PASS_GLOSSY_COLOR:
- case SCE_PASS_TRANSM_COLOR:
- case SCE_PASS_SUBSURFACE_COLOR:
- if (((pass_filter & R_BAKE_PASS_FILTER_COLOR) != 0) ||
- ((pass_filter & R_BAKE_PASS_FILTER_DIRECT) != 0) ||
- ((pass_filter & R_BAKE_PASS_FILTER_INDIRECT) != 0))
- {
- return true;
- }
- else {
- BKE_report(reports, RPT_ERROR,
- "Bake pass requires Direct, Indirect, or Color contributions to be enabled");
- return false;
- }
- break;
- default:
- return true;
- break;
- }
+ switch (pass_type) {
+ case SCE_PASS_COMBINED:
+ if ((pass_filter & R_BAKE_PASS_FILTER_EMIT) != 0) {
+ return true;
+ }
+
+ if (((pass_filter & R_BAKE_PASS_FILTER_DIRECT) != 0) ||
+ ((pass_filter & R_BAKE_PASS_FILTER_INDIRECT) != 0)) {
+ if (((pass_filter & R_BAKE_PASS_FILTER_DIFFUSE) != 0) ||
+ ((pass_filter & R_BAKE_PASS_FILTER_GLOSSY) != 0) ||
+ ((pass_filter & R_BAKE_PASS_FILTER_TRANSM) != 0) ||
+ ((pass_filter & R_BAKE_PASS_FILTER_SUBSURFACE) != 0)) {
+ return true;
+ }
+
+ if ((pass_filter & R_BAKE_PASS_FILTER_AO) != 0) {
+ BKE_report(
+ reports,
+ RPT_ERROR,
+ "Combined bake pass Ambient Occlusion contribution requires an enabled light pass "
+ "(bake the Ambient Occlusion pass type instead)");
+ }
+ else {
+ BKE_report(reports,
+ RPT_ERROR,
+ "Combined bake pass requires Emit, or a light pass with "
+ "Direct or Indirect contributions enabled");
+ }
+
+ return false;
+ }
+ else {
+ BKE_report(reports,
+ RPT_ERROR,
+ "Combined bake pass requires Emit, or a light pass with "
+ "Direct or Indirect contributions enabled");
+ return false;
+ }
+ break;
+ case SCE_PASS_DIFFUSE_COLOR:
+ case SCE_PASS_GLOSSY_COLOR:
+ case SCE_PASS_TRANSM_COLOR:
+ case SCE_PASS_SUBSURFACE_COLOR:
+ if (((pass_filter & R_BAKE_PASS_FILTER_COLOR) != 0) ||
+ ((pass_filter & R_BAKE_PASS_FILTER_DIRECT) != 0) ||
+ ((pass_filter & R_BAKE_PASS_FILTER_INDIRECT) != 0)) {
+ return true;
+ }
+ else {
+ BKE_report(reports,
+ RPT_ERROR,
+ "Bake pass requires Direct, Indirect, or Color contributions to be enabled");
+ return false;
+ }
+ break;
+ default:
+ return true;
+ break;
+ }
}
/* before even getting in the bake function we check for some basic errors */
-static bool bake_objects_check(Main *bmain, ViewLayer *view_layer, Object *ob, ListBase *selected_objects,
- ReportList *reports, const bool is_selected_to_active)
+static bool bake_objects_check(Main *bmain,
+ ViewLayer *view_layer,
+ Object *ob,
+ ListBase *selected_objects,
+ ReportList *reports,
+ const bool is_selected_to_active)
{
- CollectionPointerLink *link;
-
- /* error handling and tag (in case multiple materials share the same image) */
- BKE_main_id_tag_idcode(bmain, ID_IM, LIB_TAG_DOIT, false);
-
- if (is_selected_to_active) {
- int tot_objects = 0;
-
- if (!bake_object_check(view_layer, ob, reports))
- return false;
-
- for (link = selected_objects->first; link; link = link->next) {
- Object *ob_iter = (Object *)link->ptr.data;
-
- if (ob_iter == ob)
- continue;
-
- if (ELEM(ob_iter->type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL) == false) {
- BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is not a mesh or can't be converted to a mesh (Curve, Text, Surface or Metaball)", ob_iter->id.name + 2);
- return false;
- }
- tot_objects += 1;
- }
-
- if (tot_objects == 0) {
- BKE_report(reports, RPT_ERROR, "No valid selected objects");
- return false;
- }
- }
- else {
- if (BLI_listbase_is_empty(selected_objects)) {
- BKE_report(reports, RPT_ERROR, "No valid selected objects");
- return false;
- }
-
- for (link = selected_objects->first; link; link = link->next) {
- if (!bake_object_check(view_layer, link->ptr.data, reports))
- return false;
- }
- }
- return true;
+ CollectionPointerLink *link;
+
+ /* error handling and tag (in case multiple materials share the same image) */
+ BKE_main_id_tag_idcode(bmain, ID_IM, LIB_TAG_DOIT, false);
+
+ if (is_selected_to_active) {
+ int tot_objects = 0;
+
+ if (!bake_object_check(view_layer, ob, reports))
+ return false;
+
+ for (link = selected_objects->first; link; link = link->next) {
+ Object *ob_iter = (Object *)link->ptr.data;
+
+ if (ob_iter == ob)
+ continue;
+
+ if (ELEM(ob_iter->type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL) == false) {
+ BKE_reportf(reports,
+ RPT_ERROR,
+ "Object \"%s\" is not a mesh or can't be converted to a mesh (Curve, Text, "
+ "Surface or Metaball)",
+ ob_iter->id.name + 2);
+ return false;
+ }
+ tot_objects += 1;
+ }
+
+ if (tot_objects == 0) {
+ BKE_report(reports, RPT_ERROR, "No valid selected objects");
+ return false;
+ }
+ }
+ else {
+ if (BLI_listbase_is_empty(selected_objects)) {
+ BKE_report(reports, RPT_ERROR, "No valid selected objects");
+ return false;
+ }
+
+ for (link = selected_objects->first; link; link = link->next) {
+ if (!bake_object_check(view_layer, link->ptr.data, reports))
+ return false;
+ }
+ }
+ return true;
}
/* it needs to be called after bake_objects_check since the image tagging happens there */
static void bake_images_clear(Main *bmain, const bool is_tangent)
{
- Image *image;
- for (image = bmain->images.first; image; image = image->id.next) {
- if ((image->id.tag & LIB_TAG_DOIT) != 0) {
- RE_bake_ibuf_clear(image, is_tangent);
- }
- }
+ Image *image;
+ for (image = bmain->images.first; image; image = image->id.next) {
+ if ((image->id.tag & LIB_TAG_DOIT) != 0) {
+ RE_bake_ibuf_clear(image, is_tangent);
+ }
+ }
}
static void build_image_lookup(Main *bmain, Object *ob, BakeImages *bake_images)
{
- const int tot_mat = ob->totcol;
- int i, j;
- int tot_images = 0;
-
- /* error handling and tag (in case multiple materials share the same image) */
- BKE_main_id_tag_idcode(bmain, ID_IM, LIB_TAG_DOIT, false);
-
- for (i = 0; i < tot_mat; i++) {
- Image *image;
- ED_object_get_active_image(ob, i + 1, &image, NULL, NULL, NULL);
-
- /* Some materials have no image, we just ignore those cases. */
- if (image == NULL) {
- bake_images->lookup[i] = -1;
- }
- else if (image->id.tag & LIB_TAG_DOIT) {
- for (j = 0; j < i; j++) {
- if (bake_images->data[j].image == image) {
- bake_images->lookup[i] = j;
- break;
- }
- }
- }
- else {
- bake_images->lookup[i] = tot_images;
- bake_images->data[tot_images].image = image;
- image->id.tag |= LIB_TAG_DOIT;
- tot_images++;
- }
- }
-
- bake_images->size = tot_images;
+ const int tot_mat = ob->totcol;
+ int i, j;
+ int tot_images = 0;
+
+ /* error handling and tag (in case multiple materials share the same image) */
+ BKE_main_id_tag_idcode(bmain, ID_IM, LIB_TAG_DOIT, false);
+
+ for (i = 0; i < tot_mat; i++) {
+ Image *image;
+ ED_object_get_active_image(ob, i + 1, &image, NULL, NULL, NULL);
+
+ /* Some materials have no image, we just ignore those cases. */
+ if (image == NULL) {
+ bake_images->lookup[i] = -1;
+ }
+ else if (image->id.tag & LIB_TAG_DOIT) {
+ for (j = 0; j < i; j++) {
+ if (bake_images->data[j].image == image) {
+ bake_images->lookup[i] = j;
+ break;
+ }
+ }
+ }
+ else {
+ bake_images->lookup[i] = tot_images;
+ bake_images->data[tot_images].image = image;
+ image->id.tag |= LIB_TAG_DOIT;
+ tot_images++;
+ }
+ }
+
+ bake_images->size = tot_images;
}
/*
@@ -595,881 +661,1130 @@ static void build_image_lookup(Main *bmain, Object *ob, BakeImages *bake_images)
*/
static size_t initialize_internal_images(BakeImages *bake_images, ReportList *reports)
{
- int i;
- size_t tot_size = 0;
-
- for (i = 0; i < bake_images->size; i++) {
- ImBuf *ibuf;
- void *lock;
-
- BakeImage *bk_image = &bake_images->data[i];
- ibuf = BKE_image_acquire_ibuf(bk_image->image, NULL, &lock);
-
- if (ibuf) {
- bk_image->width = ibuf->x;
- bk_image->height = ibuf->y;
- bk_image->offset = tot_size;
-
- tot_size += (size_t)ibuf->x * (size_t)ibuf->y;
- }
- else {
- BKE_image_release_ibuf(bk_image->image, ibuf, lock);
- BKE_reportf(reports, RPT_ERROR, "Uninitialized image %s", bk_image->image->id.name + 2);
- return 0;
- }
- BKE_image_release_ibuf(bk_image->image, ibuf, lock);
- }
- return tot_size;
+ int i;
+ size_t tot_size = 0;
+
+ for (i = 0; i < bake_images->size; i++) {
+ ImBuf *ibuf;
+ void *lock;
+
+ BakeImage *bk_image = &bake_images->data[i];
+ ibuf = BKE_image_acquire_ibuf(bk_image->image, NULL, &lock);
+
+ if (ibuf) {
+ bk_image->width = ibuf->x;
+ bk_image->height = ibuf->y;
+ bk_image->offset = tot_size;
+
+ tot_size += (size_t)ibuf->x * (size_t)ibuf->y;
+ }
+ else {
+ BKE_image_release_ibuf(bk_image->image, ibuf, lock);
+ BKE_reportf(reports, RPT_ERROR, "Uninitialized image %s", bk_image->image->id.name + 2);
+ return 0;
+ }
+ BKE_image_release_ibuf(bk_image->image, ibuf, lock);
+ }
+ return tot_size;
}
/* create new mesh with edit mode changes and modifiers applied */
static Mesh *bake_mesh_new_from_object(Depsgraph *depsgraph, Main *bmain, Scene *scene, Object *ob)
{
- bool apply_modifiers = (ob->type != OB_MESH);
- Mesh *me = BKE_mesh_new_from_object(depsgraph, bmain, scene, ob, apply_modifiers, false);
+ bool apply_modifiers = (ob->type != OB_MESH);
+ Mesh *me = BKE_mesh_new_from_object(depsgraph, bmain, scene, ob, apply_modifiers, false);
- if (me->flag & ME_AUTOSMOOTH) {
- BKE_mesh_split_faces(me, true);
- }
+ if (me->flag & ME_AUTOSMOOTH) {
+ BKE_mesh_split_faces(me, true);
+ }
- return me;
+ return me;
}
-static int bake(
- Render *re, Main *bmain, Scene *scene, ViewLayer *view_layer, Object *ob_low, ListBase *selected_objects,
- ReportList *reports,
- const eScenePassType pass_type, const int pass_filter, const int margin,
- const eBakeSaveMode save_mode, const bool is_clear, const bool is_split_materials,
- const bool is_automatic_name, const bool is_selected_to_active, const bool is_cage,
- const float cage_extrusion, const int normal_space, const eBakeNormalSwizzle normal_swizzle[],
- const char *custom_cage, const char *filepath, const int width, const int height,
- const char *identifier, ScrArea *sa, const char *uv_layer)
+static int bake(Render *re,
+ Main *bmain,
+ Scene *scene,
+ ViewLayer *view_layer,
+ Object *ob_low,
+ ListBase *selected_objects,
+ ReportList *reports,
+ const eScenePassType pass_type,
+ const int pass_filter,
+ const int margin,
+ const eBakeSaveMode save_mode,
+ const bool is_clear,
+ const bool is_split_materials,
+ const bool is_automatic_name,
+ const bool is_selected_to_active,
+ const bool is_cage,
+ const float cage_extrusion,
+ const int normal_space,
+ const eBakeNormalSwizzle normal_swizzle[],
+ const char *custom_cage,
+ const char *filepath,
+ const int width,
+ const int height,
+ const char *identifier,
+ ScrArea *sa,
+ const char *uv_layer)
{
- /* We build a depsgraph for the baking,
- * so we don't need to change the original data to adjust visibility and modifiers. */
- Depsgraph *depsgraph = DEG_graph_new(scene, view_layer, DAG_EVAL_RENDER);
- DEG_graph_build_from_view_layer(depsgraph, bmain, scene, view_layer);
-
- int op_result = OPERATOR_CANCELLED;
- bool ok = false;
-
- Object *ob_cage = NULL;
- Object *ob_cage_eval = NULL;
- Object *ob_low_eval = NULL;
-
- BakeHighPolyData *highpoly = NULL;
- int tot_highpoly = 0;
-
- Mesh *me_low = NULL;
- Mesh *me_cage = NULL;
-
- MultiresModifierData *mmd_low = NULL;
- int mmd_flags_low = 0;
-
- float *result = NULL;
-
- BakePixel *pixel_array_low = NULL;
- BakePixel *pixel_array_high = NULL;
-
- const bool is_save_internal = (save_mode == R_BAKE_SAVE_INTERNAL);
- const bool is_noncolor = is_noncolor_pass(pass_type);
- const int depth = RE_pass_depth(pass_type);
-
- BakeImages bake_images = {NULL};
-
- size_t num_pixels;
- int tot_materials;
-
- RE_bake_engine_set_engine_parameters(re, bmain, scene);
-
- if (!RE_bake_has_engine(re)) {
- BKE_report(reports, RPT_ERROR, "Current render engine does not support baking");
- goto cleanup;
- }
-
- tot_materials = ob_low->totcol;
-
- if (uv_layer && uv_layer[0] != '\0') {
- Mesh *me = (Mesh *)ob_low->data;
- if (CustomData_get_named_layer(&me->ldata, CD_MLOOPUV, uv_layer) == -1) {
- BKE_reportf(reports, RPT_ERROR,
- "No UV layer named \"%s\" found in the object \"%s\"", uv_layer, ob_low->id.name + 2);
- goto cleanup;
- }
- }
-
- if (tot_materials == 0) {
- if (is_save_internal) {
- BKE_report(reports, RPT_ERROR,
- "No active image found, add a material or bake to an external file");
-
- goto cleanup;
- }
- else if (is_split_materials) {
- BKE_report(reports, RPT_ERROR,
- "No active image found, add a material or bake without the Split Materials option");
-
- goto cleanup;
- }
- else {
- /* baking externally without splitting materials */
- tot_materials = 1;
- }
- }
-
- /* we overallocate in case there is more materials than images */
- bake_images.data = MEM_mallocN(sizeof(BakeImage) * tot_materials, "bake images dimensions (width, height, offset)");
- bake_images.lookup = MEM_mallocN(sizeof(int) * tot_materials, "bake images lookup (from material to BakeImage)");
-
- build_image_lookup(bmain, ob_low, &bake_images);
-
- if (is_save_internal) {
- num_pixels = initialize_internal_images(&bake_images, reports);
-
- if (num_pixels == 0) {
- goto cleanup;
- }
- }
- else {
- /* when saving externally always use the size specified in the UI */
-
- num_pixels = (size_t)width * (size_t)height * bake_images.size;
-
- for (int i = 0; i < bake_images.size; i++) {
- bake_images.data[i].width = width;
- bake_images.data[i].height = height;
- bake_images.data[i].offset = (is_split_materials ? num_pixels : 0);
- bake_images.data[i].image = NULL;
- }
-
- if (!is_split_materials) {
- /* saving a single image */
- for (int i = 0; i < tot_materials; i++) {
- bake_images.lookup[i] = 0;
- }
- }
- }
-
- if (is_selected_to_active) {
- CollectionPointerLink *link;
- tot_highpoly = 0;
-
- for (link = selected_objects->first; link; link = link->next) {
- Object *ob_iter = link->ptr.data;
-
- if (ob_iter == ob_low)
- continue;
-
- tot_highpoly ++;
- }
-
- if (is_cage && custom_cage[0] != '\0') {
- ob_cage = BLI_findstring(&bmain->objects, custom_cage, offsetof(ID, name) + 2);
-
- if (ob_cage == NULL || ob_cage->type != OB_MESH) {
- BKE_report(reports, RPT_ERROR, "No valid cage object");
- goto cleanup;
- }
- else {
- ob_cage_eval = DEG_get_evaluated_object(depsgraph, ob_cage);
- ob_cage_eval->restrictflag |= OB_RESTRICT_RENDER;
- ob_cage_eval->base_flag &= ~(BASE_VISIBLE | BASE_ENABLED_RENDER);
- }
- }
- }
-
- pixel_array_low = MEM_mallocN(sizeof(BakePixel) * num_pixels, "bake pixels low poly");
- pixel_array_high = MEM_mallocN(sizeof(BakePixel) * num_pixels, "bake pixels high poly");
- result = MEM_callocN(sizeof(float) * depth * num_pixels, "bake return pixels");
-
- /* for multires bake, use linear UV subdivision to match low res UVs */
- if (pass_type == SCE_PASS_NORMAL && normal_space == R_BAKE_SPACE_TANGENT && !is_selected_to_active) {
- mmd_low = (MultiresModifierData *) modifiers_findByType(ob_low, eModifierType_Multires);
- if (mmd_low) {
- mmd_flags_low = mmd_low->flags;
- mmd_low->uv_smooth = SUBSURF_UV_SMOOTH_NONE;
- }
- }
-
- /* Make sure depsgraph is up to date. */
- BKE_scene_graph_update_tagged(depsgraph, bmain);
- ob_low_eval = DEG_get_evaluated_object(depsgraph, ob_low);
-
- /* get the mesh as it arrives in the renderer */
- me_low = bake_mesh_new_from_object(depsgraph, bmain, scene, ob_low_eval);
-
- /* populate the pixel array with the face data */
- if ((is_selected_to_active && (ob_cage == NULL) && is_cage) == false)
- RE_bake_pixels_populate(me_low, pixel_array_low, num_pixels, &bake_images, uv_layer);
- /* else populate the pixel array with the 'cage' mesh (the smooth version of the mesh) */
-
- if (is_selected_to_active) {
- CollectionPointerLink *link;
- int i = 0;
-
- /* prepare cage mesh */
- if (ob_cage) {
- me_cage = bake_mesh_new_from_object(depsgraph, bmain, scene, ob_cage_eval);
- if ((me_low->totpoly != me_cage->totpoly) || (me_low->totloop != me_cage->totloop)) {
- BKE_report(reports, RPT_ERROR,
- "Invalid cage object, the cage mesh must have the same number "
- "of faces as the active object");
- goto cleanup;
- }
- }
- else if (is_cage) {
- BKE_object_eval_reset(ob_low_eval);
-
- ModifierData *md = ob_low_eval->modifiers.first;
- while (md) {
- ModifierData *md_next = md->next;
-
- /* Edge Split cannot be applied in the cage,
- * the cage is supposed to have interpolated normals
- * between the faces unless the geometry is physically
- * split. So we create a copy of the low poly mesh without
- * the eventual edge split.*/
-
- if (md->type == eModifierType_EdgeSplit) {
- BLI_remlink(&ob_low_eval->modifiers, md);
- modifier_free(md);
- }
- md = md_next;
- }
-
- me_cage = bake_mesh_new_from_object(depsgraph, bmain, scene, ob_low_eval);
- RE_bake_pixels_populate(me_cage, pixel_array_low, num_pixels, &bake_images, uv_layer);
- }
-
- highpoly = MEM_callocN(sizeof(BakeHighPolyData) * tot_highpoly, "bake high poly objects");
-
- /* populate highpoly array */
- for (link = selected_objects->first; link; link = link->next) {
- Object *ob_iter = link->ptr.data;
-
- if (ob_iter == ob_low)
- continue;
-
- /* initialize highpoly_data */
- highpoly[i].ob = ob_iter;
- highpoly[i].ob_eval = DEG_get_evaluated_object(depsgraph, ob_iter);
- highpoly[i].ob_eval->restrictflag &= ~OB_RESTRICT_RENDER;
- highpoly[i].ob_eval->base_flag |= (BASE_VISIBLE | BASE_ENABLED_RENDER);
- highpoly[i].me = bake_mesh_new_from_object(depsgraph, bmain, scene, highpoly[i].ob_eval);
-
- /* lowpoly to highpoly transformation matrix */
- copy_m4_m4(highpoly[i].obmat, highpoly[i].ob->obmat);
- invert_m4_m4(highpoly[i].imat, highpoly[i].obmat);
-
- highpoly[i].is_flip_object = is_negative_m4(highpoly[i].ob->obmat);
-
- i++;
- }
-
- BLI_assert(i == tot_highpoly);
-
-
- if (ob_cage != NULL) {
- ob_cage_eval->restrictflag |= OB_RESTRICT_RENDER;
- ob_cage_eval->base_flag &= ~(BASE_VISIBLE | BASE_ENABLED_RENDER);
- }
- ob_low_eval->restrictflag |= OB_RESTRICT_RENDER;
- ob_low_eval->base_flag &= ~(BASE_VISIBLE | BASE_ENABLED_RENDER);
-
- /* populate the pixel arrays with the corresponding face data for each high poly object */
- if (!RE_bake_pixels_populate_from_objects(
- me_low, pixel_array_low, pixel_array_high, highpoly, tot_highpoly, num_pixels, ob_cage != NULL,
- cage_extrusion, ob_low_eval->obmat, (ob_cage ? ob_cage->obmat : ob_low_eval->obmat), me_cage))
- {
- BKE_report(reports, RPT_ERROR, "Error handling selected objects");
- goto cleanup;
- }
-
- /* the baking itself */
- for (i = 0; i < tot_highpoly; i++) {
- ok = RE_bake_engine(re, depsgraph, highpoly[i].ob, i, pixel_array_high,
- num_pixels, depth, pass_type, pass_filter, result);
- if (!ok) {
- BKE_reportf(reports, RPT_ERROR, "Error baking from object \"%s\"", highpoly[i].ob->id.name + 2);
- goto cleanup;
- }
- }
- }
- else {
- /* If low poly is not renderable it should have failed long ago. */
- BLI_assert((ob_low_eval->restrictflag & OB_RESTRICT_RENDER) == 0);
-
- if (RE_bake_has_engine(re)) {
- ok = RE_bake_engine(re, depsgraph, ob_low_eval, 0, pixel_array_low, num_pixels, depth, pass_type, pass_filter, result);
- }
- else {
- BKE_report(reports, RPT_ERROR, "Current render engine does not support baking");
- goto cleanup;
- }
- }
-
- /* normal space conversion
- * the normals are expected to be in world space, +X +Y +Z */
- if (ok && pass_type == SCE_PASS_NORMAL) {
- switch (normal_space) {
- case R_BAKE_SPACE_WORLD:
- {
- /* Cycles internal format */
- if ((normal_swizzle[0] == R_BAKE_POSX) &&
- (normal_swizzle[1] == R_BAKE_POSY) &&
- (normal_swizzle[2] == R_BAKE_POSZ))
- {
- break;
- }
- else {
- RE_bake_normal_world_to_world(pixel_array_low, num_pixels, depth, result, normal_swizzle);
- }
- break;
- }
- case R_BAKE_SPACE_OBJECT:
- {
- RE_bake_normal_world_to_object(pixel_array_low, num_pixels, depth, result, ob_low_eval, normal_swizzle);
- break;
- }
- case R_BAKE_SPACE_TANGENT:
- {
- if (is_selected_to_active) {
- RE_bake_normal_world_to_tangent(pixel_array_low, num_pixels, depth, result, me_low, normal_swizzle, ob_low_eval->obmat);
- }
- else {
- /* from multiresolution */
- Mesh *me_nores = NULL;
- ModifierData *md = NULL;
- int mode;
-
- BKE_object_eval_reset(ob_low_eval);
- md = modifiers_findByType(ob_low_eval, eModifierType_Multires);
-
- if (md) {
- mode = md->mode;
- md->mode &= ~eModifierMode_Render;
- }
-
- /* Evaluate modifiers again. */
- me_nores = BKE_mesh_new_from_object(depsgraph, bmain, scene, ob_low_eval, true, false);
- RE_bake_pixels_populate(me_nores, pixel_array_low, num_pixels, &bake_images, uv_layer);
-
- RE_bake_normal_world_to_tangent(pixel_array_low, num_pixels, depth, result, me_nores, normal_swizzle, ob_low_eval->obmat);
- BKE_id_free(bmain, me_nores);
-
- if (md)
- md->mode = mode;
- }
- break;
- }
- default:
- break;
- }
- }
-
- if (!ok) {
- BKE_reportf(reports, RPT_ERROR, "Problem baking object \"%s\"", ob_low->id.name + 2);
- op_result = OPERATOR_CANCELLED;
- }
- else {
- /* save the results */
- for (int i = 0; i < bake_images.size; i++) {
- BakeImage *bk_image = &bake_images.data[i];
-
- if (is_save_internal) {
- ok = write_internal_bake_pixels(
- bk_image->image,
- pixel_array_low + bk_image->offset,
- result + bk_image->offset * depth,
- bk_image->width, bk_image->height,
- margin, is_clear, is_noncolor);
-
- /* might be read by UI to set active image for display */
- bake_update_image(sa, bk_image->image);
-
- if (!ok) {
- BKE_reportf(reports, RPT_ERROR,
- "Problem saving the bake map internally for object \"%s\"", ob_low->id.name + 2);
- op_result = OPERATOR_CANCELLED;
- }
- else {
- BKE_report(reports, RPT_INFO,
- "Baking map saved to internal image, save it externally or pack it");
- op_result = OPERATOR_FINISHED;
- }
- }
- /* save externally */
- else {
- BakeData *bake = &scene->r.bake;
- char name[FILE_MAX];
-
- BKE_image_path_from_imtype(name, filepath, BKE_main_blendfile_path(bmain),
- 0, bake->im_format.imtype, true, false, NULL);
-
- if (is_automatic_name) {
- BLI_path_suffix(name, FILE_MAX, ob_low->id.name + 2, "_");
- BLI_path_suffix(name, FILE_MAX, identifier, "_");
- }
-
- if (is_split_materials) {
- if (bk_image->image) {
- BLI_path_suffix(name, FILE_MAX, bk_image->image->id.name + 2, "_");
- }
- else {
- if (ob_low_eval->mat[i]) {
- BLI_path_suffix(name, FILE_MAX, ob_low_eval->mat[i]->id.name + 2, "_");
- }
- else if (me_low->mat[i]) {
- BLI_path_suffix(name, FILE_MAX, me_low->mat[i]->id.name + 2, "_");
- }
- else {
- /* if everything else fails, use the material index */
- char tmp[5];
- sprintf(tmp, "%d", i % 1000);
- BLI_path_suffix(name, FILE_MAX, tmp, "_");
- }
- }
- }
-
- /* save it externally */
- ok = write_external_bake_pixels(
- name,
- pixel_array_low + bk_image->offset,
- result + bk_image->offset * depth,
- bk_image->width, bk_image->height,
- margin, &bake->im_format, is_noncolor);
-
- if (!ok) {
- BKE_reportf(reports, RPT_ERROR, "Problem saving baked map in \"%s\"", name);
- op_result = OPERATOR_CANCELLED;
- }
- else {
- BKE_reportf(reports, RPT_INFO, "Baking map written to \"%s\"", name);
- op_result = OPERATOR_FINISHED;
- }
-
- if (!is_split_materials) {
- break;
- }
- }
- }
- }
-
- if (is_save_internal)
- refresh_images(&bake_images);
+ /* We build a depsgraph for the baking,
+ * so we don't need to change the original data to adjust visibility and modifiers. */
+ Depsgraph *depsgraph = DEG_graph_new(scene, view_layer, DAG_EVAL_RENDER);
+ DEG_graph_build_from_view_layer(depsgraph, bmain, scene, view_layer);
+
+ int op_result = OPERATOR_CANCELLED;
+ bool ok = false;
+
+ Object *ob_cage = NULL;
+ Object *ob_cage_eval = NULL;
+ Object *ob_low_eval = NULL;
+
+ BakeHighPolyData *highpoly = NULL;
+ int tot_highpoly = 0;
+
+ Mesh *me_low = NULL;
+ Mesh *me_cage = NULL;
+
+ MultiresModifierData *mmd_low = NULL;
+ int mmd_flags_low = 0;
+
+ float *result = NULL;
+
+ BakePixel *pixel_array_low = NULL;
+ BakePixel *pixel_array_high = NULL;
+
+ const bool is_save_internal = (save_mode == R_BAKE_SAVE_INTERNAL);
+ const bool is_noncolor = is_noncolor_pass(pass_type);
+ const int depth = RE_pass_depth(pass_type);
+
+ BakeImages bake_images = {NULL};
+
+ size_t num_pixels;
+ int tot_materials;
+
+ RE_bake_engine_set_engine_parameters(re, bmain, scene);
+
+ if (!RE_bake_has_engine(re)) {
+ BKE_report(reports, RPT_ERROR, "Current render engine does not support baking");
+ goto cleanup;
+ }
+
+ tot_materials = ob_low->totcol;
+
+ if (uv_layer && uv_layer[0] != '\0') {
+ Mesh *me = (Mesh *)ob_low->data;
+ if (CustomData_get_named_layer(&me->ldata, CD_MLOOPUV, uv_layer) == -1) {
+ BKE_reportf(reports,
+ RPT_ERROR,
+ "No UV layer named \"%s\" found in the object \"%s\"",
+ uv_layer,
+ ob_low->id.name + 2);
+ goto cleanup;
+ }
+ }
+
+ if (tot_materials == 0) {
+ if (is_save_internal) {
+ BKE_report(
+ reports, RPT_ERROR, "No active image found, add a material or bake to an external file");
+
+ goto cleanup;
+ }
+ else if (is_split_materials) {
+ BKE_report(
+ reports,
+ RPT_ERROR,
+ "No active image found, add a material or bake without the Split Materials option");
+
+ goto cleanup;
+ }
+ else {
+ /* baking externally without splitting materials */
+ tot_materials = 1;
+ }
+ }
+
+ /* we overallocate in case there is more materials than images */
+ bake_images.data = MEM_mallocN(sizeof(BakeImage) * tot_materials,
+ "bake images dimensions (width, height, offset)");
+ bake_images.lookup = MEM_mallocN(sizeof(int) * tot_materials,
+ "bake images lookup (from material to BakeImage)");
+
+ build_image_lookup(bmain, ob_low, &bake_images);
+
+ if (is_save_internal) {
+ num_pixels = initialize_internal_images(&bake_images, reports);
+
+ if (num_pixels == 0) {
+ goto cleanup;
+ }
+ }
+ else {
+ /* when saving externally always use the size specified in the UI */
+
+ num_pixels = (size_t)width * (size_t)height * bake_images.size;
+
+ for (int i = 0; i < bake_images.size; i++) {
+ bake_images.data[i].width = width;
+ bake_images.data[i].height = height;
+ bake_images.data[i].offset = (is_split_materials ? num_pixels : 0);
+ bake_images.data[i].image = NULL;
+ }
+
+ if (!is_split_materials) {
+ /* saving a single image */
+ for (int i = 0; i < tot_materials; i++) {
+ bake_images.lookup[i] = 0;
+ }
+ }
+ }
+
+ if (is_selected_to_active) {
+ CollectionPointerLink *link;
+ tot_highpoly = 0;
+
+ for (link = selected_objects->first; link; link = link->next) {
+ Object *ob_iter = link->ptr.data;
+
+ if (ob_iter == ob_low)
+ continue;
+
+ tot_highpoly++;
+ }
+
+ if (is_cage && custom_cage[0] != '\0') {
+ ob_cage = BLI_findstring(&bmain->objects, custom_cage, offsetof(ID, name) + 2);
+
+ if (ob_cage == NULL || ob_cage->type != OB_MESH) {
+ BKE_report(reports, RPT_ERROR, "No valid cage object");
+ goto cleanup;
+ }
+ else {
+ ob_cage_eval = DEG_get_evaluated_object(depsgraph, ob_cage);
+ ob_cage_eval->restrictflag |= OB_RESTRICT_RENDER;
+ ob_cage_eval->base_flag &= ~(BASE_VISIBLE | BASE_ENABLED_RENDER);
+ }
+ }
+ }
+
+ pixel_array_low = MEM_mallocN(sizeof(BakePixel) * num_pixels, "bake pixels low poly");
+ pixel_array_high = MEM_mallocN(sizeof(BakePixel) * num_pixels, "bake pixels high poly");
+ result = MEM_callocN(sizeof(float) * depth * num_pixels, "bake return pixels");
+
+ /* for multires bake, use linear UV subdivision to match low res UVs */
+ if (pass_type == SCE_PASS_NORMAL && normal_space == R_BAKE_SPACE_TANGENT &&
+ !is_selected_to_active) {
+ mmd_low = (MultiresModifierData *)modifiers_findByType(ob_low, eModifierType_Multires);
+ if (mmd_low) {
+ mmd_flags_low = mmd_low->flags;
+ mmd_low->uv_smooth = SUBSURF_UV_SMOOTH_NONE;
+ }
+ }
+
+ /* Make sure depsgraph is up to date. */
+ BKE_scene_graph_update_tagged(depsgraph, bmain);
+ ob_low_eval = DEG_get_evaluated_object(depsgraph, ob_low);
+
+ /* get the mesh as it arrives in the renderer */
+ me_low = bake_mesh_new_from_object(depsgraph, bmain, scene, ob_low_eval);
+
+ /* populate the pixel array with the face data */
+ if ((is_selected_to_active && (ob_cage == NULL) && is_cage) == false)
+ RE_bake_pixels_populate(me_low, pixel_array_low, num_pixels, &bake_images, uv_layer);
+ /* else populate the pixel array with the 'cage' mesh (the smooth version of the mesh) */
+
+ if (is_selected_to_active) {
+ CollectionPointerLink *link;
+ int i = 0;
+
+ /* prepare cage mesh */
+ if (ob_cage) {
+ me_cage = bake_mesh_new_from_object(depsgraph, bmain, scene, ob_cage_eval);
+ if ((me_low->totpoly != me_cage->totpoly) || (me_low->totloop != me_cage->totloop)) {
+ BKE_report(reports,
+ RPT_ERROR,
+ "Invalid cage object, the cage mesh must have the same number "
+ "of faces as the active object");
+ goto cleanup;
+ }
+ }
+ else if (is_cage) {
+ BKE_object_eval_reset(ob_low_eval);
+
+ ModifierData *md = ob_low_eval->modifiers.first;
+ while (md) {
+ ModifierData *md_next = md->next;
+
+ /* Edge Split cannot be applied in the cage,
+ * the cage is supposed to have interpolated normals
+ * between the faces unless the geometry is physically
+ * split. So we create a copy of the low poly mesh without
+ * the eventual edge split.*/
+
+ if (md->type == eModifierType_EdgeSplit) {
+ BLI_remlink(&ob_low_eval->modifiers, md);
+ modifier_free(md);
+ }
+ md = md_next;
+ }
+
+ me_cage = bake_mesh_new_from_object(depsgraph, bmain, scene, ob_low_eval);
+ RE_bake_pixels_populate(me_cage, pixel_array_low, num_pixels, &bake_images, uv_layer);
+ }
+
+ highpoly = MEM_callocN(sizeof(BakeHighPolyData) * tot_highpoly, "bake high poly objects");
+
+ /* populate highpoly array */
+ for (link = selected_objects->first; link; link = link->next) {
+ Object *ob_iter = link->ptr.data;
+
+ if (ob_iter == ob_low)
+ continue;
+
+ /* initialize highpoly_data */
+ highpoly[i].ob = ob_iter;
+ highpoly[i].ob_eval = DEG_get_evaluated_object(depsgraph, ob_iter);
+ highpoly[i].ob_eval->restrictflag &= ~OB_RESTRICT_RENDER;
+ highpoly[i].ob_eval->base_flag |= (BASE_VISIBLE | BASE_ENABLED_RENDER);
+ highpoly[i].me = bake_mesh_new_from_object(depsgraph, bmain, scene, highpoly[i].ob_eval);
+
+ /* lowpoly to highpoly transformation matrix */
+ copy_m4_m4(highpoly[i].obmat, highpoly[i].ob->obmat);
+ invert_m4_m4(highpoly[i].imat, highpoly[i].obmat);
+
+ highpoly[i].is_flip_object = is_negative_m4(highpoly[i].ob->obmat);
+
+ i++;
+ }
+
+ BLI_assert(i == tot_highpoly);
+
+ if (ob_cage != NULL) {
+ ob_cage_eval->restrictflag |= OB_RESTRICT_RENDER;
+ ob_cage_eval->base_flag &= ~(BASE_VISIBLE | BASE_ENABLED_RENDER);
+ }
+ ob_low_eval->restrictflag |= OB_RESTRICT_RENDER;
+ ob_low_eval->base_flag &= ~(BASE_VISIBLE | BASE_ENABLED_RENDER);
+
+ /* populate the pixel arrays with the corresponding face data for each high poly object */
+ if (!RE_bake_pixels_populate_from_objects(me_low,
+ pixel_array_low,
+ pixel_array_high,
+ highpoly,
+ tot_highpoly,
+ num_pixels,
+ ob_cage != NULL,
+ cage_extrusion,
+ ob_low_eval->obmat,
+ (ob_cage ? ob_cage->obmat : ob_low_eval->obmat),
+ me_cage)) {
+ BKE_report(reports, RPT_ERROR, "Error handling selected objects");
+ goto cleanup;
+ }
+
+ /* the baking itself */
+ for (i = 0; i < tot_highpoly; i++) {
+ ok = RE_bake_engine(re,
+ depsgraph,
+ highpoly[i].ob,
+ i,
+ pixel_array_high,
+ num_pixels,
+ depth,
+ pass_type,
+ pass_filter,
+ result);
+ if (!ok) {
+ BKE_reportf(
+ reports, RPT_ERROR, "Error baking from object \"%s\"", highpoly[i].ob->id.name + 2);
+ goto cleanup;
+ }
+ }
+ }
+ else {
+ /* If low poly is not renderable it should have failed long ago. */
+ BLI_assert((ob_low_eval->restrictflag & OB_RESTRICT_RENDER) == 0);
+
+ if (RE_bake_has_engine(re)) {
+ ok = RE_bake_engine(re,
+ depsgraph,
+ ob_low_eval,
+ 0,
+ pixel_array_low,
+ num_pixels,
+ depth,
+ pass_type,
+ pass_filter,
+ result);
+ }
+ else {
+ BKE_report(reports, RPT_ERROR, "Current render engine does not support baking");
+ goto cleanup;
+ }
+ }
+
+ /* normal space conversion
+ * the normals are expected to be in world space, +X +Y +Z */
+ if (ok && pass_type == SCE_PASS_NORMAL) {
+ switch (normal_space) {
+ case R_BAKE_SPACE_WORLD: {
+ /* Cycles internal format */
+ if ((normal_swizzle[0] == R_BAKE_POSX) && (normal_swizzle[1] == R_BAKE_POSY) &&
+ (normal_swizzle[2] == R_BAKE_POSZ)) {
+ break;
+ }
+ else {
+ RE_bake_normal_world_to_world(
+ pixel_array_low, num_pixels, depth, result, normal_swizzle);
+ }
+ break;
+ }
+ case R_BAKE_SPACE_OBJECT: {
+ RE_bake_normal_world_to_object(
+ pixel_array_low, num_pixels, depth, result, ob_low_eval, normal_swizzle);
+ break;
+ }
+ case R_BAKE_SPACE_TANGENT: {
+ if (is_selected_to_active) {
+ RE_bake_normal_world_to_tangent(pixel_array_low,
+ num_pixels,
+ depth,
+ result,
+ me_low,
+ normal_swizzle,
+ ob_low_eval->obmat);
+ }
+ else {
+ /* from multiresolution */
+ Mesh *me_nores = NULL;
+ ModifierData *md = NULL;
+ int mode;
+
+ BKE_object_eval_reset(ob_low_eval);
+ md = modifiers_findByType(ob_low_eval, eModifierType_Multires);
+
+ if (md) {
+ mode = md->mode;
+ md->mode &= ~eModifierMode_Render;
+ }
+
+ /* Evaluate modifiers again. */
+ me_nores = BKE_mesh_new_from_object(depsgraph, bmain, scene, ob_low_eval, true, false);
+ RE_bake_pixels_populate(me_nores, pixel_array_low, num_pixels, &bake_images, uv_layer);
+
+ RE_bake_normal_world_to_tangent(pixel_array_low,
+ num_pixels,
+ depth,
+ result,
+ me_nores,
+ normal_swizzle,
+ ob_low_eval->obmat);
+ BKE_id_free(bmain, me_nores);
+
+ if (md)
+ md->mode = mode;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ if (!ok) {
+ BKE_reportf(reports, RPT_ERROR, "Problem baking object \"%s\"", ob_low->id.name + 2);
+ op_result = OPERATOR_CANCELLED;
+ }
+ else {
+ /* save the results */
+ for (int i = 0; i < bake_images.size; i++) {
+ BakeImage *bk_image = &bake_images.data[i];
+
+ if (is_save_internal) {
+ ok = write_internal_bake_pixels(bk_image->image,
+ pixel_array_low + bk_image->offset,
+ result + bk_image->offset * depth,
+ bk_image->width,
+ bk_image->height,
+ margin,
+ is_clear,
+ is_noncolor);
+
+ /* might be read by UI to set active image for display */
+ bake_update_image(sa, bk_image->image);
+
+ if (!ok) {
+ BKE_reportf(reports,
+ RPT_ERROR,
+ "Problem saving the bake map internally for object \"%s\"",
+ ob_low->id.name + 2);
+ op_result = OPERATOR_CANCELLED;
+ }
+ else {
+ BKE_report(reports,
+ RPT_INFO,
+ "Baking map saved to internal image, save it externally or pack it");
+ op_result = OPERATOR_FINISHED;
+ }
+ }
+ /* save externally */
+ else {
+ BakeData *bake = &scene->r.bake;
+ char name[FILE_MAX];
+
+ BKE_image_path_from_imtype(name,
+ filepath,
+ BKE_main_blendfile_path(bmain),
+ 0,
+ bake->im_format.imtype,
+ true,
+ false,
+ NULL);
+
+ if (is_automatic_name) {
+ BLI_path_suffix(name, FILE_MAX, ob_low->id.name + 2, "_");
+ BLI_path_suffix(name, FILE_MAX, identifier, "_");
+ }
+
+ if (is_split_materials) {
+ if (bk_image->image) {
+ BLI_path_suffix(name, FILE_MAX, bk_image->image->id.name + 2, "_");
+ }
+ else {
+ if (ob_low_eval->mat[i]) {
+ BLI_path_suffix(name, FILE_MAX, ob_low_eval->mat[i]->id.name + 2, "_");
+ }
+ else if (me_low->mat[i]) {
+ BLI_path_suffix(name, FILE_MAX, me_low->mat[i]->id.name + 2, "_");
+ }
+ else {
+ /* if everything else fails, use the material index */
+ char tmp[5];
+ sprintf(tmp, "%d", i % 1000);
+ BLI_path_suffix(name, FILE_MAX, tmp, "_");
+ }
+ }
+ }
+
+ /* save it externally */
+ ok = write_external_bake_pixels(name,
+ pixel_array_low + bk_image->offset,
+ result + bk_image->offset * depth,
+ bk_image->width,
+ bk_image->height,
+ margin,
+ &bake->im_format,
+ is_noncolor);
+
+ if (!ok) {
+ BKE_reportf(reports, RPT_ERROR, "Problem saving baked map in \"%s\"", name);
+ op_result = OPERATOR_CANCELLED;
+ }
+ else {
+ BKE_reportf(reports, RPT_INFO, "Baking map written to \"%s\"", name);
+ op_result = OPERATOR_FINISHED;
+ }
+
+ if (!is_split_materials) {
+ break;
+ }
+ }
+ }
+ }
+
+ if (is_save_internal)
+ refresh_images(&bake_images);
cleanup:
- if (highpoly) {
- int i;
- for (i = 0; i < tot_highpoly; i++) {
- if (highpoly[i].me)
- BKE_id_free(bmain, highpoly[i].me);
- }
- MEM_freeN(highpoly);
- }
+ if (highpoly) {
+ int i;
+ for (i = 0; i < tot_highpoly; i++) {
+ if (highpoly[i].me)
+ BKE_id_free(bmain, highpoly[i].me);
+ }
+ MEM_freeN(highpoly);
+ }
- if (mmd_low)
- mmd_low->flags = mmd_flags_low;
+ if (mmd_low)
+ mmd_low->flags = mmd_flags_low;
- if (pixel_array_low)
- MEM_freeN(pixel_array_low);
+ if (pixel_array_low)
+ MEM_freeN(pixel_array_low);
- if (pixel_array_high)
- MEM_freeN(pixel_array_high);
+ if (pixel_array_high)
+ MEM_freeN(pixel_array_high);
- if (bake_images.data)
- MEM_freeN(bake_images.data);
+ if (bake_images.data)
+ MEM_freeN(bake_images.data);
- if (bake_images.lookup)
- MEM_freeN(bake_images.lookup);
+ if (bake_images.lookup)
+ MEM_freeN(bake_images.lookup);
- if (result)
- MEM_freeN(result);
+ if (result)
+ MEM_freeN(result);
- if (me_low)
- BKE_id_free(bmain, me_low);
+ if (me_low)
+ BKE_id_free(bmain, me_low);
- if (me_cage)
- BKE_id_free(bmain, me_cage);
+ if (me_cage)
+ BKE_id_free(bmain, me_cage);
- DEG_graph_free(depsgraph);
+ DEG_graph_free(depsgraph);
- return op_result;
+ return op_result;
}
static void bake_init_api_data(wmOperator *op, bContext *C, BakeAPIRender *bkr)
{
- bool is_save_internal;
- bScreen *sc = CTX_wm_screen(C);
+ bool is_save_internal;
+ bScreen *sc = CTX_wm_screen(C);
- bkr->ob = CTX_data_active_object(C);
- bkr->main = CTX_data_main(C);
- bkr->view_layer = CTX_data_view_layer(C);
- bkr->scene = CTX_data_scene(C);
- bkr->sa = sc ? BKE_screen_find_big_area(sc, SPACE_IMAGE, 10) : NULL;
+ bkr->ob = CTX_data_active_object(C);
+ bkr->main = CTX_data_main(C);
+ bkr->view_layer = CTX_data_view_layer(C);
+ bkr->scene = CTX_data_scene(C);
+ bkr->sa = sc ? BKE_screen_find_big_area(sc, SPACE_IMAGE, 10) : NULL;
- bkr->pass_type = RNA_enum_get(op->ptr, "type");
- bkr->pass_filter = RNA_enum_get(op->ptr, "pass_filter");
- bkr->margin = RNA_int_get(op->ptr, "margin");
+ bkr->pass_type = RNA_enum_get(op->ptr, "type");
+ bkr->pass_filter = RNA_enum_get(op->ptr, "pass_filter");
+ bkr->margin = RNA_int_get(op->ptr, "margin");
- bkr->save_mode = RNA_enum_get(op->ptr, "save_mode");
- is_save_internal = (bkr->save_mode == R_BAKE_SAVE_INTERNAL);
+ bkr->save_mode = RNA_enum_get(op->ptr, "save_mode");
+ is_save_internal = (bkr->save_mode == R_BAKE_SAVE_INTERNAL);
- bkr->is_clear = RNA_boolean_get(op->ptr, "use_clear");
- bkr->is_split_materials = (!is_save_internal) && RNA_boolean_get(op->ptr, "use_split_materials");
- bkr->is_automatic_name = RNA_boolean_get(op->ptr, "use_automatic_name");
- bkr->is_selected_to_active = RNA_boolean_get(op->ptr, "use_selected_to_active");
- bkr->is_cage = RNA_boolean_get(op->ptr, "use_cage");
- bkr->cage_extrusion = RNA_float_get(op->ptr, "cage_extrusion");
+ bkr->is_clear = RNA_boolean_get(op->ptr, "use_clear");
+ bkr->is_split_materials = (!is_save_internal) && RNA_boolean_get(op->ptr, "use_split_materials");
+ bkr->is_automatic_name = RNA_boolean_get(op->ptr, "use_automatic_name");
+ bkr->is_selected_to_active = RNA_boolean_get(op->ptr, "use_selected_to_active");
+ bkr->is_cage = RNA_boolean_get(op->ptr, "use_cage");
+ bkr->cage_extrusion = RNA_float_get(op->ptr, "cage_extrusion");
- bkr->normal_space = RNA_enum_get(op->ptr, "normal_space");
- bkr->normal_swizzle[0] = RNA_enum_get(op->ptr, "normal_r");
- bkr->normal_swizzle[1] = RNA_enum_get(op->ptr, "normal_g");
- bkr->normal_swizzle[2] = RNA_enum_get(op->ptr, "normal_b");
+ bkr->normal_space = RNA_enum_get(op->ptr, "normal_space");
+ bkr->normal_swizzle[0] = RNA_enum_get(op->ptr, "normal_r");
+ bkr->normal_swizzle[1] = RNA_enum_get(op->ptr, "normal_g");
+ bkr->normal_swizzle[2] = RNA_enum_get(op->ptr, "normal_b");
- bkr->width = RNA_int_get(op->ptr, "width");
- bkr->height = RNA_int_get(op->ptr, "height");
- bkr->identifier = "";
+ bkr->width = RNA_int_get(op->ptr, "width");
+ bkr->height = RNA_int_get(op->ptr, "height");
+ bkr->identifier = "";
- RNA_string_get(op->ptr, "uv_layer", bkr->uv_layer);
+ RNA_string_get(op->ptr, "uv_layer", bkr->uv_layer);
- RNA_string_get(op->ptr, "cage_object", bkr->custom_cage);
+ RNA_string_get(op->ptr, "cage_object", bkr->custom_cage);
- if ((!is_save_internal) && bkr->is_automatic_name) {
- PropertyRNA *prop = RNA_struct_find_property(op->ptr, "type");
- RNA_property_enum_identifier(C, op->ptr, prop, bkr->pass_type, &bkr->identifier);
- }
+ if ((!is_save_internal) && bkr->is_automatic_name) {
+ PropertyRNA *prop = RNA_struct_find_property(op->ptr, "type");
+ RNA_property_enum_identifier(C, op->ptr, prop, bkr->pass_type, &bkr->identifier);
+ }
- CTX_data_selected_objects(C, &bkr->selected_objects);
+ CTX_data_selected_objects(C, &bkr->selected_objects);
- bkr->reports = op->reports;
+ bkr->reports = op->reports;
- bkr->result = OPERATOR_CANCELLED;
+ bkr->result = OPERATOR_CANCELLED;
- bkr->render = RE_NewSceneRender(bkr->scene);
+ bkr->render = RE_NewSceneRender(bkr->scene);
- /* XXX hack to force saving to always be internal. Whether (and how) to support
- * external saving will be addressed later */
- bkr->save_mode = R_BAKE_SAVE_INTERNAL;
+ /* XXX hack to force saving to always be internal. Whether (and how) to support
+ * external saving will be addressed later */
+ bkr->save_mode = R_BAKE_SAVE_INTERNAL;
}
static int bake_exec(bContext *C, wmOperator *op)
{
- Render *re;
- int result = OPERATOR_CANCELLED;
- BakeAPIRender bkr = {NULL};
- Scene *scene = CTX_data_scene(C);
-
- G.is_break = false;
- G.is_rendering = true;
-
- bake_set_props(op, scene);
-
- bake_init_api_data(op, C, &bkr);
- re = bkr.render;
-
- /* setup new render */
- RE_test_break_cb(re, NULL, bake_break);
-
- if (!bake_pass_filter_check(bkr.pass_type, bkr.pass_filter, bkr.reports)) {
- goto finally;
- }
-
- if (!bake_objects_check(bkr.main, bkr.view_layer, bkr.ob, &bkr.selected_objects, bkr.reports, bkr.is_selected_to_active)) {
- goto finally;
- }
-
- if (bkr.is_clear) {
- const bool is_tangent = ((bkr.pass_type == SCE_PASS_NORMAL) && (bkr.normal_space == R_BAKE_SPACE_TANGENT));
- bake_images_clear(bkr.main, is_tangent);
- }
-
- RE_SetReports(re, bkr.reports);
-
- if (bkr.is_selected_to_active) {
- result = bake(
- bkr.render, bkr.main, bkr.scene, bkr.view_layer, bkr.ob, &bkr.selected_objects, bkr.reports,
- bkr.pass_type, bkr.pass_filter, bkr.margin, bkr.save_mode,
- bkr.is_clear, bkr.is_split_materials, bkr.is_automatic_name, true, bkr.is_cage,
- bkr.cage_extrusion, bkr.normal_space, bkr.normal_swizzle,
- bkr.custom_cage, bkr.filepath, bkr.width, bkr.height, bkr.identifier, bkr.sa,
- bkr.uv_layer);
- }
- else {
- CollectionPointerLink *link;
- const bool is_clear = bkr.is_clear && BLI_listbase_is_single(&bkr.selected_objects);
- for (link = bkr.selected_objects.first; link; link = link->next) {
- Object *ob_iter = link->ptr.data;
- result = bake(
- bkr.render, bkr.main, bkr.scene, bkr.view_layer, ob_iter, NULL, bkr.reports,
- bkr.pass_type, bkr.pass_filter, bkr.margin, bkr.save_mode,
- is_clear, bkr.is_split_materials, bkr.is_automatic_name, false, bkr.is_cage,
- bkr.cage_extrusion, bkr.normal_space, bkr.normal_swizzle,
- bkr.custom_cage, bkr.filepath, bkr.width, bkr.height, bkr.identifier, bkr.sa,
- bkr.uv_layer);
- }
- }
-
- RE_SetReports(re, NULL);
-
+ Render *re;
+ int result = OPERATOR_CANCELLED;
+ BakeAPIRender bkr = {NULL};
+ Scene *scene = CTX_data_scene(C);
+
+ G.is_break = false;
+ G.is_rendering = true;
+
+ bake_set_props(op, scene);
+
+ bake_init_api_data(op, C, &bkr);
+ re = bkr.render;
+
+ /* setup new render */
+ RE_test_break_cb(re, NULL, bake_break);
+
+ if (!bake_pass_filter_check(bkr.pass_type, bkr.pass_filter, bkr.reports)) {
+ goto finally;
+ }
+
+ if (!bake_objects_check(bkr.main,
+ bkr.view_layer,
+ bkr.ob,
+ &bkr.selected_objects,
+ bkr.reports,
+ bkr.is_selected_to_active)) {
+ goto finally;
+ }
+
+ if (bkr.is_clear) {
+ const bool is_tangent = ((bkr.pass_type == SCE_PASS_NORMAL) &&
+ (bkr.normal_space == R_BAKE_SPACE_TANGENT));
+ bake_images_clear(bkr.main, is_tangent);
+ }
+
+ RE_SetReports(re, bkr.reports);
+
+ if (bkr.is_selected_to_active) {
+ result = bake(bkr.render,
+ bkr.main,
+ bkr.scene,
+ bkr.view_layer,
+ bkr.ob,
+ &bkr.selected_objects,
+ bkr.reports,
+ bkr.pass_type,
+ bkr.pass_filter,
+ bkr.margin,
+ bkr.save_mode,
+ bkr.is_clear,
+ bkr.is_split_materials,
+ bkr.is_automatic_name,
+ true,
+ bkr.is_cage,
+ bkr.cage_extrusion,
+ bkr.normal_space,
+ bkr.normal_swizzle,
+ bkr.custom_cage,
+ bkr.filepath,
+ bkr.width,
+ bkr.height,
+ bkr.identifier,
+ bkr.sa,
+ bkr.uv_layer);
+ }
+ else {
+ CollectionPointerLink *link;
+ const bool is_clear = bkr.is_clear && BLI_listbase_is_single(&bkr.selected_objects);
+ for (link = bkr.selected_objects.first; link; link = link->next) {
+ Object *ob_iter = link->ptr.data;
+ result = bake(bkr.render,
+ bkr.main,
+ bkr.scene,
+ bkr.view_layer,
+ ob_iter,
+ NULL,
+ bkr.reports,
+ bkr.pass_type,
+ bkr.pass_filter,
+ bkr.margin,
+ bkr.save_mode,
+ is_clear,
+ bkr.is_split_materials,
+ bkr.is_automatic_name,
+ false,
+ bkr.is_cage,
+ bkr.cage_extrusion,
+ bkr.normal_space,
+ bkr.normal_swizzle,
+ bkr.custom_cage,
+ bkr.filepath,
+ bkr.width,
+ bkr.height,
+ bkr.identifier,
+ bkr.sa,
+ bkr.uv_layer);
+ }
+ }
+
+ RE_SetReports(re, NULL);
finally:
- G.is_rendering = false;
- BLI_freelistN(&bkr.selected_objects);
- return result;
+ G.is_rendering = false;
+ BLI_freelistN(&bkr.selected_objects);
+ return result;
}
static void bake_startjob(void *bkv, short *UNUSED(stop), short *do_update, float *progress)
{
- BakeAPIRender *bkr = (BakeAPIRender *)bkv;
-
- /* setup new render */
- bkr->do_update = do_update;
- bkr->progress = progress;
-
- RE_SetReports(bkr->render, bkr->reports);
-
- if (!bake_pass_filter_check(bkr->pass_type, bkr->pass_filter, bkr->reports)) {
- bkr->result = OPERATOR_CANCELLED;
- return;
- }
-
- if (!bake_objects_check(bkr->main, bkr->view_layer, bkr->ob, &bkr->selected_objects, bkr->reports, bkr->is_selected_to_active)) {
- bkr->result = OPERATOR_CANCELLED;
- return;
- }
-
- if (bkr->is_clear) {
- const bool is_tangent = ((bkr->pass_type == SCE_PASS_NORMAL) && (bkr->normal_space == R_BAKE_SPACE_TANGENT));
- bake_images_clear(bkr->main, is_tangent);
- }
-
- if (bkr->is_selected_to_active) {
- bkr->result = bake(
- bkr->render, bkr->main, bkr->scene, bkr->view_layer, bkr->ob, &bkr->selected_objects, bkr->reports,
- bkr->pass_type, bkr->pass_filter, bkr->margin, bkr->save_mode,
- bkr->is_clear, bkr->is_split_materials, bkr->is_automatic_name, true, bkr->is_cage,
- bkr->cage_extrusion, bkr->normal_space, bkr->normal_swizzle,
- bkr->custom_cage, bkr->filepath, bkr->width, bkr->height, bkr->identifier, bkr->sa,
- bkr->uv_layer);
- }
- else {
- CollectionPointerLink *link;
- const bool is_clear = bkr->is_clear && BLI_listbase_is_single(&bkr->selected_objects);
- for (link = bkr->selected_objects.first; link; link = link->next) {
- Object *ob_iter = link->ptr.data;
- bkr->result = bake(
- bkr->render, bkr->main, bkr->scene, bkr->view_layer, ob_iter, NULL, bkr->reports,
- bkr->pass_type, bkr->pass_filter, bkr->margin, bkr->save_mode,
- is_clear, bkr->is_split_materials, bkr->is_automatic_name, false, bkr->is_cage,
- bkr->cage_extrusion, bkr->normal_space, bkr->normal_swizzle,
- bkr->custom_cage, bkr->filepath, bkr->width, bkr->height, bkr->identifier, bkr->sa,
- bkr->uv_layer);
-
- if (bkr->result == OPERATOR_CANCELLED)
- return;
- }
- }
-
- RE_SetReports(bkr->render, NULL);
+ BakeAPIRender *bkr = (BakeAPIRender *)bkv;
+
+ /* setup new render */
+ bkr->do_update = do_update;
+ bkr->progress = progress;
+
+ RE_SetReports(bkr->render, bkr->reports);
+
+ if (!bake_pass_filter_check(bkr->pass_type, bkr->pass_filter, bkr->reports)) {
+ bkr->result = OPERATOR_CANCELLED;
+ return;
+ }
+
+ if (!bake_objects_check(bkr->main,
+ bkr->view_layer,
+ bkr->ob,
+ &bkr->selected_objects,
+ bkr->reports,
+ bkr->is_selected_to_active)) {
+ bkr->result = OPERATOR_CANCELLED;
+ return;
+ }
+
+ if (bkr->is_clear) {
+ const bool is_tangent = ((bkr->pass_type == SCE_PASS_NORMAL) &&
+ (bkr->normal_space == R_BAKE_SPACE_TANGENT));
+ bake_images_clear(bkr->main, is_tangent);
+ }
+
+ if (bkr->is_selected_to_active) {
+ bkr->result = bake(bkr->render,
+ bkr->main,
+ bkr->scene,
+ bkr->view_layer,
+ bkr->ob,
+ &bkr->selected_objects,
+ bkr->reports,
+ bkr->pass_type,
+ bkr->pass_filter,
+ bkr->margin,
+ bkr->save_mode,
+ bkr->is_clear,
+ bkr->is_split_materials,
+ bkr->is_automatic_name,
+ true,
+ bkr->is_cage,
+ bkr->cage_extrusion,
+ bkr->normal_space,
+ bkr->normal_swizzle,
+ bkr->custom_cage,
+ bkr->filepath,
+ bkr->width,
+ bkr->height,
+ bkr->identifier,
+ bkr->sa,
+ bkr->uv_layer);
+ }
+ else {
+ CollectionPointerLink *link;
+ const bool is_clear = bkr->is_clear && BLI_listbase_is_single(&bkr->selected_objects);
+ for (link = bkr->selected_objects.first; link; link = link->next) {
+ Object *ob_iter = link->ptr.data;
+ bkr->result = bake(bkr->render,
+ bkr->main,
+ bkr->scene,
+ bkr->view_layer,
+ ob_iter,
+ NULL,
+ bkr->reports,
+ bkr->pass_type,
+ bkr->pass_filter,
+ bkr->margin,
+ bkr->save_mode,
+ is_clear,
+ bkr->is_split_materials,
+ bkr->is_automatic_name,
+ false,
+ bkr->is_cage,
+ bkr->cage_extrusion,
+ bkr->normal_space,
+ bkr->normal_swizzle,
+ bkr->custom_cage,
+ bkr->filepath,
+ bkr->width,
+ bkr->height,
+ bkr->identifier,
+ bkr->sa,
+ bkr->uv_layer);
+
+ if (bkr->result == OPERATOR_CANCELLED)
+ return;
+ }
+ }
+
+ RE_SetReports(bkr->render, NULL);
}
static void bake_freejob(void *bkv)
{
- BakeAPIRender *bkr = (BakeAPIRender *)bkv;
+ BakeAPIRender *bkr = (BakeAPIRender *)bkv;
- BLI_freelistN(&bkr->selected_objects);
- MEM_freeN(bkr);
+ BLI_freelistN(&bkr->selected_objects);
+ MEM_freeN(bkr);
- G.is_rendering = false;
+ G.is_rendering = false;
}
static void bake_set_props(wmOperator *op, Scene *scene)
{
- PropertyRNA *prop;
- BakeData *bake = &scene->r.bake;
-
- prop = RNA_struct_find_property(op->ptr, "filepath");
- if (!RNA_property_is_set(op->ptr, prop)) {
- RNA_property_string_set(op->ptr, prop, bake->filepath);
- }
-
- prop = RNA_struct_find_property(op->ptr, "width");
- if (!RNA_property_is_set(op->ptr, prop)) {
- RNA_property_int_set(op->ptr, prop, bake->width);
- }
-
- prop = RNA_struct_find_property(op->ptr, "height");
- if (!RNA_property_is_set(op->ptr, prop)) {
- RNA_property_int_set(op->ptr, prop, bake->width);
- }
-
- prop = RNA_struct_find_property(op->ptr, "margin");
- if (!RNA_property_is_set(op->ptr, prop)) {
- RNA_property_int_set(op->ptr, prop, bake->margin);
- }
-
- prop = RNA_struct_find_property(op->ptr, "use_selected_to_active");
- if (!RNA_property_is_set(op->ptr, prop)) {
- RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_TO_ACTIVE) != 0);
- }
-
- prop = RNA_struct_find_property(op->ptr, "cage_extrusion");
- if (!RNA_property_is_set(op->ptr, prop)) {
- RNA_property_float_set(op->ptr, prop, bake->cage_extrusion);
- }
-
- prop = RNA_struct_find_property(op->ptr, "cage_object");
- if (!RNA_property_is_set(op->ptr, prop)) {
- if (bake->cage_object) {
- RNA_property_string_set(op->ptr, prop, bake->cage_object->id.name + 2);
- }
- }
-
- prop = RNA_struct_find_property(op->ptr, "normal_space");
- if (!RNA_property_is_set(op->ptr, prop)) {
- RNA_property_enum_set(op->ptr, prop, bake->normal_space);
- }
-
- prop = RNA_struct_find_property(op->ptr, "normal_r");
- if (!RNA_property_is_set(op->ptr, prop)) {
- RNA_property_enum_set(op->ptr, prop, bake->normal_swizzle[0]);
- }
-
- prop = RNA_struct_find_property(op->ptr, "normal_g");
- if (!RNA_property_is_set(op->ptr, prop)) {
- RNA_property_enum_set(op->ptr, prop, bake->normal_swizzle[1]);
- }
-
- prop = RNA_struct_find_property(op->ptr, "normal_b");
- if (!RNA_property_is_set(op->ptr, prop)) {
- RNA_property_enum_set(op->ptr, prop, bake->normal_swizzle[2]);
- }
-
- prop = RNA_struct_find_property(op->ptr, "save_mode");
- if (!RNA_property_is_set(op->ptr, prop)) {
- RNA_property_enum_set(op->ptr, prop, bake->save_mode);
- }
-
- prop = RNA_struct_find_property(op->ptr, "use_clear");
- if (!RNA_property_is_set(op->ptr, prop)) {
- RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_CLEAR) != 0);
- }
-
- prop = RNA_struct_find_property(op->ptr, "use_cage");
- if (!RNA_property_is_set(op->ptr, prop)) {
- RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_CAGE) != 0);
- }
-
- prop = RNA_struct_find_property(op->ptr, "use_split_materials");
- if (!RNA_property_is_set(op->ptr, prop)) {
- RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_SPLIT_MAT) != 0);
- }
-
- prop = RNA_struct_find_property(op->ptr, "use_automatic_name");
- if (!RNA_property_is_set(op->ptr, prop)) {
- RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_AUTO_NAME) != 0);
- }
-
- prop = RNA_struct_find_property(op->ptr, "pass_filter");
- if (!RNA_property_is_set(op->ptr, prop)) {
- RNA_property_enum_set(op->ptr, prop, bake->pass_filter);
- }
+ PropertyRNA *prop;
+ BakeData *bake = &scene->r.bake;
+
+ prop = RNA_struct_find_property(op->ptr, "filepath");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ RNA_property_string_set(op->ptr, prop, bake->filepath);
+ }
+
+ prop = RNA_struct_find_property(op->ptr, "width");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ RNA_property_int_set(op->ptr, prop, bake->width);
+ }
+
+ prop = RNA_struct_find_property(op->ptr, "height");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ RNA_property_int_set(op->ptr, prop, bake->width);
+ }
+
+ prop = RNA_struct_find_property(op->ptr, "margin");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ RNA_property_int_set(op->ptr, prop, bake->margin);
+ }
+
+ prop = RNA_struct_find_property(op->ptr, "use_selected_to_active");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_TO_ACTIVE) != 0);
+ }
+
+ prop = RNA_struct_find_property(op->ptr, "cage_extrusion");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ RNA_property_float_set(op->ptr, prop, bake->cage_extrusion);
+ }
+
+ prop = RNA_struct_find_property(op->ptr, "cage_object");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ if (bake->cage_object) {
+ RNA_property_string_set(op->ptr, prop, bake->cage_object->id.name + 2);
+ }
+ }
+
+ prop = RNA_struct_find_property(op->ptr, "normal_space");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ RNA_property_enum_set(op->ptr, prop, bake->normal_space);
+ }
+
+ prop = RNA_struct_find_property(op->ptr, "normal_r");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ RNA_property_enum_set(op->ptr, prop, bake->normal_swizzle[0]);
+ }
+
+ prop = RNA_struct_find_property(op->ptr, "normal_g");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ RNA_property_enum_set(op->ptr, prop, bake->normal_swizzle[1]);
+ }
+
+ prop = RNA_struct_find_property(op->ptr, "normal_b");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ RNA_property_enum_set(op->ptr, prop, bake->normal_swizzle[2]);
+ }
+
+ prop = RNA_struct_find_property(op->ptr, "save_mode");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ RNA_property_enum_set(op->ptr, prop, bake->save_mode);
+ }
+
+ prop = RNA_struct_find_property(op->ptr, "use_clear");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_CLEAR) != 0);
+ }
+
+ prop = RNA_struct_find_property(op->ptr, "use_cage");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_CAGE) != 0);
+ }
+
+ prop = RNA_struct_find_property(op->ptr, "use_split_materials");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_SPLIT_MAT) != 0);
+ }
+
+ prop = RNA_struct_find_property(op->ptr, "use_automatic_name");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_AUTO_NAME) != 0);
+ }
+
+ prop = RNA_struct_find_property(op->ptr, "pass_filter");
+ if (!RNA_property_is_set(op->ptr, prop)) {
+ RNA_property_enum_set(op->ptr, prop, bake->pass_filter);
+ }
}
static int bake_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- wmJob *wm_job;
- BakeAPIRender *bkr;
- Render *re;
- Scene *scene = CTX_data_scene(C);
+ wmJob *wm_job;
+ BakeAPIRender *bkr;
+ Render *re;
+ Scene *scene = CTX_data_scene(C);
- bake_set_props(op, scene);
+ bake_set_props(op, scene);
- /* only one render job at a time */
- if (WM_jobs_test(CTX_wm_manager(C), scene, WM_JOB_TYPE_OBJECT_BAKE))
- return OPERATOR_CANCELLED;
+ /* only one render job at a time */
+ if (WM_jobs_test(CTX_wm_manager(C), scene, WM_JOB_TYPE_OBJECT_BAKE))
+ return OPERATOR_CANCELLED;
- bkr = MEM_mallocN(sizeof(BakeAPIRender), "render bake");
+ bkr = MEM_mallocN(sizeof(BakeAPIRender), "render bake");
- /* init bake render */
- bake_init_api_data(op, C, bkr);
- re = bkr->render;
+ /* init bake render */
+ bake_init_api_data(op, C, bkr);
+ re = bkr->render;
- /* setup new render */
- RE_test_break_cb(re, NULL, bake_break);
- RE_progress_cb(re, bkr, bake_progress_update);
+ /* setup new render */
+ RE_test_break_cb(re, NULL, bake_break);
+ RE_progress_cb(re, bkr, bake_progress_update);
- /* setup job */
- wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Texture Bake",
- WM_JOB_EXCL_RENDER | WM_JOB_PRIORITY | WM_JOB_PROGRESS, WM_JOB_TYPE_OBJECT_BAKE);
- WM_jobs_customdata_set(wm_job, bkr, bake_freejob);
- WM_jobs_timer(wm_job, 0.5, NC_IMAGE, 0); /* TODO - only draw bake image, can we enforce this */
- WM_jobs_callbacks(wm_job, bake_startjob, NULL, NULL, NULL);
+ /* setup job */
+ wm_job = WM_jobs_get(CTX_wm_manager(C),
+ CTX_wm_window(C),
+ scene,
+ "Texture Bake",
+ WM_JOB_EXCL_RENDER | WM_JOB_PRIORITY | WM_JOB_PROGRESS,
+ WM_JOB_TYPE_OBJECT_BAKE);
+ WM_jobs_customdata_set(wm_job, bkr, bake_freejob);
+ WM_jobs_timer(wm_job, 0.5, NC_IMAGE, 0); /* TODO - only draw bake image, can we enforce this */
+ WM_jobs_callbacks(wm_job, bake_startjob, NULL, NULL, NULL);
- G.is_break = false;
- G.is_rendering = true;
+ G.is_break = false;
+ G.is_rendering = true;
- WM_jobs_start(CTX_wm_manager(C), wm_job);
+ WM_jobs_start(CTX_wm_manager(C), wm_job);
- WM_cursor_wait(0);
+ WM_cursor_wait(0);
- /* add modal handler for ESC */
- WM_event_add_modal_handler(C, op);
+ /* add modal handler for ESC */
+ WM_event_add_modal_handler(C, op);
- WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, scene);
- return OPERATOR_RUNNING_MODAL;
+ WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, scene);
+ return OPERATOR_RUNNING_MODAL;
}
void OBJECT_OT_bake(wmOperatorType *ot)
{
- PropertyRNA *prop;
-
- /* identifiers */
- ot->name = "Bake";
- ot->description = "Bake image textures of selected objects";
- ot->idname = "OBJECT_OT_bake";
-
- /* api callbacks */
- ot->exec = bake_exec;
- ot->modal = bake_modal;
- ot->invoke = bake_invoke;
- ot->poll = ED_operator_object_active_editable_mesh;
-
- RNA_def_enum(ot->srna, "type", rna_enum_bake_pass_type_items, SCE_PASS_COMBINED, "Type",
- "Type of pass to bake, some of them may not be supported by the current render engine");
- prop = RNA_def_enum(ot->srna, "pass_filter", rna_enum_bake_pass_filter_type_items, R_BAKE_PASS_FILTER_NONE, "Pass Filter",
- "Filter to combined, diffuse, glossy, transmission and subsurface passes");
- RNA_def_property_flag(prop, PROP_ENUM_FLAG);
- RNA_def_string_file_path(ot->srna, "filepath", NULL, FILE_MAX, "File Path",
- "Image filepath to use when saving externally");
- RNA_def_int(ot->srna, "width", 512, 1, INT_MAX, "Width",
- "Horizontal dimension of the baking map (external only)", 64, 4096);
- RNA_def_int(ot->srna, "height", 512, 1, INT_MAX, "Height",
- "Vertical dimension of the baking map (external only)", 64, 4096);
- RNA_def_int(ot->srna, "margin", 16, 0, INT_MAX, "Margin",
- "Extends the baked result as a post process filter", 0, 64);
- RNA_def_boolean(ot->srna, "use_selected_to_active", false, "Selected to Active",
- "Bake shading on the surface of selected objects to the active object");
- RNA_def_float(ot->srna, "cage_extrusion", 0.0f, 0.0f, FLT_MAX, "Cage Extrusion",
- "Distance to use for the inward ray cast when using selected to active", 0.0f, 1.0f);
- RNA_def_string(ot->srna, "cage_object", NULL, MAX_NAME, "Cage Object",
- "Object to use as cage, instead of calculating the cage from the active object with cage extrusion");
- RNA_def_enum(ot->srna, "normal_space", rna_enum_normal_space_items, R_BAKE_SPACE_TANGENT, "Normal Space",
- "Choose normal space for baking");
- RNA_def_enum(ot->srna, "normal_r", rna_enum_normal_swizzle_items, R_BAKE_POSX, "R", "Axis to bake in red channel");
- RNA_def_enum(ot->srna, "normal_g", rna_enum_normal_swizzle_items, R_BAKE_POSY, "G", "Axis to bake in green channel");
- RNA_def_enum(ot->srna, "normal_b", rna_enum_normal_swizzle_items, R_BAKE_POSZ, "B", "Axis to bake in blue channel");
- RNA_def_enum(ot->srna, "save_mode", rna_enum_bake_save_mode_items, R_BAKE_SAVE_INTERNAL, "Save Mode",
- "Choose how to save the baking map");
- RNA_def_boolean(ot->srna, "use_clear", false, "Clear",
- "Clear Images before baking (only for internal saving)");
- RNA_def_boolean(ot->srna, "use_cage", false, "Cage",
- "Cast rays to active object from a cage");
- RNA_def_boolean(ot->srna, "use_split_materials", false, "Split Materials",
- "Split baked maps per material, using material name in output file (external only)");
- RNA_def_boolean(ot->srna, "use_automatic_name", false, "Automatic Name",
- "Automatically name the output file with the pass type");
- RNA_def_string(ot->srna, "uv_layer", NULL, MAX_CUSTOMDATA_LAYER_NAME, "UV Layer", "UV layer to override active");
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Bake";
+ ot->description = "Bake image textures of selected objects";
+ ot->idname = "OBJECT_OT_bake";
+
+ /* api callbacks */
+ ot->exec = bake_exec;
+ ot->modal = bake_modal;
+ ot->invoke = bake_invoke;
+ ot->poll = ED_operator_object_active_editable_mesh;
+
+ RNA_def_enum(
+ ot->srna,
+ "type",
+ rna_enum_bake_pass_type_items,
+ SCE_PASS_COMBINED,
+ "Type",
+ "Type of pass to bake, some of them may not be supported by the current render engine");
+ prop = RNA_def_enum(ot->srna,
+ "pass_filter",
+ rna_enum_bake_pass_filter_type_items,
+ R_BAKE_PASS_FILTER_NONE,
+ "Pass Filter",
+ "Filter to combined, diffuse, glossy, transmission and subsurface passes");
+ RNA_def_property_flag(prop, PROP_ENUM_FLAG);
+ RNA_def_string_file_path(ot->srna,
+ "filepath",
+ NULL,
+ FILE_MAX,
+ "File Path",
+ "Image filepath to use when saving externally");
+ RNA_def_int(ot->srna,
+ "width",
+ 512,
+ 1,
+ INT_MAX,
+ "Width",
+ "Horizontal dimension of the baking map (external only)",
+ 64,
+ 4096);
+ RNA_def_int(ot->srna,
+ "height",
+ 512,
+ 1,
+ INT_MAX,
+ "Height",
+ "Vertical dimension of the baking map (external only)",
+ 64,
+ 4096);
+ RNA_def_int(ot->srna,
+ "margin",
+ 16,
+ 0,
+ INT_MAX,
+ "Margin",
+ "Extends the baked result as a post process filter",
+ 0,
+ 64);
+ RNA_def_boolean(ot->srna,
+ "use_selected_to_active",
+ false,
+ "Selected to Active",
+ "Bake shading on the surface of selected objects to the active object");
+ RNA_def_float(ot->srna,
+ "cage_extrusion",
+ 0.0f,
+ 0.0f,
+ FLT_MAX,
+ "Cage Extrusion",
+ "Distance to use for the inward ray cast when using selected to active",
+ 0.0f,
+ 1.0f);
+ RNA_def_string(ot->srna,
+ "cage_object",
+ NULL,
+ MAX_NAME,
+ "Cage Object",
+ "Object to use as cage, instead of calculating the cage from the active object "
+ "with cage extrusion");
+ RNA_def_enum(ot->srna,
+ "normal_space",
+ rna_enum_normal_space_items,
+ R_BAKE_SPACE_TANGENT,
+ "Normal Space",
+ "Choose normal space for baking");
+ RNA_def_enum(ot->srna,
+ "normal_r",
+ rna_enum_normal_swizzle_items,
+ R_BAKE_POSX,
+ "R",
+ "Axis to bake in red channel");
+ RNA_def_enum(ot->srna,
+ "normal_g",
+ rna_enum_normal_swizzle_items,
+ R_BAKE_POSY,
+ "G",
+ "Axis to bake in green channel");
+ RNA_def_enum(ot->srna,
+ "normal_b",
+ rna_enum_normal_swizzle_items,
+ R_BAKE_POSZ,
+ "B",
+ "Axis to bake in blue channel");
+ RNA_def_enum(ot->srna,
+ "save_mode",
+ rna_enum_bake_save_mode_items,
+ R_BAKE_SAVE_INTERNAL,
+ "Save Mode",
+ "Choose how to save the baking map");
+ RNA_def_boolean(ot->srna,
+ "use_clear",
+ false,
+ "Clear",
+ "Clear Images before baking (only for internal saving)");
+ RNA_def_boolean(ot->srna, "use_cage", false, "Cage", "Cast rays to active object from a cage");
+ RNA_def_boolean(
+ ot->srna,
+ "use_split_materials",
+ false,
+ "Split Materials",
+ "Split baked maps per material, using material name in output file (external only)");
+ RNA_def_boolean(ot->srna,
+ "use_automatic_name",
+ false,
+ "Automatic Name",
+ "Automatically name the output file with the pass type");
+ RNA_def_string(ot->srna,
+ "uv_layer",
+ NULL,
+ MAX_CUSTOMDATA_LAYER_NAME,
+ "UV Layer",
+ "UV layer to override active");
}