diff options
6 files changed, 65 insertions, 8 deletions
diff --git a/release/scripts/startup/bl_operators/uvcalc_smart_project.py b/release/scripts/startup/bl_operators/uvcalc_smart_project.py index f29bf07ab3a..73e6bcd9b0c 100644 --- a/release/scripts/startup/bl_operators/uvcalc_smart_project.py +++ b/release/scripts/startup/bl_operators/uvcalc_smart_project.py @@ -708,6 +708,7 @@ def main(context, island_margin, projection_limit, user_area_weight, + use_aspect ): global USER_FILL_HOLES global USER_FILL_HOLES_QUALITY @@ -720,7 +721,6 @@ def main(context, global dict_matrix dict_matrix = {} - # Constants: # Takes a list of faces that make up a UV island and rotate # until they optimally fit inside a square. @@ -992,9 +992,31 @@ def main(context, print("Smart Projection time: %.2f" % (time.time() - time1)) # Window.DrawProgressBar(0.9, "Smart Projections done, time: %.2f sec" % (time.time() - time1)) + # aspect correction is only done in edit mode - and only smart unwrap supports currently if is_editmode: bpy.ops.object.mode_set(mode='EDIT') + if use_aspect: + import bmesh + aspect = context.scene.uvedit_aspect(context.active_object) + if aspect[0] > aspect[1]: + aspect[0] = aspect[1]/aspect[0]; + aspect[1] = 1.0 + else: + aspect[1] = aspect[0]/aspect[1]; + aspect[0] = 1.0 + + bm = bmesh.from_edit_mesh(me) + + uv_act = bm.loops.layers.uv.active + + faces = [f for f in bm.faces if f.select] + + for f in faces: + for l in f.loops: + l[uv_act].uv[0] *= aspect[0] + l[uv_act].uv[1] *= aspect[1] + dict_matrix.clear() #XXX Window.DrawProgressBar(1.0, "") @@ -1017,7 +1039,7 @@ def main(context, ] """ -from bpy.props import FloatProperty +from bpy.props import FloatProperty, BoolProperty class SmartProject(Operator): @@ -1046,6 +1068,11 @@ class SmartProject(Operator): min=0.0, max=1.0, default=0.0, ) + use_aspect = BoolProperty( + name="Correct Aspect", + description="Map UVs taking image aspect ratio into account", + default=True + ) @classmethod def poll(cls, context): @@ -1056,6 +1083,7 @@ class SmartProject(Operator): self.island_margin, self.angle_limit, self.user_area_weight, + self.use_aspect ) return {'FINISHED'} diff --git a/source/blender/editors/include/ED_uvedit.h b/source/blender/editors/include/ED_uvedit.h index bf3b18e143e..3e8f234e979 100644 --- a/source/blender/editors/include/ED_uvedit.h +++ b/source/blender/editors/include/ED_uvedit.h @@ -94,6 +94,8 @@ void uvedit_uv_select_disable(struct BMEditMesh *em, struct Scene *scene, struct bool ED_uvedit_nearest_uv(struct Scene *scene, struct Object *obedit, struct Image *ima, const float co[2], float r_uv[2]); +void ED_uvedit_get_aspect(struct Scene *scene, struct Object *ob, struct BMesh *em, float *aspx, float *aspy); + /* uvedit_unwrap_ops.c */ void ED_uvedit_live_unwrap_begin(struct Scene *scene, struct Object *obedit); void ED_uvedit_live_unwrap_re_solve(void); diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h index 8865bc6775b..d1fd8d969a4 100644 --- a/source/blender/editors/uvedit/uvedit_intern.h +++ b/source/blender/editors/uvedit/uvedit_intern.h @@ -72,7 +72,6 @@ void uv_find_nearest_edge(struct Scene *scene, struct Image *ima, struct BMEditM /* utility tool functions */ void uvedit_live_unwrap_update(struct SpaceImage *sima, struct Scene *scene, struct Object *obedit); -void uvedit_get_aspect(struct Scene *scene, struct Object *ob, struct BMesh *em, float *aspx, float *aspy); /* operators */ diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index 9359baa5020..eab3d5965f6 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -1660,7 +1660,7 @@ static int stitch_init(bContext *C, wmOperator *op) return 0; } - uvedit_get_aspect(scene, obedit, em->bm, &aspx, &aspy); + ED_uvedit_get_aspect(scene, obedit, em->bm, &aspx, &aspy); state->aspect = aspx / aspy; /* Entirely possible if redoing last operator that static island is bigger than total number of islands. diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index 6a33351753e..b5e27ab0cf6 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -190,7 +190,7 @@ static bool uvedit_have_selection(Scene *scene, BMEditMesh *em, bool implicit) return false; } -void uvedit_get_aspect(Scene *scene, Object *ob, BMesh *bm, float *aspx, float *aspy) +void ED_uvedit_get_aspect(Scene *scene, Object *ob, BMesh *bm, float *aspx, float *aspy) { bool sloppy = true; bool selected = false; @@ -264,7 +264,7 @@ static ParamHandle *construct_param_handle(Scene *scene, Object *ob, BMesh *bm, if (correct_aspect) { float aspx, aspy; - uvedit_get_aspect(scene, ob, bm, &aspx, &aspy); + ED_uvedit_get_aspect(scene, ob, bm, &aspx, &aspy); if (aspx != aspy) param_aspect_ratio(handle, aspx, aspy); @@ -376,7 +376,7 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, Object *ob, B if (correct_aspect) { float aspx, aspy; - uvedit_get_aspect(scene, ob, em->bm, &aspx, &aspy); + ED_uvedit_get_aspect(scene, ob, em->bm, &aspx, &aspy); if (aspx != aspy) param_aspect_ratio(handle, aspx, aspy); @@ -1010,7 +1010,7 @@ static void correct_uv_aspect(Scene *scene, Object *ob, BMEditMesh *em) const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); - uvedit_get_aspect(scene, ob, em->bm, &aspx, &aspy); + ED_uvedit_get_aspect(scene, ob, em->bm, &aspx, &aspy); if (aspx == aspy) return; diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c index 84134e7cd3a..ed5919149f4 100644 --- a/source/blender/makesrna/intern/rna_scene_api.c +++ b/source/blender/makesrna/intern/rna_scene_api.c @@ -47,12 +47,14 @@ #include "BKE_animsys.h" #include "BKE_depsgraph.h" +#include "BKE_editmesh.h" #include "BKE_global.h" #include "BKE_image.h" #include "BKE_scene.h" #include "BKE_writeavi.h" #include "ED_transform.h" +#include "ED_uvedit.h" #ifdef WITH_PYTHON # include "BPY_extern.h" @@ -90,6 +92,23 @@ static void rna_Scene_frame_set(Scene *scene, int frame, float subframe) } } +static void rna_Scene_uvedit_aspect(Scene *scene, Object *ob, float *aspect) +{ + BMEditMesh *em; + if (!(ob && ob->type == OB_MESH && ob->mode == OB_MODE_EDIT)) { + aspect[0] = aspect[1]= 1.0f; + return; + } + + em = BKE_editmesh_from_object(ob); + if (!EDBM_mtexpoly_check(em)) { + aspect[0] = aspect[1]= 1.0f; + return; + } + + ED_uvedit_get_aspect(scene, ob, em->bm, aspect, aspect + 1); +} + static void rna_Scene_update_tagged(Scene *scene) { #ifdef WITH_PYTHON @@ -191,6 +210,15 @@ void RNA_api_scene(StructRNA *srna) RNA_def_function_ui_description(func, "Update data tagged to be updated from previous access to data or operators"); + func = RNA_def_function(srna, "uvedit_aspect", "rna_Scene_uvedit_aspect"); + RNA_def_function_ui_description(func, "Get uv aspect for current object"); + parm = RNA_def_pointer(func, "object", "Object", "", "Object"); + RNA_def_property_flag(parm, PROP_REQUIRED); + + parm = RNA_def_float_vector(func, "aspect", 2, NULL, 0.0f, FLT_MAX, "", "aspect", 0.0f, FLT_MAX); + RNA_def_property_flag(parm, PROP_THICK_WRAP); + RNA_def_function_output(func, parm); + /* Ray Cast */ func = RNA_def_function(srna, "ray_cast", "rna_Scene_ray_cast"); RNA_def_function_ui_description(func, "Cast a ray onto in object space"); |