diff options
author | Dalai Felinto <dfelinto@gmail.com> | 2016-01-15 18:00:56 +0300 |
---|---|---|
committer | Dalai Felinto <dfelinto@gmail.com> | 2016-01-15 18:00:56 +0300 |
commit | 9a76354585e2cd2011267e79bd99ca59a06588f8 (patch) | |
tree | e775e7c44dc210ef9978b483930ade6a9b4d6fc5 /source/blender/editors/object/object_bake_api.c | |
parent | 9137a4401440d3f3206e989f49f3539079d685b8 (diff) |
Cycles-Bake: Custom Baking passes
The combined pass is built with the contributions the user finds fit.
It is useful for lightmap baking, as well as non-view dependent effects
baking.
The manual will be updated once we get closer to the 2.77 release.
Meanwhile the new page can be found here:
http://dalaifelinto.com/blender-manual/render/cycles/baking.html
Reviewers: sergey, brecht
Differential Revision: https://developer.blender.org/D1674
Diffstat (limited to 'source/blender/editors/object/object_bake_api.c')
-rw-r--r-- | source/blender/editors/object/object_bake_api.c | 97 |
1 files changed, 89 insertions, 8 deletions
diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c index 616c4370448..bceda8ef620 100644 --- a/source/blender/editors/object/object_bake_api.c +++ b/source/blender/editors/object/object_bake_api.c @@ -87,6 +87,7 @@ typedef struct BakeAPIRender { ListBase selected_objects; ScenePassType pass_type; + int pass_filter; int margin; int save_mode; @@ -428,6 +429,66 @@ static bool bake_object_check(Object *ob, ReportList *reports) return true; } +static bool bake_pass_filter_check(ScenePassType 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; + } +} + /* before even getting in the bake function we check for some basic errors */ static bool bake_objects_check(Main *bmain, Object *ob, ListBase *selected_objects, ReportList *reports, const bool is_selected_to_active) @@ -552,7 +613,7 @@ static size_t initialize_internal_images(BakeImages *bake_images, ReportList *re static int bake( Render *re, Main *bmain, Scene *scene, Object *ob_low, ListBase *selected_objects, ReportList *reports, - const ScenePassType pass_type, const int margin, + const ScenePassType pass_type, const int pass_filter, const int margin, const BakeSaveMode 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 BakeNormalSwizzle normal_swizzle[], @@ -794,7 +855,7 @@ static int bake( /* the baking itself */ for (i = 0; i < tot_highpoly; i++) { ok = RE_bake_engine(re, highpoly[i].ob, i, pixel_array_high, - num_pixels, depth, pass_type, result); + 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 cage_cleanup; @@ -820,7 +881,7 @@ cage_cleanup: ob_low->restrictflag &= ~OB_RESTRICT_RENDER; if (RE_bake_has_engine(re)) { - ok = RE_bake_engine(re, ob_low, 0, pixel_array_low, num_pixels, depth, pass_type, result); + ok = RE_bake_engine(re, ob_low, 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"); @@ -1032,6 +1093,7 @@ static void bake_init_api_data(wmOperator *op, bContext *C, BakeAPIRender *bkr) 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->save_mode = RNA_enum_get(op->ptr, "save_mode"); @@ -1090,6 +1152,10 @@ static int bake_exec(bContext *C, wmOperator *op) /* 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.ob, &bkr.selected_objects, bkr.reports, bkr.is_selected_to_active)) { goto finally; } @@ -1104,7 +1170,7 @@ static int bake_exec(bContext *C, wmOperator *op) if (bkr.is_selected_to_active) { result = bake( bkr.render, bkr.main, bkr.scene, bkr.ob, &bkr.selected_objects, bkr.reports, - bkr.pass_type, bkr.margin, bkr.save_mode, + 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, @@ -1117,7 +1183,7 @@ static int bake_exec(bContext *C, wmOperator *op) Object *ob_iter = link->ptr.data; result = bake( bkr.render, bkr.main, bkr.scene, ob_iter, NULL, bkr.reports, - bkr.pass_type, bkr.margin, bkr.save_mode, + 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, @@ -1143,6 +1209,11 @@ static void bake_startjob(void *bkv, short *UNUSED(stop), short *do_update, floa 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->ob, &bkr->selected_objects, bkr->reports, bkr->is_selected_to_active)) { bkr->result = OPERATOR_CANCELLED; return; @@ -1156,7 +1227,7 @@ static void bake_startjob(void *bkv, short *UNUSED(stop), short *do_update, floa if (bkr->is_selected_to_active) { bkr->result = bake( bkr->render, bkr->main, bkr->scene, bkr->ob, &bkr->selected_objects, bkr->reports, - bkr->pass_type, bkr->margin, bkr->save_mode, + 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, @@ -1169,7 +1240,7 @@ static void bake_startjob(void *bkv, short *UNUSED(stop), short *do_update, floa Object *ob_iter = link->ptr.data; bkr->result = bake( bkr->render, bkr->main, bkr->scene, ob_iter, NULL, bkr->reports, - bkr->pass_type, bkr->margin, bkr->save_mode, + 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, @@ -1277,6 +1348,11 @@ static void bake_set_props(wmOperator *op, Scene *scene) 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)) @@ -1325,6 +1401,8 @@ static int bake_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event) void OBJECT_OT_bake(wmOperatorType *ot) { + PropertyRNA *prop; + /* identifiers */ ot->name = "Bake"; ot->description = "Bake image textures of selected objects"; @@ -1336,8 +1414,11 @@ void OBJECT_OT_bake(wmOperatorType *ot) ot->invoke = bake_invoke; ot->poll = ED_operator_object_active_editable_mesh; - RNA_def_enum(ot->srna, "type", rna_enum_render_pass_type_items, SCE_PASS_COMBINED, "Type", + 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", |