From fd0b74280e05025d99195bc1ea73815551ecba8a Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Tue, 17 Jun 2014 12:16:02 -0300 Subject: [PATCH] Bake-API: allow custom UV to be baked Note: the custom UV option is only available when calling the operator via a script. It's currently not exposed in the UI since it's intended to be used by scripters To test it: bpy.ops.object.bake(type='UV', use_clear=True, uv_layer='MyNewUV') Reviewers: campbellbarton Differential Revision: https://developer.blender.org/D546 --- .../blender/editors/object/object_bake_api.c | 33 ++++++++++++++----- .../blender/render/extern/include/RE_bake.h | 2 +- .../blender/render/intern/source/bake_api.c | 11 +++++-- 3 files changed, 35 insertions(+), 11 deletions(-) diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c index cdb23b23f7d..582ecf09ece 100644 --- a/source/blender/editors/object/object_bake_api.c +++ b/source/blender/editors/object/object_bake_api.c @@ -495,6 +495,7 @@ typedef struct BakeAPIRender { int normal_space; BakeNormalSwizzle normal_swizzle[3]; + char uv_layer[MAX_CUSTOMDATA_LAYER_NAME]; char custom_cage[MAX_NAME]; char filepath[FILE_MAX]; @@ -516,7 +517,7 @@ static int bake( const bool is_automatic_name, const bool is_selected_to_active, const bool is_cage, 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) + const char *identifier, ScrArea *sa, const char *uv_layer) { int op_result = OPERATOR_CANCELLED; bool ok = false; @@ -552,6 +553,15 @@ static int bake( 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, @@ -644,7 +654,7 @@ static int bake( /* 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); + 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) { @@ -688,7 +698,7 @@ static int bake( /* get the cage mesh as it arrives in the renderer */ me_cage = BKE_mesh_new_from_object(bmain, scene, ob_low, 1, 2, 1, 0); - RE_bake_pixels_populate(me_cage, pixel_array_low, num_pixels, &bake_images); + 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"); @@ -827,7 +837,7 @@ static int bake( } me_nores = BKE_mesh_new_from_object(bmain, scene, ob_low, 1, 2, 1, 0); - RE_bake_pixels_populate(me_nores, pixel_array_low, num_pixels, &bake_images); + 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->obmat); BKE_libblock_free(bmain, me_nores); @@ -1009,6 +1019,8 @@ static void bake_init_api_data(wmOperator *op, bContext *C, BakeAPIRender *bkr) 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, "cage_object", bkr->custom_cage); if ((!is_save_internal) && bkr->is_automatic_name) { @@ -1048,7 +1060,8 @@ static int bake_exec(bContext *C, wmOperator *op) bkr.pass_type, 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.custom_cage, bkr.filepath, bkr.width, bkr.height, bkr.identifier, bkr.sa, + bkr.uv_layer); } else { CollectionPointerLink *link; @@ -1060,7 +1073,8 @@ static int bake_exec(bContext *C, wmOperator *op) bkr.pass_type, 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.custom_cage, bkr.filepath, bkr.width, bkr.height, bkr.identifier, bkr.sa, + bkr.uv_layer); } } @@ -1088,7 +1102,8 @@ static void bake_startjob(void *bkv, short *UNUSED(stop), short *UNUSED(do_updat bkr->pass_type, 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->custom_cage, bkr->filepath, bkr->width, bkr->height, bkr->identifier, bkr->sa, + bkr->uv_layer); } else { CollectionPointerLink *link; @@ -1100,7 +1115,8 @@ static void bake_startjob(void *bkv, short *UNUSED(stop), short *UNUSED(do_updat bkr->pass_type, 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->custom_cage, bkr->filepath, bkr->width, bkr->height, bkr->identifier, bkr->sa, + bkr->uv_layer); if (bkr->result == OPERATOR_CANCELLED) return; @@ -1286,4 +1302,5 @@ void OBJECT_OT_bake(wmOperatorType *ot) "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"); } diff --git a/source/blender/render/extern/include/RE_bake.h b/source/blender/render/extern/include/RE_bake.h index 961ca3fdd6d..8f2a0e382a4 100644 --- a/source/blender/render/extern/include/RE_bake.h +++ b/source/blender/render/extern/include/RE_bake.h @@ -87,7 +87,7 @@ bool RE_bake_pixels_populate_from_objects( void RE_bake_pixels_populate( struct Mesh *me, struct BakePixel *pixel_array, - const int num_pixels, const struct BakeImages *bake_images); + const int num_pixels, const struct BakeImages *bake_images, const char *uv_layer); void RE_bake_mask_fill(const BakePixel pixel_array[], const int num_pixels, char *mask); diff --git a/source/blender/render/intern/source/bake_api.c b/source/blender/render/intern/source/bake_api.c index 713f7b8f808..28cb916dca1 100644 --- a/source/blender/render/intern/source/bake_api.c +++ b/source/blender/render/intern/source/bake_api.c @@ -594,7 +594,7 @@ static void bake_differentials(BakeDataZSpan *bd, const float *uv1, const float void RE_bake_pixels_populate( Mesh *me, BakePixel pixel_array[], - const int num_pixels, const BakeImages *bake_images) + const int num_pixels, const BakeImages *bake_images, const char *uv_layer) { BakeDataZSpan bd; int i, a; @@ -619,7 +619,14 @@ void RE_bake_pixels_populate( zbuf_alloc_span(&bd.zspan[i], bake_images->data[i].width, bake_images->data[i].height, R.clipcrop); } - mtface = CustomData_get_layer(&me->fdata, CD_MTFACE); + if (uv_layer == NULL) { + mtface = CustomData_get_layer(&me->fdata, CD_MTFACE); + } + else { + int uv_id = CustomData_get_named_layer(&me->fdata, CD_MTFACE, uv_layer); + mtface = CustomData_get_layer_n(&me->fdata, CD_MTFACE, uv_id); + } + mface = CustomData_get_layer(&me->fdata, CD_MFACE); if (mtface == NULL)