UV Unwrap (lscm, project from view, cube etc) now default to correcting for the active images aspect ratio.

This is now default but can be disabled in the UV Calculation panel. At the moment its called "Image Aspect" but another name could be better.
This commit is contained in:
Campbell Barton 2008-03-26 14:50:29 +00:00
parent 6184c07474
commit 5fa576a89f
11 changed files with 176 additions and 80 deletions

View File

@ -6438,7 +6438,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
sce->toolsettings->uvcalc_cubesize = 1.0f;
sce->toolsettings->uvcalc_mapdir = 1;
sce->toolsettings->uvcalc_mapalign = 1;
sce->toolsettings->uvcalc_flag = 1;
sce->toolsettings->uvcalc_flag = UVCALC_FILLHOLES;
sce->toolsettings->unwrapper = 1;
}

View File

@ -44,7 +44,6 @@ struct MTFace;
void do_imagebuts(unsigned short event);
void calc_image_view(struct SpaceImage *sima, char mode);
void drawimagespace(struct ScrArea *sa, void *spacedata);
void image_changed(struct SpaceImage *sima, struct Image *image);
int draw_uvs_face_check(void);
void uv_center(float uv[][2], float cent[2], void * isquad);
void draw_uvs_sima(void);

View File

@ -42,6 +42,8 @@ struct MTFace;
struct Object;
void image_changed(struct SpaceImage *sima, struct Image *image);
void object_uvs_changed(struct Object *ob);
void object_tface_flags_changed(struct Object *ob, int updateButtons);

View File

@ -776,6 +776,10 @@ typedef struct Scene {
#define IMAGEPAINT_DRAW_TOOL 2
#define IMAGEPAINT_DRAW_TOOL_DRAWING 4
/* toolsettings->uvcalc_flag */
#define UVCALC_FILLHOLES 1
#define UVCALC_NO_ASPECT_CORRECT 2 /* would call this UVCALC_ASPECT_CORRECT, except it should be default with old file */
/* toolsettings->particle flag */
#define PE_KEEP_LENGTHS 1
#define PE_LOCK_FIRST 2

View File

@ -6232,12 +6232,14 @@ static void editing_panel_mesh_uvautocalculation(void)
uiBlockBeginAlign(block);
uiDefButS(block, MENU, REDRAWBUTSEDIT, "Unwrapper%t|Conformal%x0|Angle Based%x1",100,row,200,butH, &G.scene->toolsettings->unwrapper, 0, 0, 0, 0, "Unwrap method");
uiDefButBitS(block, TOG, 1, B_NOP, "Fill Holes",100,row-butHB,200,butH,&G.scene->toolsettings->uvcalc_flag, 0, 0, 0, 0, "Fill holes to prevent internal overlaps");
uiDefButBitS(block, TOG, UVCALC_FILLHOLES, B_NOP, "Fill Holes",100,row-butHB,200,butH,&G.scene->toolsettings->uvcalc_flag, 0, 0, 0, 0, "Fill holes to prevent internal overlaps");
uiBlockEndAlign(block);
row-= 2*butHB+butS;
row= 180;
uiDefButBitS(block, TOGN, UVCALC_NO_ASPECT_CORRECT, B_NOP, "Image Aspect",100,row,200,butH,&G.scene->toolsettings->uvcalc_flag, 0, 0, 0, 0, "Scale the UV Unwrapping to correct for the current images aspect ratio");
uiBlockBeginAlign(block);
uiDefButF(block, NUM,B_UVAUTO_CUBESIZE ,"Cube Size:",315,row,200,butH, &G.scene->toolsettings->uvcalc_cubesize, 0.0001, 100.0, 10, 3, "Defines the cubemap size for cube mapping");
uiBlockEndAlign(block);

View File

@ -290,80 +290,6 @@ ImBuf *imagewindow_get_ibuf(SpaceImage *sima)
return NULL;
}
extern int EM_texFaceCheck(void); /* from editmesh.c */
/* called to assign images to UV faces */
void image_changed(SpaceImage *sima, Image *image)
{
MTFace *tface;
EditMesh *em = G.editMesh;
EditFace *efa;
ImBuf *ibuf = NULL;
short change = 0;
if(image==NULL) {
sima->flag &= ~SI_DRAWTOOL;
} else {
ibuf = BKE_image_get_ibuf(image, NULL);
}
if(sima->mode!=SI_TEXTURE)
return;
/* skip assigning these procedural images... */
if(image && (image->type==IMA_TYPE_R_RESULT || image->type==IMA_TYPE_COMPOSITE)) {
return;
} else if ((G.obedit) &&
(G.obedit->type == OB_MESH) &&
(G.editMesh) &&
(G.editMesh->faces.first)
) {
/* Add a UV layer if there is none, editmode only */
if ( !CustomData_has_layer(&G.editMesh->fdata, CD_MTFACE) ) {
EM_add_data_layer(&em->fdata, CD_MTFACE);
CustomData_set_layer_active(&em->fdata, CD_MTFACE, 0); /* always zero because we have no other UV layers */
change = 1; /* so we update the object, incase no faces are selected */
/* BIF_undo_push("New UV Texture"); - undo should be done by whatever changes the image */
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWBUTSEDIT, 0);
}
for (efa= em->faces.first; efa; efa= efa->next) {
tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
if (efa->h==0 && efa->f & SELECT) {
if (image) {
tface->tpage= image;
tface->mode |= TF_TEX;
if(image->tpageflag & IMA_TILES) tface->mode |= TF_TILES;
else tface->mode &= ~TF_TILES;
if(image->id.us==0) id_us_plus(&image->id);
else id_lib_extern(&image->id);
if (tface->transp==TF_ADD) {} /* they obviously know what they are doing! - leave as is */
else if (ibuf && ibuf->depth == 32) tface->transp = TF_ALPHA;
else tface->transp = TF_SOLID;
} else {
tface->tpage= NULL;
tface->mode &= ~TF_TEX;
tface->transp = TF_SOLID;
}
change = 1;
}
}
}
/* change the space image after because simaFaceDraw_Check uses the space image
* to check if the face is displayed in UV-localview */
sima->image = image;
if (change)
object_uvs_changed(OBACT);
allqueue(REDRAWBUTSEDIT, 0);
}
/*
* dotile - 1, set the tile flag (from the space image)
* 2, set the tile index for the faces.

View File

@ -83,6 +83,7 @@
#include "BIF_gl.h"
#include "BIF_graphics.h"
#include "BIF_space.h" /* for allqueue */
#include "BIF_drawimage.h" /* for allqueue */
#include "BDR_drawmesh.h"
#include "BDR_editface.h"
@ -338,6 +339,48 @@ static void uv_calc_shift_project(float *target, float *shift, float rotmat[][4]
}
}
void correct_uv_aspect( void )
{
float aspx, aspy;
transform_aspect_ratio_tface_uv(&aspx, &aspy);
if (aspx != aspy) {
MTFace *tface;
EditMesh *em = G.editMesh;
EditFace *efa;
float scale;
if (aspx > aspy) {
scale = aspy/aspx;
for (efa= em->faces.first; efa; efa= efa->next) {
if (efa->f & SELECT) {
tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
tface->uv[0][0] = ((tface->uv[0][0]-0.5)*scale)+0.5;
tface->uv[1][0] = ((tface->uv[1][0]-0.5)*scale)+0.5;
tface->uv[2][0] = ((tface->uv[2][0]-0.5)*scale)+0.5;
if(efa->v4) {
tface->uv[3][0] = ((tface->uv[3][0]-0.5)*scale)+0.5;
}
}
}
} else {
scale = aspx/aspy;
for (efa= em->faces.first; efa; efa= efa->next) {
if (efa->f & SELECT) {
tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
tface->uv[0][1] = ((tface->uv[0][1]-0.5)*scale)+0.5;
tface->uv[1][1] = ((tface->uv[1][1]-0.5)*scale)+0.5;
tface->uv[2][1] = ((tface->uv[2][1]-0.5)*scale)+0.5;
if(efa->v4) {
tface->uv[3][1] = ((tface->uv[3][1]-0.5)*scale)+0.5;
}
}
}
}
}
}
void calculate_uv_map(unsigned short mapmode)
{
MTFace *tface;
@ -555,6 +598,13 @@ void calculate_uv_map(unsigned short mapmode)
}
}
if ( (mapmode!=B_UVAUTO_BOUNDS) &&
(mapmode!=B_UVAUTO_RESET) &&
(G.scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT)==0
) {
correct_uv_aspect();
}
BIF_undo_push("UV calculation");
object_uvs_changed(OBACT);

View File

@ -2632,6 +2632,81 @@ void BIF_image_update_frame(void)
}
}
extern int EM_texFaceCheck(void); /* from editmesh.c */
/* called to assign images to UV faces */
void image_changed(SpaceImage *sima, Image *image)
{
MTFace *tface;
EditMesh *em = G.editMesh;
EditFace *efa;
ImBuf *ibuf = NULL;
short change = 0;
if(image==NULL) {
sima->flag &= ~SI_DRAWTOOL;
} else {
ibuf = BKE_image_get_ibuf(image, NULL);
}
if(sima->mode!=SI_TEXTURE)
return;
/* skip assigning these procedural images... */
if(image && (image->type==IMA_TYPE_R_RESULT || image->type==IMA_TYPE_COMPOSITE)) {
return;
} else if ((G.obedit) &&
(G.obedit->type == OB_MESH) &&
(G.editMesh) &&
(G.editMesh->faces.first)
) {
/* Add a UV layer if there is none, editmode only */
if ( !CustomData_has_layer(&G.editMesh->fdata, CD_MTFACE) ) {
EM_add_data_layer(&em->fdata, CD_MTFACE);
CustomData_set_layer_active(&em->fdata, CD_MTFACE, 0); /* always zero because we have no other UV layers */
change = 1; /* so we update the object, incase no faces are selected */
/* BIF_undo_push("New UV Texture"); - undo should be done by whatever changes the image */
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWBUTSEDIT, 0);
}
for (efa= em->faces.first; efa; efa= efa->next) {
tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
if (efa->h==0 && efa->f & SELECT) {
if (image) {
tface->tpage= image;
tface->mode |= TF_TEX;
if(image->tpageflag & IMA_TILES) tface->mode |= TF_TILES;
else tface->mode &= ~TF_TILES;
if(image->id.us==0) id_us_plus(&image->id);
else id_lib_extern(&image->id);
if (tface->transp==TF_ADD) {} /* they obviously know what they are doing! - leave as is */
else if (ibuf && ibuf->depth == 32) tface->transp = TF_ALPHA;
else tface->transp = TF_SOLID;
} else {
tface->tpage= NULL;
tface->mode &= ~TF_TEX;
tface->transp = TF_SOLID;
}
change = 1;
}
}
}
/* change the space image after because simaFaceDraw_Check uses the space image
* to check if the face is displayed in UV-localview */
sima->image = image;
if (change)
object_uvs_changed(OBACT);
allqueue(REDRAWBUTSEDIT, 0);
}
void aspect_sima(SpaceImage *sima, float *x, float *y)
{
*x = *y = 1.0;

View File

@ -256,6 +256,16 @@ static void p_chart_uv_scale(PChart *chart, float scale)
}
}
static void p_chart_uv_scale_xy(PChart *chart, float x, float y)
{
PVert *v;
for (v=chart->verts; v; v=v->nextlink) {
v->uv[0] *= x;
v->uv[1] *= y;
}
}
static void p_chart_uv_translate(PChart *chart, float trans[2])
{
PVert *v;
@ -4220,6 +4230,18 @@ void param_average(ParamHandle *handle)
}
}
void param_scale(ParamHandle *handle, float x, float y)
{
PHandle *phandle = (PHandle*)handle;
PChart *chart;
int i;
for (i = 0; i < phandle->ncharts; i++) {
chart = phandle->charts[i];
p_chart_uv_scale_xy(chart, x, y);
}
}
void param_flush(ParamHandle *handle)
{
PHandle *phandle = (PHandle*)handle;

View File

@ -75,6 +75,10 @@ void param_pack(ParamHandle *handle);
void param_average(ParamHandle *handle);
/* Simple x,y scale */
void param_scale(ParamHandle *handle, float x, float y);
/* Flushing */
void param_flush(ParamHandle *handle);

View File

@ -288,7 +288,7 @@ void unwrap_lscm(short seamcut)
EditMesh *em = G.editMesh;
ParamHandle *handle;
short abf = G.scene->toolsettings->unwrapper == 1;
short fillholes = G.scene->toolsettings->uvcalc_flag & 1;
short fillholes = G.scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES;
/* add uvs if there not here */
if (!EM_texFaceCheck()) {
@ -318,6 +318,18 @@ void unwrap_lscm(short seamcut)
param_lscm_solve(handle);
param_lscm_end(handle);
/* scale before packing */
if ((G.scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT)==0) {
float aspx, aspy;
transform_aspect_ratio_tface_uv(&aspx, &aspy);
if (aspx!=aspy) {
param_scale(handle, 1.0, aspx/aspy);
}
}
param_pack(handle);
param_flush(handle);
@ -340,7 +352,7 @@ void minimize_stretch_tface_uv(void)
double lasttime;
short doit = 1, escape = 0, val, blend = 0;
unsigned short event = 0;
short fillholes = G.scene->toolsettings->uvcalc_flag & 1;
short fillholes = G.scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES;
if(!EM_texFaceCheck()) return;
@ -474,7 +486,7 @@ void unwrap_lscm_live_begin(void)
{
EditMesh *em = G.editMesh;
short abf = G.scene->toolsettings->unwrapper == 1;
short fillholes = G.scene->toolsettings->uvcalc_flag & 1;
short fillholes = G.scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES;
if(!EM_texFaceCheck()) return;