diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 08641c05941..a15daee706f 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -1907,10 +1907,15 @@ class CYCLES_RENDER_PT_bake_selected_to_active(CyclesButtonsPanel, Panel): col.prop(cbk, "use_cage", text="Cage") if cbk.use_cage: - col.prop(cbk, "cage_extrusion", text="Extrusion") - col.prop(cbk, "cage_object", text="Cage Object") + col.prop(cbk, "cage_object") + col = layout.column() + col.prop(cbk, "cage_extrusion") + col.active = cbk.cage_object is None else: - col.prop(cbk, "cage_extrusion", text="Ray Distance") + col.prop(cbk, "cage_extrusion", text="Extrusion") + + col = layout.column() + col.prop(cbk, "max_ray_distance") class CYCLES_RENDER_PT_bake_output(CyclesButtonsPanel, Panel): diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c index c31de7f371c..e84dbca2469 100644 --- a/source/blender/editors/object/object_bake_api.c +++ b/source/blender/editors/object/object_bake_api.c @@ -96,6 +96,7 @@ typedef struct BakeAPIRender { bool is_cage; float cage_extrusion; + float max_ray_distance; int normal_space; eBakeNormalSwizzle normal_swizzle[3]; @@ -737,6 +738,7 @@ static int bake(Render *re, const bool is_selected_to_active, const bool is_cage, const float cage_extrusion, + const float max_ray_distance, const int normal_space, const eBakeNormalSwizzle normal_swizzle[], const char *custom_cage, @@ -1010,6 +1012,7 @@ static int bake(Render *re, num_pixels, ob_cage != NULL, cage_extrusion, + max_ray_distance, ob_low_eval->obmat, (ob_cage ? ob_cage->obmat : ob_low_eval->obmat), me_cage)) { @@ -1305,6 +1308,7 @@ static void bake_init_api_data(wmOperator *op, bContext *C, BakeAPIRender *bkr) bkr->is_selected_to_active = RNA_boolean_get(op->ptr, "use_selected_to_active"); bkr->is_cage = RNA_boolean_get(op->ptr, "use_cage"); bkr->cage_extrusion = RNA_float_get(op->ptr, "cage_extrusion"); + bkr->max_ray_distance = RNA_float_get(op->ptr, "max_ray_distance"); bkr->normal_space = RNA_enum_get(op->ptr, "normal_space"); bkr->normal_swizzle[0] = RNA_enum_get(op->ptr, "normal_r"); @@ -1394,6 +1398,7 @@ static int bake_exec(bContext *C, wmOperator *op) true, bkr.is_cage, bkr.cage_extrusion, + bkr.max_ray_distance, bkr.normal_space, bkr.normal_swizzle, bkr.custom_cage, @@ -1426,6 +1431,7 @@ static int bake_exec(bContext *C, wmOperator *op) false, bkr.is_cage, bkr.cage_extrusion, + bkr.max_ray_distance, bkr.normal_space, bkr.normal_swizzle, bkr.custom_cage, @@ -1495,6 +1501,7 @@ static void bake_startjob(void *bkv, short *UNUSED(stop), short *do_update, floa true, bkr->is_cage, bkr->cage_extrusion, + bkr->max_ray_distance, bkr->normal_space, bkr->normal_swizzle, bkr->custom_cage, @@ -1527,6 +1534,7 @@ static void bake_startjob(void *bkv, short *UNUSED(stop), short *do_update, floa false, bkr->is_cage, bkr->cage_extrusion, + bkr->max_ray_distance, bkr->normal_space, bkr->normal_swizzle, bkr->custom_cage, @@ -1586,6 +1594,11 @@ static void bake_set_props(wmOperator *op, Scene *scene) RNA_property_boolean_set(op->ptr, prop, (bake->flag & R_BAKE_TO_ACTIVE) != 0); } + prop = RNA_struct_find_property(op->ptr, "max_ray_distance"); + if (!RNA_property_is_set(op->ptr, prop)) { + RNA_property_float_set(op->ptr, prop, bake->max_ray_distance); + } + prop = RNA_struct_find_property(op->ptr, "cage_extrusion"); if (!RNA_property_is_set(op->ptr, prop)) { RNA_property_float_set(op->ptr, prop, bake->cage_extrusion); @@ -1765,13 +1778,24 @@ void OBJECT_OT_bake(wmOperatorType *ot) false, "Selected to Active", "Bake shading on the surface of selected objects to the active object"); + RNA_def_float(ot->srna, + "max_ray_distance", + 0.0f, + 0.0f, + FLT_MAX, + "Max Ray Distance", + "The maximum ray distance for matching points between the active and selected " + "objects. If zero, there is no limit", + 0.0f, + 1.0f); RNA_def_float(ot->srna, "cage_extrusion", 0.0f, 0.0f, FLT_MAX, "Cage Extrusion", - "Distance to use for the inward ray cast when using selected to active", + "Inflate the active object by the specified distance for baking. This helps " + "matching to points nearer to the outside of the selected object meshes", 0.0f, 1.0f); RNA_def_string(ot->srna, diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 1533b82ad4e..8c34a7cb0a1 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -555,13 +555,14 @@ typedef struct BakeData { short margin, flag; float cage_extrusion; + float max_ray_distance; int pass_filter; char normal_swizzle[3]; char normal_space; char save_mode; - char _pad[3]; + char _pad[7]; struct Object *cage_object; } BakeData; diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 6423175e2f4..0d5e59b0e8b 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -4884,13 +4884,23 @@ static void rna_def_bake_data(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Margin", "Extends the baked result as a post process filter"); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + prop = RNA_def_property(srna, "max_ray_distance", PROP_FLOAT, PROP_DISTANCE); + RNA_def_property_range(prop, 0.0, FLT_MAX); + RNA_def_property_ui_range(prop, 0.0, 1.0, 1, 3); + RNA_def_property_ui_text(prop, + "Max Ray Distance", + "The maximum ray distance for matching points between the active and " + "selected objects. If zero, there is no limit"); + RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + prop = RNA_def_property(srna, "cage_extrusion", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_range(prop, 0.0, FLT_MAX); RNA_def_property_ui_range(prop, 0.0, 1.0, 1, 3); RNA_def_property_ui_text( prop, "Cage Extrusion", - "Distance to use for the inward ray cast when using selected to active"); + "Inflate the active object by the specified distance for baking. This helps matching to " + "points nearer to the outside of the selected object meshes"); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); prop = RNA_def_property(srna, "normal_space", PROP_ENUM, PROP_NONE); diff --git a/source/blender/render/extern/include/RE_bake.h b/source/blender/render/extern/include/RE_bake.h index 59e34404074..3bab9179f84 100644 --- a/source/blender/render/extern/include/RE_bake.h +++ b/source/blender/render/extern/include/RE_bake.h @@ -84,6 +84,7 @@ bool RE_bake_pixels_populate_from_objects(struct Mesh *me_low, const size_t num_pixels, const bool is_custom_cage, const float cage_extrusion, + const float max_ray_distance, float mat_low[4][4], float mat_cage[4][4], struct Mesh *me_cage); diff --git a/source/blender/render/intern/source/bake_api.c b/source/blender/render/intern/source/bake_api.c index e823a481d59..06f77854595 100644 --- a/source/blender/render/intern/source/bake_api.c +++ b/source/blender/render/intern/source/bake_api.c @@ -321,11 +321,16 @@ static bool cast_ray_highpoly(BVHTreeFromMesh *treeData, const float co[3], const float dir[3], const int pixel_id, - const int tot_highpoly) + const int tot_highpoly, + const float max_ray_distance) { int i; int hit_mesh = -1; - float hit_distance = FLT_MAX; + float hit_distance = max_ray_distance; + if (hit_distance == 0.0f) { + /* No ray distance set, use maximum. */ + hit_distance = FLT_MAX; + } BVHTreeRayHit *hits; hits = MEM_mallocN(sizeof(BVHTreeRayHit) * tot_highpoly, "Bake Highpoly to Lowpoly: BVH Rays"); @@ -520,6 +525,7 @@ bool RE_bake_pixels_populate_from_objects(struct Mesh *me_low, const size_t num_pixels, const bool is_custom_cage, const float cage_extrusion, + const float max_ray_distance, float mat_low[4][4], float mat_cage[4][4], struct Mesh *me_cage) @@ -623,7 +629,8 @@ bool RE_bake_pixels_populate_from_objects(struct Mesh *me_low, co, dir, i, - tot_highpoly)) { + tot_highpoly, + max_ray_distance)) { /* if it fails mask out the original pixel array */ pixel_array_from[i].primitive_id = -1; }