[Bf-blender-cvs] [2a9efa4] master: Bake-API: Support for batch baking
Dalai Felinto
noreply at git.blender.org
Fri May 30 03:57:10 CEST 2014
Commit: 2a9efa4e5185275d6d16c8348decd6d6b52afab6
Author: Dalai Felinto
Date: Thu May 29 22:54:57 2014 -0300
https://developer.blender.org/rB2a9efa4e5185275d6d16c8348decd6d6b52afab6
Bake-API: Support for batch baking
When "Selected to Active" is not on, we bake all the selected objects.
This is the same behaviour we have for Blender Internal.
Dev note: I moved most of the validation tests to outside the bake()
routine so the function can be called in loop.
Reviewers: campbellbarton
Differential Revision: https://developer.blender.org/D560
===================================================================
M source/blender/editors/object/object_bake_api.c
M source/blender/render/extern/include/RE_bake.h
M source/blender/render/intern/source/bake_api.c
===================================================================
diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c
index e349ad8..8baea24 100644
--- a/source/blender/editors/object/object_bake_api.c
+++ b/source/blender/editors/object/object_bake_api.c
@@ -288,34 +288,138 @@ static bool is_noncolor_pass(ScenePassType pass_type)
SCE_PASS_INDEXMA);
}
-static bool build_image_lookup(Main *bmain, Object *ob, BakeImages *bake_images, ReportList *reports)
+/* if all is good tag image and return true */
+static bool bake_object_check(Object *ob, ReportList *reports)
{
- const int tot_mat = ob->totcol;
- int i, j;
- int tot_images = 0;
+ Image *image;
+ void *lock;
+ int i;
- /* error handling and tag (in case multiple materials share the same image) */
- BKE_main_id_tag_idcode(bmain, ID_IM, 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;
- for (i = 0; i < tot_mat; i++) {
- Image *image;
+ const int pidx = CustomData_get_active_layer_index(&me->pdata, CD_MTEXPOLY);
+ const int lidx = CustomData_get_active_layer_index(&me->ldata, CD_MLOOPUV);
+ const int fidx = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE);
+
+ if ((pidx == -1) && (lidx == -1) && (fidx == -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++) {
ED_object_get_active_image(ob, i + 1, &image, NULL, NULL);
- if (!image) {
+ if (image) {
+ ImBuf *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 {
if (ob->mat[i]) {
BKE_reportf(reports, RPT_ERROR,
- "No active image found in material %d (%s)", i, ob->mat[i]->id.name + 2);
+ "No active image found in material \"%s\" (%d) for object \"%s\"",
+ ob->mat[i]->id.name + 2, i, ob->id.name + 2);
}
else if (((Mesh *) ob->data)->mat[i]) {
BKE_reportf(reports, RPT_ERROR,
- "No active image found in material %d (%s)", i, ((Mesh *) ob->data)->mat[i]->id.name + 2);
+ "No active image found in material \"%s\" (%d) for object \"%s\"",
+ ((Mesh *) ob->data)->mat[i]->id.name + 2, i, ob->id.name + 2);
}
else {
BKE_reportf(reports, RPT_ERROR,
- "No active image found in material %d", i);
+ "No active image found in material (%d) for object \"%s\"",
+ i, ob->id.name + 2);
+ }
+ return false;
+ }
+
+ image->id.flag |= LIB_DOIT;
+ }
+ return true;
+}
+
+/* before even getting in the bake function we check for some basic errors */
+static bool bake_objects_check(Main *bmain, Object *ob, ListBase *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, false);
+
+ if (is_selected_to_active) {
+ int tot_objects = 0;
+
+ if (!bake_object_check(ob, reports))
+ return false;
+
+ for (link = objects->first; link; link = link->next) {
+ Object *ob_iter = (Object *)link->ptr.data;
+
+ if (ob_iter == ob)
+ continue;
+
+ if (ob_iter->type != OB_MESH) {
+ BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is not a mesh", 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 {
+ for (link = objects->first; link; link = link->next) {
+ if (!bake_object_check(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->image.first; image; image = image->id.next) {
+ if ((image->id.flag & LIB_DOIT) != 0) {
+ RE_bake_ibuf_clear(image, is_tangent);
+ }
+ }
+}
+
+static bool 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, false);
+
+ for (i = 0; i < tot_mat; i++) {
+ Image *image;
+ ED_object_get_active_image(ob, i + 1, &image, NULL, NULL);
if ((image->id.flag & LIB_DOIT)) {
for (j = 0; j < i; j++) {
@@ -384,7 +488,7 @@ typedef struct BakeAPIRender {
bool is_clear;
bool is_split_materials;
bool is_automatic_name;
- bool use_selected_to_active;
+ bool is_selected_to_active;
float cage_extrusion;
int normal_space;
@@ -408,7 +512,7 @@ static int bake(
Main *bmain, Scene *scene, Object *ob_low, ListBase *selected_objects, ReportList *reports,
const ScenePassType pass_type, const int margin,
const BakeSaveMode save_mode, const bool is_clear, const bool is_split_materials,
- const bool is_automatic_name, const bool use_selected_to_active,
+ const bool is_automatic_name, const bool is_selected_to_active,
const float cage_extrusion, const int normal_space, const BakeNormalSwizzle normal_swizzle[],
const char *custom_cage, const char *filepath, const int width, const int height,
const char *identifier, ScrArea *sa)
@@ -418,7 +522,7 @@ static int bake(
Object *ob_cage = NULL;
- BakeHighPolyData *highpoly;
+ BakeHighPolyData *highpoly = NULL;
int tot_highpoly;
char restrict_flag_low = ob_low->restrictflag;
@@ -435,9 +539,6 @@ static int bake(
const bool is_noncolor = is_noncolor_pass(pass_type);
const int depth = RE_pass_depth(pass_type);
- bool is_highpoly = false;
- bool is_tangent;
-
BakeImages bake_images = {NULL};
int num_pixels;
@@ -447,15 +548,8 @@ static int bake(
re = RE_NewRender(scene->id.name);
RE_SetReports(re, NULL);
- is_tangent = pass_type == SCE_PASS_NORMAL && normal_space == R_BAKE_SPACE_TANGENT;
tot_materials = ob_low->totcol;
- /* ensure active uv */
- if (CustomData_get_active_layer(&((Mesh *)ob_low->data)->pdata, CD_MTEXPOLY) == -1) {
- BKE_report(reports, RPT_ERROR, "No active UV layer found in the active object");
- goto cleanup;
- }
-
if (tot_materials == 0) {
if (is_save_internal) {
BKE_report(reports, RPT_ERROR,
@@ -479,7 +573,7 @@ static int bake(
bake_images.data = MEM_callocN(sizeof(BakeImage) * tot_materials, "bake images dimensions (width, height, offset)");
bake_images.lookup = MEM_callocN(sizeof(int) * tot_materials, "bake images lookup (from material to BakeImage)");
- if (!build_image_lookup(bmain, ob_low, &bake_images, reports))
+ if (!build_image_lookup(bmain, ob_low, &bake_images))
goto cleanup;
if (is_save_internal) {
@@ -488,10 +582,6 @@ static int bake(
if (num_pixels == 0) {
goto cleanup;
}
-
- if (is_clear) {
- RE_bake_ibuf_clear(&bake_images, is_tangent);
- }
}
else {
/* when saving extenally always use the size specified in the UI */
@@ -512,7 +602,7 @@ static int bake(
}
}
- if (use_selected_to_active) {
+ if (is_selected_to_active) {
CollectionPointerLink *link;
tot_highpoly = 0;
@@ -525,27 +615,19 @@ static int bake(
tot_highpoly ++;
}
- if (tot_highpoly == 0) {
- BKE_report(reports, RPT_ERROR, "No valid selected objects");
- goto cleanup;
- }
- else {
- is_highpoly = true;
- }
- }
-
- if (custom_cage[0] != '\0') {
- ob_cage = BLI_findstring(&bmain->object, custom_cage, offsetof(ID, name) + 2);
+ if (custom_cage[0] != '\0') {
+ ob_cage = BLI_findstring(&bmain->object, custom_cage, offsetof(ID, name) + 2);
- /* TODO check if cage object has the same topology (num of triangles and a valid UV) */
- if (ob_cage == NULL || ob_cage->type != OB_MESH) {
- BKE_report(reports, RPT_ERROR, "No valid cage object");
- op_result = OPERATOR_CANCELLED;
+ /* TODO check if cage object has the same topology (num of triangles and a valid UV) */
+ if (ob_cage == NULL || ob_cage->type != OB_MESH) {
+ BKE_report(reports, RPT_ERROR, "No valid cage object");
+ op_result = OPERATOR_CANCELLED;
- goto cleanup;
- }
- else {
- restrict_flag_cage = ob_cage->restrictflag;
+ goto cleanup;
+ }
+ else {
+ restrict_flag_cage = ob_cage->restrictflag;
+ }
}
}
@@ -559,7 +641,7 @@ static int bake(
pixel_array_low = MEM_callocN(sizeof(BakePixel) * num_pixels, "bake pixels low poly");
result = MEM_callocN(sizeof(float) * depth * num_pixels, "bake return pixels");
- if (is_highpoly) {
+ if (is_selected_to_active) {
CollectionPointerLink *link;
ModifierData *md, *nmd;
ListBase modifiers_tmp, modifiers_original;
@@ -697,7 +779,7 @@ static int bake(
/* normal space conversion
* the normals are expected to be in world space, +X +Y +Z */
- if (pass_type == SCE_PASS_NORMAL) {
+ if (ok && pass_type == SCE_PASS_NORMAL) {
switch (normal_space) {
case R_BAKE_SPACE_WORLD:
{
@@ -720,7 +802,7 @@ static int bake(
}
case R_BAKE_SPACE_TANGENT:
{
- if (is_highpoly) {
+ if (is_selected_to_active) {
RE_bake_normal_world_to_tangent(pixel_array_low, num_pixels, depth, result, me_low, normal_swizzle, ob_low->obmat);
}
else {
@@ -753,7 +835,7 @@ static int bake(
}
if (!ok) {
- BKE_report(reports, RPT_ERROR, "Problem baking object map");
+ BKE_reportf(reports, RPT_ERROR, "Problem baking object \"%s\"", ob_low->id.name + 2);
op_result = OPERATOR_CANCELLED;
}
else {
@@ -773,9 +855,8 @@ static int bake(
bake_update_image(sa, bk_image->image);
if (!ok) {
- BKE_report(reports, RPT_ERROR,
- "Problem saving the bake map internally, "
- "make sure there is a Texture
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list