Fix T42859 smart UV unwrap does not support aspect correction.

Can be considered TODO but it's not bad to support either. Also added
RNA api to get aspect ratio of assigned UV image - returns aspect
corrected image dimensions so needs adjustments for uv editing.
This commit is contained in:
Antonis Ryakiotakis 2014-12-11 19:46:35 +01:00
parent 2309def874
commit f1ddf99580
Notes: blender-bot 2023-02-14 09:44:48 +01:00
Referenced by issue #42859, SmartUV wrong aspect ratio projection on non square images
6 changed files with 65 additions and 8 deletions

View File

@ -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'}

View File

@ -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);

View File

@ -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 */

View File

@ -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.

View File

@ -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;

View File

@ -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");