[Bf-blender-cvs] [44a1d84] bake-cycles: Cycles-Bake: better support for multiple materials referring to the same image
Dalai Felinto
noreply at git.blender.org
Sat Apr 26 18:22:08 CEST 2014
Commit: 44a1d847cc8953d7be40617b61a76f6f065981c5
Author: Dalai Felinto
Date: Sat Apr 26 13:21:43 2014 -0300
https://developer.blender.org/rB44a1d847cc8953d7be40617b61a76f6f065981c5
Cycles-Bake: better support for multiple materials referring to the same image
This brings performance gain, as well as a bugfix where the margin would advance over one of the images
===================================================================
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 077e8e8..7efb76a 100644
--- a/source/blender/editors/object/object_bake_api.c
+++ b/source/blender/editors/object/object_bake_api.c
@@ -263,17 +263,17 @@ static bool is_data_pass(ScenePassType pass_type)
SCE_PASS_INDEXMA);
}
-static int get_save_internal_status(wmOperator *op, Object *ob, BakeImage *images)
+static bool build_image_lookup(wmOperator *op, Main *bmain, Object *ob, BakeImages *images)
{
- int i;
+ int i, j;
+ int tot_images = 0;
int tot_mat = ob->totcol;
- int tot_size = 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++) {
- ImBuf *ibuf;
- void *lock;
Image *image;
-
ED_object_get_active_image(ob, i + 1, &image, NULL, NULL);
if (!image) {
@@ -289,31 +289,60 @@ static int get_save_internal_status(wmOperator *op, Object *ob, BakeImage *image
BKE_reportf(op->reports, RPT_ERROR,
"No active image found in material %d", i);
}
+ return false;
+ }
- return -1;
+ if ((image->id.flag & LIB_DOIT)) {
+ for (j = 0; j < i; j++) {
+ if (images->data[j].image == image) {
+ images->lookup[i] = j;
+ break;
+ }
+ }
+ }
+ else {
+ images->lookup[i] = tot_images;
+ images->data[tot_images].image = image;
+ image->id.flag |= LIB_DOIT;
+ tot_images++;
}
+ }
+
+ images->size = tot_images;
+ return true;
+}
- ibuf = BKE_image_acquire_ibuf(image, NULL, &lock);
+/*
+ * returns the total number of pixels
+ */
+static int initialize_internal_images(wmOperator *op, BakeImages *images)
+{
+ int i;
+ int tot_size = 0;
+
+ for (i = 0; i < images->size; i++) {
+ ImBuf *ibuf;
+ void *lock;
+
+ BakeImage *image = &images->data[i];
+ ibuf = BKE_image_acquire_ibuf(image->image, NULL, &lock);
if (ibuf) {
int num_pixels = ibuf->x * ibuf->y;
- images[i].width = ibuf->x;
- images[i].height = ibuf->y;
- images[i].offset = tot_size;
- images[i].image = image;
+ image->width = ibuf->x;
+ image->height = ibuf->y;
+ image->offset = tot_size;
tot_size += num_pixels;
}
else {
- BKE_image_release_ibuf(image, ibuf, lock);
- BKE_reportf(op->reports, RPT_ERROR, "Not inialized image in material '%d' (%s)", i, ob->mat[i]->id.name + 2);
- return -1;
+ BKE_image_release_ibuf(image->image, ibuf, lock);
+ BKE_reportf(op->reports, RPT_ERROR, "Not initialized image %s", image->image->id.name + 2);
+ return 0;
}
-
- BKE_image_release_ibuf(image, ibuf, lock);
+ BKE_image_release_ibuf(image->image, ibuf, lock);
}
-
return tot_size;
}
@@ -356,7 +385,7 @@ static int bake_exec(bContext *C, wmOperator *op)
bool is_highpoly = false;
bool is_tangent;
- BakeImage *images;
+ BakeImages images;
int normal_space = RNA_enum_get(op->ptr, "normal_space");
BakeNormalSwizzle normal_swizzle[] = {
@@ -369,16 +398,16 @@ static int bake_exec(bContext *C, wmOperator *op)
char filepath[FILE_MAX];
int num_pixels;
- int tot_images;
+ int tot_materials;
int i;
RNA_string_get(op->ptr, "cage", custom_cage);
RNA_string_get(op->ptr, "filepath", filepath);
is_tangent = pass_type == SCE_PASS_NORMAL && normal_space == R_BAKE_SPACE_TANGENT;
- tot_images = ob_low->totcol;
+ tot_materials = ob_low->totcol;
- if (tot_images == 0) {
+ if (tot_materials == 0) {
if (is_save_internal) {
BKE_report(op->reports, RPT_ERROR,
"No active image found. Add a material or bake to an external file");
@@ -391,34 +420,42 @@ static int bake_exec(bContext *C, wmOperator *op)
}
else {
/* baking externally without splitting materials */
- tot_images = 1;
+ int tot_images = 1;
}
}
- images = MEM_callocN(sizeof(BakeImage) * tot_images, "bake images dimensions (width, height, offset)");
+ /* we overallocate in case there is more materials than images */
+ images.data = MEM_callocN(sizeof(BakeImage) * tot_materials, "bake images dimensions (width, height, offset)");
+ images.lookup = MEM_callocN(sizeof(int) * tot_materials, "bake images lookup (from material to BakeImage)");
+
+ if(!build_image_lookup(op, bmain, ob_low, &images))
+ goto cleanup;
if (is_save_internal) {
- num_pixels = get_save_internal_status(op, ob_low, images);
+ num_pixels = initialize_internal_images(op, &images);
- if (num_pixels <= 0) {
+ if (num_pixels == 0) {
goto cleanup;
}
- else if (is_clear) {
- RE_bake_ibuf_clear(images, tot_images, is_tangent);
+
+ if (is_clear) {
+ RE_bake_ibuf_clear(&images, is_tangent);
}
}
else {
+#if 0
num_pixels = 0;
for (i = 0; i < tot_images; i++) {
- images[i].width = RNA_int_get(op->ptr, "width");
- images[i].height = RNA_int_get(op->ptr, "height");
- images[i].offset = (is_split_materials ? num_pixels : 0);
- images[i].image = NULL;
+ images.data[i].width = RNA_int_get(op->ptr, "width");
+ images.data[i].height = RNA_int_get(op->ptr, "height");
+ images.data[i].offset = (is_split_materials ? num_pixels : 0);
+ images.data[i].image = NULL;
- num_pixels += images[i].width * images[i].height;
+ num_pixels += images.data[i].width * images.data[i].height;
}
- BLI_assert(num_pixels == tot_images * images[0].width * images[0].height);
+ BLI_assert(num_pixels == tot_images * images.data[0].width * images.data[0].height);
+#endif
}
if (use_selected_to_active) {
@@ -543,7 +580,7 @@ static int bake_exec(bContext *C, wmOperator *op)
BLI_assert(i == tot_highpoly);
/* populate the pixel array with the face data */
- RE_populate_bake_pixels(me_low, pixel_array_low, num_pixels, images);
+ RE_populate_bake_pixels(me_low, pixel_array_low, num_pixels, &images);
ob_low->restrictflag |= OB_RESTRICT_RENDER;
@@ -578,7 +615,7 @@ static int bake_exec(bContext *C, wmOperator *op)
me_low = BKE_mesh_new_from_object(bmain, scene, ob_low, 1, 2, 1, 0);
/* populate the pixel array with the face data */
- RE_populate_bake_pixels(me_low, pixel_array_low, num_pixels, images);
+ RE_populate_bake_pixels(me_low, pixel_array_low, num_pixels, &images);
/* make sure low poly renders */
ob_low->restrictflag &= ~OB_RESTRICT_RENDER;
@@ -628,7 +665,7 @@ static int bake_exec(bContext *C, wmOperator *op)
}
me_nores = BKE_mesh_new_from_object(bmain, scene, ob_low, 1, 2, 1, 0);
- RE_populate_bake_pixels(me_nores, pixel_array_low, num_pixels, images);
+ RE_populate_bake_pixels(me_nores, pixel_array_low, num_pixels, &images);
RE_normal_world_to_tangent(pixel_array_low, num_pixels, depth, result, me_nores, normal_swizzle);
BKE_libblock_free(bmain, me_nores);
@@ -649,8 +686,8 @@ static int bake_exec(bContext *C, wmOperator *op)
}
else {
/* save the results */
- for (i = 0; i < tot_images; i++) {
- BakeImage *image = &images[i];
+ for (i = 0; i < images.size; i++) {
+ BakeImage *image = &images.data[i];
if (is_save_internal) {
ok = write_internal_bake_pixels(image->image, pixel_array_low + image->offset, result + image->offset * depth, image->width, image->height, is_linear, margin, is_clear);
@@ -746,8 +783,11 @@ cleanup:
if (pixel_array_low)
MEM_freeN(pixel_array_low);
- if (images)
- MEM_freeN(images);
+ if (images.data)
+ MEM_freeN(images.data);
+
+ if (images.lookup)
+ MEM_freeN(images.lookup);
if (result)
MEM_freeN(result);
diff --git a/source/blender/render/extern/include/RE_bake.h b/source/blender/render/extern/include/RE_bake.h
index 933a41e..206f53a 100644
--- a/source/blender/render/extern/include/RE_bake.h
+++ b/source/blender/render/extern/include/RE_bake.h
@@ -42,6 +42,12 @@ typedef struct BakeImage {
int offset;
} BakeImage;
+typedef struct BakeImages {
+ BakeImage *data; /* all the images of an object */
+ int *lookup; /* lookup table from Material to BakeImage */
+ int size;
+} BakeImages;
+
typedef struct BakePixel {
int primitive_id;
float uv[2];
@@ -71,7 +77,7 @@ void RE_populate_bake_pixels_from_objects(struct Mesh *me_low, BakePixel pixel_a
BakeHighPolyData highpoly[], const int tot_highpoly, const int num_pixels,
const float cage_extrusion);
-void RE_populate_bake_pixels(struct Mesh *me, struct BakePixel *pixel_array, const int num_pixels, const struct BakeImage *images);
+void RE_populate_bake_pixels(struct Mesh *me, struct BakePixel *pixel_array, const int num_pixels, const struct BakeImages *images);
void RE_bake_mask_fill(const BakePixel pixel_array[], const int num_pixels, char *mask);
@@ -81,6 +87,6 @@ void RE_normal_world_to_object(const BakePixel pixel_array[], const int num_pixe
void RE_normal_world_to_tangent(const BakePixel pixel_array[], const int num_pixels, const int depth, float result[], struct Mesh *me, const BakeNormalSwizzle normal_swizzle[3]);
void RE_normal_world_to_world(const BakePixel pixel_array[], const int num_pixels, const int depth, float result[], const BakeNormalSwizzle normal_swizzle[3]);
-void RE_bake_ibuf_clear(struct BakeImage *images, const int tot_mat, const bool is_tangent);
+void RE_bake_ibuf_clear(struct BakeImages *images, const bool is_tangent);
#endif
diff --git a/source/blender/render/intern/source/bake_api.c b/source/blender/render/intern/source/bake_api.c
index 64f46f2..a7ca762 100644
--- a/source/blender/render/intern/source/bake_api.c
+++ b/source/blender/render/intern/source/bake_api.c
@@ -81,8 +81,7 @@ extern struct Render R;
typedef struct BakeDataZSpan {
BakePixel *pixel_array;
int primitive_id;
- int mat_nr;
- const BakeImage *images;
+ BakeImage *image;
ZSpan *zspan;
} BakeDataZSpan;
@@ -108,9 +107,9 @@ static void store_bake_pixel(void *handle, int x, int y, float u, float v)
{
BakeDataZSpan *bd = (BakeDataZSpan *)handle;
BakePixel *pixel;
- const int mat_nr = bd->mat_nr;
- const int width = bd->images[mat_nr].width;
- const int offset = bd->images[mat_nr].offset;
+
+ const int width = bd->image->width;
+ const int offset = bd->image->offset;
const int i = offset + y * width + x;
pixel = &bd->pixel_array[i];
@@ -431,10 +430,10 @@ cleanup:
MEM_free
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list