[Bf-blender-cvs] [0b4fae7a51f] master: Cleanup: refactoring of bake code in preparation of vertex color baking
Brecht Van Lommel
noreply at git.blender.org
Thu Dec 24 12:41:48 CET 2020
Commit: 0b4fae7a51fb869c27d9407b8b5eadeb418d0bfc
Author: Brecht Van Lommel
Date: Wed Dec 23 16:39:36 2020 +0100
Branches: master
https://developer.blender.org/rB0b4fae7a51fb869c27d9407b8b5eadeb418d0bfc
Cleanup: refactoring of bake code in preparation of vertex color baking
Split of internal/external image bake target code off into smaller functions and
refactor associated data structures for clarity. Designed so that a vertex color
bake target is easy to fit in.
Also avoid passing in a huge number of arguments into the main baking function,
pass a struct instead.
===================================================================
M source/blender/editors/object/object_bake_api.c
M source/blender/render/RE_bake.h
M source/blender/render/intern/bake.c
M source/blender/render/intern/engine.c
===================================================================
diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c
index 19097d95743..2dba883d866 100644
--- a/source/blender/editors/object/object_bake_api.c
+++ b/source/blender/editors/object/object_bake_api.c
@@ -25,6 +25,7 @@
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "RNA_access.h"
@@ -74,22 +75,19 @@
static void bake_set_props(wmOperator *op, Scene *scene);
typedef struct BakeAPIRender {
- Object *ob;
+ /* Data to work on. */
Main *main;
Scene *scene;
ViewLayer *view_layer;
- ReportList *reports;
+ Object *ob;
ListBase selected_objects;
+ /* Baking settings. */
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;
@@ -100,21 +98,26 @@ typedef struct BakeAPIRender {
char uv_layer[MAX_CUSTOMDATA_LAYER_NAME];
char custom_cage[MAX_NAME];
- char filepath[FILE_MAX];
+ /* Settings for external image saving. */
+ eBakeSaveMode save_mode;
+ char filepath[FILE_MAX];
+ bool is_automatic_name;
+ bool is_split_materials;
int width;
int height;
const char *identifier;
- int result;
- bool ready;
-
- /* callbacks */
+ /* Baking render session. */
Render *render;
+
+ /* Progress Callbacks. */
float *progress;
short *do_update;
- /* for redrawing */
+ /* Operator state. */
+ ReportList *reports;
+ int result;
ScrArea *area;
} BakeAPIRender;
@@ -299,15 +302,18 @@ static bool write_internal_bake_pixels(Image *image,
}
/* force OpenGL reload */
-static void refresh_images(BakeImages *bake_images)
+static void bake_targets_refresh(BakeTargets *targets)
{
- for (int i = 0; i < bake_images->size; i++) {
- Image *ima = bake_images->data[i].image;
- LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
- if (tile->ok == IMA_OK_LOADED) {
- BKE_image_free_gputextures(ima);
- DEG_id_tag_update(&ima->id, 0);
- break;
+ for (int i = 0; i < targets->num_images; i++) {
+ Image *ima = targets->images[i].image;
+
+ if (ima) {
+ LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
+ if (tile->ok == IMA_OK_LOADED) {
+ BKE_image_free_gputextures(ima);
+ DEG_id_tag_update(&ima->id, 0);
+ break;
+ }
}
}
}
@@ -498,6 +504,7 @@ static bool bake_object_check(ViewLayer *view_layer, Object *ob, ReportList *rep
image->id.tag |= LIB_TAG_DOIT;
}
+
return true;
}
@@ -622,7 +629,7 @@ static bool bake_objects_check(Main *bmain,
}
/* 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)
+static void bake_targets_clear(Main *bmain, const bool is_tangent)
{
Image *image;
for (image = bmain->images.first; image; image = image->id.next) {
@@ -632,110 +639,337 @@ static void bake_images_clear(Main *bmain, const bool is_tangent)
}
}
-static void build_image_lookup(Main *bmain, Object *ob, BakeImages *bake_images)
+/* create new mesh with edit mode changes and modifiers applied */
+static Mesh *bake_mesh_new_from_object(Object *object)
{
- const int tot_mat = ob->totcol;
- int tot_images = 0;
+ Mesh *me = BKE_mesh_new_from_object(NULL, object, false);
- /* 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 (me->flag & ME_AUTOSMOOTH) {
+ BKE_mesh_split_faces(me, true);
+ }
+
+ return me;
+}
+
+/* Image Bake Targets */
+
+static bool bake_targets_init_image_textures(const BakeAPIRender *bkr,
+ BakeTargets *targets,
+ Object *ob,
+ ReportList *reports)
+{
+ int num_materials = ob->totcol;
+
+ if (num_materials == 0) {
+ if (bkr->save_mode == R_BAKE_SAVE_INTERNAL) {
+ BKE_report(
+ reports, RPT_ERROR, "No active image found, add a material or bake to an external file");
+ return false;
+ }
+ else if (bkr->is_split_materials) {
+ BKE_report(
+ reports,
+ RPT_ERROR,
+ "No active image found, add a material or bake without the Split Materials option");
+ return false;
+ }
+ }
+
+ /* Overallocate in case there is more materials than images. */
+ targets->num_materials = num_materials;
+ targets->images = MEM_callocN(sizeof(BakeImage) * targets->num_materials, "BakeTargets.images");
+ targets->material_to_image = MEM_callocN(sizeof(int) * targets->num_materials,
+ "BakeTargets.material_to_image");
- for (int i = 0; i < tot_mat; i++) {
+ /* Error handling and tag (in case multiple materials share the same image). */
+ BKE_main_id_tag_idcode(bkr->main, ID_IM, LIB_TAG_DOIT, false);
+
+ for (int i = 0; i < num_materials; 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;
+ targets->material_to_image[i] = -1;
}
else if (image->id.tag & LIB_TAG_DOIT) {
for (int j = 0; j < i; j++) {
- if (bake_images->data[j].image == image) {
- bake_images->lookup[i] = j;
+ if (targets->images[j].image == image) {
+ targets->material_to_image[i] = j;
break;
}
}
}
else {
- bake_images->lookup[i] = tot_images;
- bake_images->data[tot_images].image = image;
+ targets->material_to_image[i] = targets->num_images;
+ targets->images[targets->num_images].image = image;
image->id.tag |= LIB_TAG_DOIT;
- tot_images++;
+ targets->num_images++;
}
}
- bake_images->size = tot_images;
+ return true;
}
-/*
- * returns the total number of pixels
- */
-static size_t init_internal_images(BakeImages *bake_images, ReportList *reports)
+static bool bake_targets_init_internal(const BakeAPIRender *bkr,
+ BakeTargets *targets,
+ Object *ob,
+ ReportList *reports)
{
- size_t tot_size = 0;
+ if (!bake_targets_init_image_textures(bkr, targets, ob, reports)) {
+ return false;
+ }
- for (int i = 0; i < bake_images->size; i++) {
- BakeImage *bk_image = &bake_images->data[i];
+ /* Saving to image datablocks. */
+ for (int i = 0; i < targets->num_images; i++) {
+ BakeImage *bk_image = &targets->images[i];
void *lock;
ImBuf *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;
+ bk_image->offset = targets->num_pixels;
- tot_size += (size_t)ibuf->x * (size_t)ibuf->y;
+ targets->num_pixels += (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;
+ return false;
}
BKE_image_release_ibuf(bk_image->image, ibuf, lock);
}
- return tot_size;
+
+ return true;
}
-/* create new mesh with edit mode changes and modifiers applied */
-static Mesh *bake_mesh_new_from_object(Object *object)
+static bool bake_targets_output_internal(const BakeAPIRender *bkr,
+ BakeTargets *targets,
+ Object *ob,
+ BakePixel *pixel_array,
+ ReportList *reports)
{
- Mesh *me = BKE_mesh_new_from_object(NULL, object, false);
+ bool all_ok = true;
+
+ for (int i = 0; i < targets->num_images; i++) {
+ BakeImage *bk_image = &targets->images[i];
+ const bool ok = write_internal_bake_pixels(bk_image->image,
+ pixel_array + bk_image->offset,
+ targets->result +
+ bk_image->offset * targets->num_channels,
+ bk_image->width,
+ bk_image->height,
+ bkr->margin,
+ bkr->is_clear,
+ targets->is_noncolor);
+
+ /* might be read by UI to set active image for display */
+ bake_update_image(bkr->area, bk_image->image);
+
+ if (!ok) {
+ BKE_reportf(reports,
+ RPT_ERROR,
+ "Problem saving the bake map internally for object \"%s\"",
+ ob->id.name + 2);
+ all_ok = false;
+ }
+ else {
+ BKE_report(
+ reports, RPT_INFO, "Baking map saved to internal image, save it externally or pack it");
+ }
+ }
- if (me->flag & ME_AUTOSMOOTH) {
- BKE_mesh_split_faces(me, true);
+ return all_ok;
+}
+
+static bool bake_targets_init_external(const BakeAPIRender *bkr,
+ BakeTargets *targets,
+ Object *ob,
+ ReportList *reports)
+{
+ if (!bake_targets_init_image_textures(bkr, targets, ob, reports)) {
+ return false;
}
- return me;
+ /* Saving to disk. */
+ for (int i = 0; i < targets->num_images; i++) {
+ BakeImage *bk_image = &targets->images[i];
+
+ bk_image->width = bkr->width;
+ bk_image->height = bkr->height;
+ bk_image->offset = targets->num_pixels;
+ bk_image->image = NULL;
+
+ targets->num_pixels += (size_t)bkr->width * (size_t)bkr->height;
+
+ if (!bkr->is_split_materials) {
+ break;
+ }
+ }
+
+ if (!bkr->is_split_materials) {
+ /* saving a single image */
+ for (int i = 0; i < targets->num_materials;
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list