diff --git a/source/blender/include/BIF_drawimage.h b/source/blender/include/BIF_drawimage.h index cb3dc7a7a4a..f1ab908cdbf 100644 --- a/source/blender/include/BIF_drawimage.h +++ b/source/blender/include/BIF_drawimage.h @@ -46,7 +46,7 @@ void image_viewmove(int mode); void image_viewzoom(unsigned short event, int invert); void image_viewcentre(void); void uvco_to_areaco(float *vec, short *mval); -void uvco_to_areaco_noclip(float *vec, short *mval); +void uvco_to_areaco_noclip(float *vec, int *mval); void what_image(struct SpaceImage *sima); #endif diff --git a/source/blender/include/BIF_editsima.h b/source/blender/include/BIF_editsima.h index 9bf2007a5ff..364c825ba69 100644 --- a/source/blender/include/BIF_editsima.h +++ b/source/blender/include/BIF_editsima.h @@ -30,6 +30,8 @@ * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ +struct Mesh; + #define TF_PIN_MASK(id) (TF_PIN1 << id) #define TF_SEL_MASK(id) (TF_SEL1 << id) @@ -40,12 +42,17 @@ void object_tface_flags_changed(struct Object *ob, int updateButtons); int is_uv_tface_editing_allowed(void); int is_uv_tface_editing_allowed_silent(void); + +void get_connected_limit_tface_uv(float *limit); +int minmax_tface_uv(float *min, float *max); + +void transform_width_height_tface_uv(int *width, int *height); +void transform_aspect_ratio_tface_uv(float *aspx, float *aspy); + void borderselect_sima(void); void mouseco_to_curtile(void); void mouse_select_sima(void); void select_swap_tface_uv(void); -void tface_do_clip(void); -void transform_tface_uv(int mode, int context); void mirrormenu_tface_uv(void); void mirror_tface_uv(char mirroraxis); void hide_tface_uv(int swap); @@ -55,8 +62,7 @@ void unlink_selection(void); void select_linked_tface_uv(int mode); void toggle_uv_select(int mode); void pin_tface_uv(int mode); -int minmax_tface_uv(float *min, float *max); void weld_align_menu_tface_uv(void); void weld_align_tface_uv(char tool); -void get_connected_limit_tface_uv(float *limit); +void be_square_tface_uv(struct Mesh *me); diff --git a/source/blender/include/BIF_transform.h b/source/blender/include/BIF_transform.h index cff4dea2e14..fc67aaf0f9b 100755 --- a/source/blender/include/BIF_transform.h +++ b/source/blender/include/BIF_transform.h @@ -74,6 +74,7 @@ void BIF_setLocalAxisConstraint(char axis, char *text); void BIF_setLocalLockConstraint(char axis, char *text); void BIF_drawConstraint(void); void BIF_drawPropCircle(void); +void BIF_getPropCenter(float *center); void BIF_TransformSetUndo(char *str); diff --git a/source/blender/include/transform.h b/source/blender/include/transform.h index 4e6eaa7150c..8ec878a60b1 100755 --- a/source/blender/include/transform.h +++ b/source/blender/include/transform.h @@ -105,6 +105,11 @@ typedef struct TransDataExtension { float obmat[3][3]; /* Object matrix */ } TransDataExtension; +typedef struct TransData2D { + float loc[3]; /* Location of data used to transform (x,y,0) */ + float *loc2d; /* Pointer to real 2d location of data */ +} TransData2D; + typedef struct TransData { float dist; /* Distance needed to affect element (for Proportionnal Editing) */ float rdist; /* Distance to the nearest element (for Proportionnal Editing) */ @@ -135,6 +140,7 @@ typedef struct TransInfo { int total; /* total number of transformed data */ TransData *data; /* transformed data (array) */ TransDataExtension *ext; /* transformed data extension (array) */ + TransData2D *data2d; /* transformed data for 2d (array) */ TransCon con; /* transformed constraint */ NumInput num; /* numerical input */ char redraw; /* redraw flag */ @@ -147,9 +153,13 @@ typedef struct TransInfo { short idx_max; /* maximum index on the input vector */ float snap[3]; /* Snapping Gears */ - float viewmat[4][4]; /* copy from G.vd, prevents feedback */ - float viewinv[4][4]; + float viewmat[4][4]; /* copy from G.vd, prevents feedback, */ + float viewinv[4][4]; /* and to make sure we don't have to */ + float persmat[4][4]; /* access G.vd from other space types */ float persinv[4][4]; + short persp; + short around; + char spacetype; /* spacetype where transforming is */ float vec[3]; /* translation, to show for widget */ float mat[3][3]; /* rot/rescale, to show for widget */ @@ -184,6 +194,8 @@ typedef struct TransInfo { #define T_CAMERA 16 // when shift pressed, higher resolution transform. cannot rely on G.qual, need event! #define T_SHIFT_MOD 32 + // trans on points, having no rotation/scale +#define T_POINTS 64 // for manipulator exceptions, like scaling using center point, drawing help lines #define T_USES_MANIPULATOR 128 @@ -193,11 +205,14 @@ typedef struct TransInfo { #define T_NULL_ONE 512 #define T_NO_ZERO 1024 -#define T_PROP_EDIT 2048 -#define T_PROP_CONNECTED 4096 +#define T_PROP_EDIT 2048 +#define T_PROP_CONNECTED 4096 /* if MMB is pressed or not */ -#define T_MMB_PRESSED 8192 +#define T_MMB_PRESSED 8192 +#define T_V3D_ALIGN 16384 +#define T_2D_EDIT 32768 /* for 2d views like uv or ipo */ +#define T_CLIP_UV 65536 /* transinfo->con->mode */ #define CON_APPLY 1 @@ -218,6 +233,14 @@ typedef struct TransInfo { void checkFirstTime(void); +void setTransformViewMatrices(TransInfo *t); +void convertViewVec(TransInfo *t, float *vec, short dx, short dy); +void projectIntView(TransInfo *t, float *vec, int *adr); +void projectFloatView(TransInfo *t, float *vec, float *adr); + +void convertVecToDisplayNum(float *vec, float *num); +void convertDisplayNumToVec(float *num, float *vec); + void initWarp(TransInfo *t); int Warp(TransInfo *t, short mval[2]); @@ -260,6 +283,8 @@ int BoneEnvelope(TransInfo *t, short mval[2]); /*********************** transform_conversions.c ********** */ struct ListBase; void count_bone_select(TransInfo *t, struct ListBase *lb, int do_it); +void flushTransUVs(TransInfo *t); +int clipUVTransform(TransInfo *t, float *vec, int resize); /*********************** exported from transform_manipulator.c ********** */ struct ScrArea; diff --git a/source/blender/src/drawimage.c b/source/blender/src/drawimage.c index 3fac54390b4..7897f95a197 100644 --- a/source/blender/src/drawimage.c +++ b/source/blender/src/drawimage.c @@ -80,6 +80,7 @@ #include "BIF_glutil.h" #include "BIF_space.h" #include "BIF_screen.h" +#include "BIF_transform.h" #include "BSE_trans_types.h" #include "BSE_view.h" @@ -89,8 +90,6 @@ #include "blendef.h" #include "butspace.h" // event codes -float prop_cent[3]= {0.0, 0.0, 0.0}, prop_size= 0.1; - /** * Sets up the fields of the View2D member of the SpaceImage struct * This routine can be called in two modes: @@ -239,7 +238,7 @@ void uvco_to_areaco(float *vec, short *mval) } } -void uvco_to_areaco_noclip(float *vec, short *mval) +void uvco_to_areaco_noclip(float *vec, int *mval) { float x, y; @@ -509,28 +508,12 @@ static unsigned int *get_part_from_ibuf(ImBuf *ibuf, short startx, short starty, return rectmain; } -/* now only in use by drawimage.c */ -static void draw_prop_circle() +static void draw_image_transform(ImBuf *ibuf) { - if (G.scene->proportional) { - float tmat[4][4], imat[4][4]; - - if(G.moving) { - BIF_ThemeColor(TH_GRID); - - mygetmatrix(tmat); - Mat4Invert(imat, tmat); - - drawcircball(GL_LINE_LOOP, prop_cent, prop_size, imat); - } - } -} + if(G.moving) { + float aspx, aspy, center[3]; -static void draw_image_prop_circle(ImBuf *ibuf) -{ - float aspx, aspy; - - if(G.moving && G.scene->proportional) { + BIF_drawConstraint(); if(ibuf==0 || ibuf->rect==0 || ibuf->x==0 || ibuf->y==0) { aspx= aspy= 1.0; @@ -540,12 +523,16 @@ static void draw_image_prop_circle(ImBuf *ibuf) aspy= 256.0/ibuf->y; } + BIF_getPropCenter(center); + /* scale and translate the circle into place and draw it */ glPushMatrix(); glScalef(aspx, aspy, 1.0); - glTranslatef((1/aspx)*prop_cent[0] - prop_cent[0], - (1/aspy)*prop_cent[1] - prop_cent[1], 0.0); - draw_prop_circle(); + glTranslatef((1/aspx)*center[0] - center[0], + (1/aspy)*center[1] - center[1], 0.0); + + BIF_drawPropCircle(); + glPopMatrix(); } } @@ -937,7 +924,7 @@ void drawimagespace(ScrArea *sa, void *spacedata) calc_image_view(G.sima, 'f'); /* float */ } - draw_image_prop_circle(ibuf); + draw_image_transform(ibuf); myortho2(-0.375, sa->winx-0.375, -0.375, sa->winy-0.375); draw_image_view_icon(); @@ -1111,7 +1098,7 @@ void image_viewcentre(void) if(size<=0.01) size= 0.01; - G.sima->zoom= 1.0/size; + G.sima->zoom= 0.7/size; calc_image_view(G.sima, 'p'); diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c index 0d2ab8ab9ed..d14584ffc5b 100644 --- a/source/blender/src/editobject.c +++ b/source/blender/src/editobject.c @@ -3441,6 +3441,10 @@ void std_rmouse_transform(void (*xf_func)(int, int)) #endif Transform(); } + else if(curarea->spacetype==SPACE_IMAGE) { + initTransform(TFM_TRANSLATION, CTX_NONE); + Transform(); + } else if(xf_func) xf_func('g', 0); diff --git a/source/blender/src/editsima.c b/source/blender/src/editsima.c index 6f79f1daae9..d0745ef1fe2 100644 --- a/source/blender/src/editsima.c +++ b/source/blender/src/editsima.c @@ -74,6 +74,7 @@ #include "BIF_space.h" #include "BIF_editsima.h" #include "BIF_toolbox.h" +#include "BIF_transform.h" #include "BIF_mywindow.h" #include "BSE_drawipo.h" @@ -241,41 +242,7 @@ void clever_numbuts_sima(void) } } -static void sima_pixelgrid(float *loc, float sx, float sy) -{ - float y; - float x; - - if(G.sima->flag & SI_PIXELSNAP) { - if(G.sima->image && G.sima->image->ibuf) { - x= G.sima->image->ibuf->x; - y= G.sima->image->ibuf->y; - - sx= floor(x*sx)/x; - if(G.sima->flag & SI_CLIP_UV) { - CLAMP(sx, 0, 1.0); - } - loc[0]= sx; - - sy= floor(y*sy)/y; - if(G.sima->flag & SI_CLIP_UV) { - CLAMP(sy, 0, 1.0); - } - loc[1]= sy; - } - else { - loc[0]= sx; - loc[1]= sy; - } - } - else { - loc[0]= sx; - loc[1]= sy; - } -} - - -static void be_square_tface_uv(Mesh *me) +void be_square_tface_uv(Mesh *me) { TFace *tface; MFace *mface; @@ -333,522 +300,32 @@ static void be_square_tface_uv(Mesh *me) } } } - } -void tface_do_clip(void) +void transform_aspect_ratio_tface_uv(float *aspx, float *aspy) { - Mesh *me; - TFace *tface; - int a, b; - - if( is_uv_tface_editing_allowed()==0 ) return; - me= get_mesh(OBACT); - tface= me->tface; - - for(a=0; atotface; a++, tface++) { - if(tface->flag & TF_SELECT) { - for(b=0; b<4; b++) { - CLAMP(tface->uv[b][0], 0.0, 1.0); - CLAMP(tface->uv[b][1], 0.0, 1.0); - } - } - } - + int w, h; + + transform_width_height_tface_uv(&w, &h); + *aspx= (float)w/256.0f; + *aspy= (float)h/256.0f; } -void transform_tface_uv(int mode, int context) // 2 args, for callback +void transform_width_height_tface_uv(int *width, int *height) { - MFace *mface; - TFace *tface; - Mesh *me; - TransVert *transmain, *tv; - - float dist, xdist, ydist, aspx, aspy; - float asp, dx1, dx2, dy1, dy2, phi, dphi, co, si; - float size[2], sizefac; - float dx, dy, dvec2[2], dvec[2], div, cent[2]; - float x, y, min[2], max[2], vec[2], xtra[2], ivec[2]; - int xim, yim, tot=0, a, b, firsttime=1, afbreek=0; - int propmode= 0, proptot= 0, midtog= 0, proj= 0, prop_recalc= 1; - unsigned short event = 0; - short mval[2], val, xo, yo, xn, yn, xc, yc; - char str[80]; - extern float prop_size, prop_cent[3]; - - if( is_uv_tface_editing_allowed()==0 ) return; - me= get_mesh(OBACT); - - if(G.scene->proportional) propmode= 1; - - min[0]= min[1]= 10000.0; - max[0]= max[1]= -10000.0; - - calc_image_view(G.sima, 'f'); - if(G.sima->image && G.sima->image->ibuf) { - xim= G.sima->image->ibuf->x; - yim= G.sima->image->ibuf->y; + *width= G.sima->image->ibuf->x; + *height= G.sima->image->ibuf->y; } else { - xim= yim= 256; + *width= 256; + *height= 256; } - aspx = (float)xim/256.0; - aspy = (float)yim/256.0; - - /* which vertices are involved? */ - tface= me->tface; - mface= me->mface; - for(a=me->totface; a>0; a--, tface++, mface++) { - if(tface->flag & TF_SELECT) { - if(tface->flag & TF_SEL1) tot++; - if(tface->flag & TF_SEL2) tot++; - if(tface->flag & TF_SEL3) tot++; - if(mface->v4 && (tface->flag & TF_SEL4)) tot++; - if(propmode) { - if(mface->v4) proptot+=4; - else proptot+=3; - } - } - } - if(tot==0) return; - if(propmode) tot= proptot; - - G.moving= 1; - prop_size/= 3; - - tv=transmain= MEM_callocN(tot*sizeof(TransVert), "transmain"); - - tface= me->tface; - mface= me->mface; - for(a=me->totface; a>0; a--, tface++, mface++) { - if(tface->flag & TF_SELECT) { - if (tface->flag & TF_SEL1 || propmode) { - tv->loc= tface->uv[0]; - if(tface->flag & TF_SEL1) tv->flag= 1; - tv++; - } - if (tface->flag & TF_SEL2 || propmode) { - tv->loc= tface->uv[1]; - if(tface->flag & TF_SEL2) tv->flag= 1; - tv++; - } - if (tface->flag & TF_SEL3 || propmode) { - tv->loc= tface->uv[2]; - if(tface->flag & TF_SEL3) tv->flag= 1; - tv++; - } - if(mface->v4) { - if (tface->flag & TF_SEL4 || propmode) { - tv->loc= tface->uv[3]; - if(tface->flag & TF_SEL4) tv->flag= 1; - tv++; - } - } - } - } - - a= tot; - tv= transmain; - while(a--) { - tv->oldloc[0]= tv->loc[0]; - tv->oldloc[1]= tv->loc[1]; - if(tv->flag) { - DO_MINMAX2(tv->loc, min, max); - } - tv++; - } - - cent[0]= (min[0]+max[0])/2.0; - cent[1]= (min[1]+max[1])/2.0; - prop_cent[0]= cent[0]; - prop_cent[1]= cent[1]; - - ipoco_to_areaco_noclip(G.v2d, cent, mval); - xc= mval[0]; - yc= mval[1]; - - getmouseco_areawin(mval); - xo= xn= mval[0]; - yo= yn= mval[1]; - dvec[0]= dvec[1]= 0.0; - dx1= xc-xn; - dy1= yc-yn; - phi= 0.0; - - - sizefac= sqrt( (float)((yc-yn)*(yc-yn)+(xn-xc)*(xn-xc)) ); - if(sizefac<2.0) sizefac= 2.0; - - while(afbreek==0) { - getmouseco_areawin(mval); - if((mval[0]!=xo || mval[1]!=yo) || firsttime) { - if(propmode && prop_recalc && transmain) { - a= tot; - tv= transmain; - - while(a--) { - if(tv->oldloc[0]oldloc[0]-min[0]; - else if(tv->oldloc[0]>max[0]) xdist= tv->oldloc[0]-max[0]; - else xdist= 0.0; - xdist*= aspx; - - if(tv->oldloc[1]oldloc[1]-min[1]; - else if(tv->oldloc[1]>max[1]) ydist= tv->oldloc[1]-max[1]; - else ydist= 0.0; - ydist*= aspy; - - dist= sqrt(xdist*xdist + ydist*ydist); - if(dist==0.0) tv->fac= 1.0; - else if(dist > prop_size) tv->fac= 0.0; - else { - dist= (prop_size-dist)/prop_size; - - switch(G.scene->prop_mode) { - case PROP_SHARP: - tv->fac= dist*dist; - break; - case PROP_SMOOTH: - tv->fac= 3.0f*dist*dist - 2.0f*dist*dist*dist; - break; - case PROP_ROOT: - tv->fac= (float)sqrt(dist); - break; - case PROP_LIN: - tv->fac= dist; - break; - case PROP_CONST: - tv->fac= 1.0f; - break; - case PROP_SPHERE: - tv->fac= (float)sqrt(2*dist - dist * dist); - break; - default: - tv->fac= 1; - } - } - tv++; - } - prop_recalc= 0; - } - if(mode=='g') { - - dx= mval[0]- xo; - dy= mval[1]- yo; - - div= G.v2d->mask.xmax-G.v2d->mask.xmin; - dvec[0]+= (G.v2d->cur.xmax-G.v2d->cur.xmin)*(dx)/div; - - div= G.v2d->mask.ymax-G.v2d->mask.ymin; - dvec[1]+= (G.v2d->cur.ymax-G.v2d->cur.ymin)*(dy)/div; - - if(midtog) dvec[proj]= 0.0; - - dvec2[0]= dvec[0]; - dvec2[1]= dvec[1]; - apply_keyb_grid(dvec2, 0.0, 1.0/8.0, 1.0/16.0, U.flag & USER_AUTOGRABGRID); - apply_keyb_grid(dvec2+1, 0.0, 1.0/8.0, 1.0/16.0, U.flag & USER_AUTOGRABGRID); - - vec[0]= dvec2[0]; - vec[1]= dvec2[1]; - - if(G.sima->flag & SI_CLIP_UV) { - if(vec[0]< -min[0]) vec[0]= -min[0]; - if(vec[1]< -min[1]) vec[1]= -min[1]; - if(vec[0]> 1.0-max[0]) vec[0]= 1.0-max[0]; - if(vec[1]> 1.0-max[1]) vec[1]= 1.0-max[1]; - } - tv= transmain; - if (propmode) { - for(a=0; aoldloc[0]+tv->fac*vec[0]; - y= tv->oldloc[1]+tv->fac*vec[1]; - - sima_pixelgrid(tv->loc, x, y); - } - } else { - for(a=0; aoldloc[0]+vec[0]; - y= tv->oldloc[1]+vec[1]; - - sima_pixelgrid(tv->loc, x, y); - } - } - - if(G.sima->flag & SI_BE_SQUARE) be_square_tface_uv(me); - - if (G.sima->flag & SI_COORDFLOATS) { - ivec[0]= vec[0]; - ivec[1]= vec[1]; - } - else { - ivec[0]= (vec[0]*xim); - ivec[1]= (vec[1]*yim); - } - - sprintf(str, "X: %.4f Y: %.4f ", ivec[0], ivec[1]); - headerprint(str); - } - else if(mode=='r') { - - dx2= xc-mval[0]; - dy2= yc-mval[1]; - - div= sqrt( (dx1*dx1+dy1*dy1)*(dx2*dx2+dy2*dy2)); - if(div>1.0) { - - dphi= (dx1*dx2+dy1*dy2)/div; - dphi= saacos(dphi); - if( (dx1*dy2-dx2*dy1)<0.0 ) dphi= -dphi; - - if(G.qual & LR_SHIFTKEY) phi+= dphi/30.0; - else phi+= dphi; - - apply_keyb_grid(&phi, 0.0, (5.0/180)*M_PI, (1.0/180)*M_PI, U.flag & USER_AUTOROTGRID); - - dx1= dx2; - dy1= dy2; - - co= cos(phi); - si= sin(phi); - asp= (float)yim/(float)xim; - - tv= transmain; - for(a=0; afac); - si= sin(phi*tv->fac); - } - x= ( co*( tv->oldloc[0]-cent[0]) - si*asp*(tv->oldloc[1]-cent[1]) ) +cent[0]; - y= ( si*( tv->oldloc[0]-cent[0])/asp + co*(tv->oldloc[1]-cent[1]) ) +cent[1]; - sima_pixelgrid(tv->loc, x, y); - - if(G.sima->flag & SI_CLIP_UV) { - if(tv->loc[0]<0.0) tv->loc[0]= 0.0; - else if(tv->loc[0]>1.0) tv->loc[0]= 1.0; - if(tv->loc[1]<0.0) tv->loc[1]= 0.0; - else if(tv->loc[1]>1.0) tv->loc[1]= 1.0; - } - } - - sprintf(str, "Rot: %.3f ", phi*180.0/M_PI); - headerprint(str); - } - } - else if(mode=='s') { - size[0]= size[1]= (sqrt((float)((yc-mval[1])*(yc-mval[1])+(mval[0]-xc)*(mval[0]-xc))))/sizefac; - if(midtog) size[proj]= 1.0; - - apply_keyb_grid(size, 0.0, 0.1, 0.01, U.flag & USER_AUTOSIZEGRID); - apply_keyb_grid(size+1, 0.0, 0.1, 0.01, U.flag & USER_AUTOSIZEGRID); - - xtra[0]= xtra[1]= 0; - - if(G.sima->flag & SI_CLIP_UV) { - /* boundbox limit: four step plan: XTRA X */ - - a=b= 0; - if(size[0]*(min[0]-cent[0]) + cent[0] + xtra[0] < 0) - a= -size[0]*(min[0]-cent[0]) - cent[0]; - if(size[0]*(max[0]-cent[0]) + cent[0] + xtra[0] > 1.0) - b= 1.0 - size[0]*(max[0]-cent[0]) - cent[0]; - xtra[0]= (a+b)/2; - - /* SIZE X */ - if(size[0]*(min[0]-cent[0]) + cent[0] + xtra[0] < 0) - size[0]= (-cent[0]-xtra[0])/(min[0]-cent[0]); - if(size[0]*(max[0]-cent[0]) + cent[0] +xtra[0] > 1.0) - size[0]= (1.0-cent[0]-xtra[0])/(max[0]-cent[0]); - - /* XTRA Y */ - a=b= 0; - if(size[1]*(min[1]-cent[1]) + cent[1] + xtra[1] < 0) - a= -size[1]*(min[1]-cent[1]) - cent[1]; - if(size[1]*(max[1]-cent[1]) + cent[1] + xtra[1] > 1.0) - b= 1.0 - size[1]*(max[1]-cent[1]) - cent[1]; - xtra[1]= (a+b)/2; - - /* SIZE Y */ - if(size[1]*(min[1]-cent[1]) + cent[1] +xtra[1] < 0) - size[1]= (-cent[1]-xtra[1])/(min[1]-cent[1]); - if(size[1]*(max[1]-cent[1]) + cent[1] + xtra[1]> 1.0) - size[1]= (1.0-cent[1]-xtra[1])/(max[1]-cent[1]); - } - - /* if(midtog==0) { */ - /* if(size[1]>size[0]) size[1]= size[0]; */ - /* else if(size[0]>size[1]) size[0]= size[1]; */ - /* } */ - - tv= transmain; - if (propmode) { - for(a=0; afac*size[0] + 1.00-tv->fac)*(tv->oldloc[0]-cent[0])+ cent[0] + xtra[0]; - y= (tv->fac*size[1] + 1.00-tv->fac)*(tv->oldloc[1]-cent[1])+ cent[1] + xtra[1]; - sima_pixelgrid(tv->loc, x, y); - } - - } else { - for(a=0; aoldloc[0]-cent[0])+ cent[0] + xtra[0]; - y= size[1]*(tv->oldloc[1]-cent[1])+ cent[1] + xtra[1]; - sima_pixelgrid(tv->loc, x, y); - } - } - - sprintf(str, "sizeX: %.3f sizeY: %.3f", size[0], size[1]); - headerprint(str); - } - - xo= mval[0]; - yo= mval[1]; - - /* Need to force a recalculate since we may be - * drawing modified UVs. - */ - if(G.sima->flag & SI_DRAWSHADOW){ - DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA); - object_handle_update(OBACT); - } - - if(G.sima->lock) { - force_draw_plus(SPACE_VIEW3D, 0); - } - else force_draw(0); - - firsttime= 0; - - } - else BIF_wait_for_statechange(); - - while(qtest()) { - event= extern_qread(&val); - if(val) { - switch(event) { - case ESCKEY: - case RIGHTMOUSE: - case LEFTMOUSE: - case SPACEKEY: - case RETKEY: - afbreek= 1; - break; - case MIDDLEMOUSE: - midtog= ~midtog; - if(midtog) { - if( abs(mval[0]-xn) > abs(mval[1]-yn)) proj= 1; - else proj= 0; - firsttime= 1; - } - break; - case WHEELDOWNMOUSE: - case PADPLUSKEY: - if(propmode) { - prop_size*= 1.1; - prop_recalc= 1; - firsttime= 1; - } - break; - case WHEELUPMOUSE: - case PADMINUS: - if(propmode) { - prop_size*= 0.90909090; - prop_recalc= 1; - firsttime= 1; - } - break; - case WKEY: - case XKEY: - case YKEY: - if(midtog) { - if(event==XKEY) { - if(proj==1) midtog= ~midtog; - else if(proj==0) proj= 1; - } - else if(event==YKEY) { - if(proj==0) midtog= ~midtog; - else if(proj==1) proj= 0; - } - } - else { - if(event==XKEY) { - midtog= ~midtog; - proj= 1; - } - else if(event==YKEY) { - midtog= ~midtog; - proj= 0; - } - } - firsttime= 1; - break; - default: - arrows_move_cursor(event); - } - } - - if(afbreek) break; - } - } - - if(event==ESCKEY || event == RIGHTMOUSE) { - tv= transmain; - for(a=0; aloc[0]= tv->oldloc[0]; - tv->loc[1]= tv->oldloc[1]; - } - } - - MEM_freeN(transmain); - - if(mode=='g') if(G.sima->flag & SI_BE_SQUARE) be_square_tface_uv(me); - - G.moving= 0; - prop_size*= 3; - - object_uvs_changed(OBACT); - - if(event!=ESCKEY && event!=RIGHTMOUSE) - BIF_undo_push("Transform UV"); } void mirror_tface_uv(char mirroraxis) { - MFace *mface; - TFace *tface; - Mesh *me; - float min[2], max[2], cent[2]; - int a, axis; - - if( is_uv_tface_editing_allowed()==0 ) return; - me= get_mesh(OBACT); - - if (!minmax_tface_uv(min, max)) - return; - - cent[0]= min[0]+max[0]; - cent[1]= min[1]+max[1]; - - if(mirroraxis=='x') axis= 0; - else axis= 1; - - tface= me->tface; - mface= me->mface; - for(a=me->totface; a>0; a--, tface++, mface++) { - if(tface->flag & TF_SELECT) { - if(tface->flag & TF_SEL1) - tface->uv[0][axis]= cent[axis] - tface->uv[0][axis]; - if(tface->flag & TF_SEL2) - tface->uv[1][axis]= cent[axis] - tface->uv[1][axis]; - if(tface->flag & TF_SEL3) - tface->uv[2][axis]= cent[axis] - tface->uv[2][axis]; - if(mface->v4 && (tface->flag & TF_SEL4)) - tface->uv[3][axis]= cent[axis] - tface->uv[3][axis]; - } - } - - object_uvs_changed(OBACT); + Mirror((short)mirroraxis); } void mirrormenu_tface_uv(void) @@ -938,6 +415,7 @@ void weld_align_menu_tface_uv(void) if(mode==1) BIF_undo_push("Weld UV"); else if(mode==2 || mode==3) BIF_undo_push("Align UV"); } + void select_swap_tface_uv(void) { Mesh *me; @@ -997,8 +475,8 @@ static void find_nearest_tface(TFace **nearesttf, MFace **nearestmf) Mesh *me; TFace *tf; MFace *mf; - int a, i, nverts, mindist, dist, fcenter[2]; - short mval[2], uval[2]; + int a, i, nverts, mindist, dist, fcenter[2], uval[2]; + short mval[2]; getmouseco_areawin(mval); @@ -1034,7 +512,7 @@ static void find_nearest_tface(TFace **nearesttf, MFace **nearestmf) } } -static int nearest_uv_between(TFace *tf, int nverts, int id, short *mval, short *uval) +static int nearest_uv_between(TFace *tf, int nverts, int id, short *mval, int *uval) { float m[3], v1[3], v2[3], c1, c2; int id1, id2; @@ -1066,8 +544,8 @@ static void find_nearest_uv(TFace **nearesttf, unsigned int *nearestv, int *near Mesh *me; TFace *tf; MFace *mf; - int a, i, nverts, mindist, dist; - short mval[2], uval[2]; + int a, i, nverts, mindist, dist, uval[2]; + short mval[2]; getmouseco_areawin(mval); @@ -1263,7 +741,7 @@ void mouse_select_sima(void) force_draw(1); BIF_undo_push("Select UV"); - std_rmouse_transform(transform_tface_uv); + rightmouse_transform(); } void borderselect_sima(void) @@ -1651,7 +1129,6 @@ void stitch_uv_tface(int mode) MEM_freeN(sortblock); if(G.sima->flag & SI_BE_SQUARE) be_square_tface_uv(me); - if(G.sima->flag & SI_CLIP_UV) tface_do_clip(); BIF_undo_push("Stitch UV"); diff --git a/source/blender/src/editview.c b/source/blender/src/editview.c index f30324ff7ac..5da61321346 100644 --- a/source/blender/src/editview.c +++ b/source/blender/src/editview.c @@ -781,19 +781,23 @@ int gesture(void) if(i) { if(curarea->spacetype==SPACE_IPO) transform_ipo(i); - else if(curarea->spacetype==SPACE_IMAGE) transform_tface_uv(i, 0); else if(curarea->spacetype==SPACE_OOPS) transform_oops('g', 0); else { + int context; + + if(curarea->spacetype==SPACE_IMAGE) context= CTX_NONE; + else context= CTX_NONE; + if(i=='g') { - initTransform(TFM_TRANSLATION, CTX_NONE); + initTransform(TFM_TRANSLATION, context); Transform(); } else if(i=='r') { - initTransform(TFM_ROTATION, CTX_NONE); + initTransform(TFM_ROTATION, context); Transform(); } else { - initTransform(TFM_RESIZE, CTX_NONE); + initTransform(TFM_RESIZE, context); Transform(); } } diff --git a/source/blender/src/header_image.c b/source/blender/src/header_image.c index 55fc3cb845d..5506bee1b57 100644 --- a/source/blender/src/header_image.c +++ b/source/blender/src/header_image.c @@ -70,6 +70,7 @@ #include "BIF_space.h" #include "BIF_toets.h" #include "BIF_toolbox.h" +#include "BIF_transform.h" #include "BIF_writeimage.h" #include "BSE_filesel.h" @@ -300,12 +301,6 @@ void do_image_buttons(unsigned short event) } break; - case B_CLIP_UV: - tface_do_clip(); - - if (OBACT) object_uvs_changed(OBACT); - break; - case B_SIMAGEPAINTTOOL: // check for packed file here allqueue(REDRAWIMAGE, 0); @@ -843,13 +838,16 @@ static void do_image_uvs_transformmenu(void *arg, int event) { switch(event) { case 0: /* Grab */ - transform_tface_uv('g', 0); + initTransform(TFM_TRANSLATION, CTX_NONE); + Transform(); break; case 1: /* Rotate */ - transform_tface_uv('r', 0); + initTransform(TFM_ROTATION, CTX_NONE); + Transform(); break; case 2: /* Scale */ - transform_tface_uv('s', 0); + initTransform(TFM_RESIZE, CTX_NONE); + Transform(); break; } } diff --git a/source/blender/src/space.c b/source/blender/src/space.c index e9bfc2a3e78..8327aa6a206 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -3871,8 +3871,10 @@ static void winqreadimagespace(ScrArea *sa, void *spacedata, BWinEvent *evt) unwrap_lscm(); break; case GKEY: - if((G.qual==0)) - transform_tface_uv('g', 0); + if((G.qual==0) && is_uv_tface_editing_allowed()) { + initTransform(TFM_TRANSLATION, CTX_NONE); + Transform(); + } break; case HKEY: if(G.qual==LR_ALTKEY) @@ -3916,12 +3918,16 @@ static void winqreadimagespace(ScrArea *sa, void *spacedata, BWinEvent *evt) pin_tface_uv(1); break; case RKEY: - if((G.qual==0)) - transform_tface_uv('r', 0); + if((G.qual==0) && is_uv_tface_editing_allowed()) { + initTransform(TFM_ROTATION, CTX_NONE); + Transform(); + } break; case SKEY: - if((G.qual==0)) - transform_tface_uv('s', 0); + if((G.qual==0) && is_uv_tface_editing_allowed()) { + initTransform(TFM_RESIZE, CTX_NONE); + Transform(); + } break; case VKEY: if((G.qual==0)) diff --git a/source/blender/src/transform.c b/source/blender/src/transform.c index 53d55c7b772..4d540159816 100755 --- a/source/blender/src/transform.c +++ b/source/blender/src/transform.c @@ -60,6 +60,7 @@ #include "DNA_texture_types.h" #include "DNA_userdef_types.h" #include "DNA_view3d_types.h" +#include "DNA_space_types.h" #include "BIF_editview.h" /* arrows_move_cursor */ #include "BIF_gl.h" @@ -71,6 +72,8 @@ #include "BIF_mywindow.h" /* warp_pointer */ #include "BIF_toolbox.h" /* notice */ #include "BIF_editmesh.h" +#include "BIF_editsima.h" +#include "BIF_drawimage.h" /* uvco_to_areaco_noclip */ #include "BKE_global.h" #include "BKE_utildefines.h" @@ -116,7 +119,7 @@ static void helpline(TransInfo *t, float *vec) } getmouseco_areawin(mval); - project_float(vecrot, cent); // no overflow in extreme cases + projectFloatView(t, vecrot, cent); // no overflow in extreme cases if(cent[0]!=IS_CLIPPED) { persp(PERSP_WIN); @@ -161,7 +164,7 @@ float InputScaleRatio(TransInfo *t, short mval[2]) { float InputHorizontalRatio(TransInfo *t, short mval[2]) { int y, pad; - pad = G.vd->area->winx / 10; + pad = curarea->winx / 10; if (t->flag & T_SHIFT_MOD) { /* deal with Shift key by adding motion / 10 to motion before shift press */ @@ -170,7 +173,143 @@ float InputHorizontalRatio(TransInfo *t, short mval[2]) { else { y = mval[0]; } - return (float)(y - pad) / (float)(G.vd->area->winx - 2 * pad); + return (float)(y - pad) / (float)(curarea->winx - 2 * pad); +} + +/* ************************** SPACE DEPENDANT CODE **************************** */ + +void setTransformViewMatrices(TransInfo *t) +{ + if(t->spacetype==SPACE_VIEW3D) { + Mat4CpyMat4(t->viewmat, G.vd->viewmat); + Mat4CpyMat4(t->viewinv, G.vd->viewinv); + Mat4CpyMat4(t->persmat, G.vd->persmat); + Mat4CpyMat4(t->persinv, G.vd->persinv); + t->persp= G.vd->persp; + } + else { + Mat4One(t->viewmat); + Mat4One(t->viewinv); + Mat4One(t->persmat); + Mat4One(t->persinv); + t->persp = 0; // ortho + } +} + +void convertViewVec(TransInfo *t, float *vec, short dx, short dy) +{ + if (t->spacetype==SPACE_VIEW3D) + window_to_3d(vec, dx, dy); + else if(t->spacetype==SPACE_IMAGE) { + float divx, divy, aspx, aspy; + + transform_aspect_ratio_tface_uv(&aspx, &aspy); + + divx= G.v2d->mask.xmax-G.v2d->mask.xmin; + divy= G.v2d->mask.ymax-G.v2d->mask.ymin; + + vec[0]= aspx*(G.v2d->cur.xmax-G.v2d->cur.xmin)*(dx)/divx; + vec[1]= aspy*(G.v2d->cur.ymax-G.v2d->cur.ymin)*(dy)/divy; + vec[2]= 0.0f; + } +} + +void projectIntView(TransInfo *t, float *vec, int *adr) +{ + if (t->spacetype==SPACE_VIEW3D) + project_int(vec, adr); + else if(t->spacetype==SPACE_IMAGE) { + float aspx, aspy, v[2]; + + transform_aspect_ratio_tface_uv(&aspx, &aspy); + v[0]= vec[0]/aspx; + v[1]= vec[1]/aspy; + + uvco_to_areaco_noclip(v, adr); + } +} + +void projectFloatView(TransInfo *t, float *vec, float *adr) +{ + if (t->spacetype==SPACE_VIEW3D) + project_float(vec, adr); + else if(t->spacetype==SPACE_IMAGE) { + int a[2]; + + projectIntView(t, vec, a); + adr[0]= a[0]; + adr[1]= a[1]; + } +} + +void convertVecToDisplayNum(float *vec, float *num) +{ + TransInfo *t= BIF_GetTransInfo(); + + VECCOPY(num, vec); + + if ((t->spacetype==SPACE_IMAGE) && (t->mode==TFM_TRANSLATION)) { + float aspx, aspy; + + if((G.sima->flag & SI_COORDFLOATS)==0) { + int width, height; + transform_width_height_tface_uv(&width, &height); + + num[0] *= width; + num[1] *= height; + } + + transform_aspect_ratio_tface_uv(&aspx, &aspy); + num[0] /= aspx; + num[1] /= aspy; + } +} + +void convertDisplayNumToVec(float *num, float *vec) +{ + TransInfo *t= BIF_GetTransInfo(); + + VECCOPY(vec, num); + + if ((t->spacetype==SPACE_IMAGE) && (t->mode==TFM_TRANSLATION)) { + float aspx, aspy; + + if((G.sima->flag & SI_COORDFLOATS)==0) { + int width, height; + transform_width_height_tface_uv(&width, &height); + + vec[0] /= width; + vec[1] /= height; + } + + transform_aspect_ratio_tface_uv(&aspx, &aspy); + vec[0] *= aspx; + vec[1] *= aspy; + } +} + +static void viewRedrawForce(TransInfo *t) +{ + if(t->spacetype==SPACE_VIEW3D) + force_draw(0); + else if(t->spacetype==SPACE_IMAGE) { + if(G.sima->lock) force_draw_plus(SPACE_VIEW3D, 0); + else force_draw(0); + } +} + +static void viewRedrawPost(TransInfo *t) +{ + if(t->spacetype==SPACE_VIEW3D) { + allqueue(REDRAWBUTSOBJECT, 0); + allqueue(REDRAWVIEW3D, 0); + } + else if(t->spacetype==SPACE_IMAGE) { + allqueue(REDRAWIMAGE, 0); + allqueue(REDRAWVIEW3D, 0); + } + + scrarea_queue_headredraw(curarea); } /* ************************** TRANSFORMATIONS **************************** */ @@ -247,11 +386,8 @@ static void view_editmove(unsigned short event) break; } - if (refresh) { - Mat4CpyMat4(Trans.viewmat, G.vd->viewmat); - Mat4CpyMat4(Trans.viewinv, G.vd->viewinv); - Mat4CpyMat4(Trans.persinv, G.vd->persinv); - } + if (refresh) + setTransformViewMatrices(&Trans); } void checkFirstTime() { @@ -316,7 +452,7 @@ static void transformEvent(unsigned short event, short val) { break; case SPACEKEY: - if (G.qual & LR_ALTKEY) { + if ((Trans.spacetype==SPACE_VIEW3D) && (G.qual & LR_ALTKEY)) { short mval[2]; getmouseco_sc(mval); @@ -421,14 +557,14 @@ static void transformEvent(unsigned short event, short val) { else { if (G.qual == 0) setUserConstraint(&Trans, (CON_AXIS0), "along %s X"); - else if (G.qual == LR_SHIFTKEY) + else if ((G.qual == LR_SHIFTKEY) && ((Trans.flag & T_2D_EDIT)==0)) setUserConstraint(&Trans, (CON_AXIS1|CON_AXIS2), "locking %s X"); } } else { if (G.qual == 0) setConstraint(&Trans, mati, (CON_AXIS0), "along global X"); - else if (G.qual == LR_SHIFTKEY) + else if ((G.qual == LR_SHIFTKEY) && ((Trans.flag & T_2D_EDIT)==0)) setConstraint(&Trans, mati, (CON_AXIS1|CON_AXIS2), "locking global X"); } Trans.redraw = 1; @@ -443,14 +579,14 @@ static void transformEvent(unsigned short event, short val) { else { if (G.qual == 0) setUserConstraint(&Trans, (CON_AXIS1), "along %s Y"); - else if (G.qual == LR_SHIFTKEY) + else if ((G.qual == LR_SHIFTKEY) && ((Trans.flag & T_2D_EDIT)==0)) setUserConstraint(&Trans, (CON_AXIS0|CON_AXIS2), "locking %s Y"); } } else { if (G.qual == 0) setConstraint(&Trans, mati, (CON_AXIS1), "along global Y"); - else if (G.qual == LR_SHIFTKEY) + else if ((G.qual == LR_SHIFTKEY) && ((Trans.flag & T_2D_EDIT)==0)) setConstraint(&Trans, mati, (CON_AXIS0|CON_AXIS2), "locking global Y"); } Trans.redraw = 1; @@ -465,11 +601,11 @@ static void transformEvent(unsigned short event, short val) { else { if (G.qual == 0) setUserConstraint(&Trans, (CON_AXIS2), "along %s Z"); - else if (G.qual == LR_SHIFTKEY) + else if ((G.qual == LR_SHIFTKEY) && ((Trans.flag & T_2D_EDIT)==0)) setUserConstraint(&Trans, (CON_AXIS0|CON_AXIS1), "locking %s Z"); } } - else { + else if ((Trans.flag & T_2D_EDIT)==0) { if (G.qual == 0) setConstraint(&Trans, mati, (CON_AXIS2), "along global Z"); else if (G.qual == LR_SHIFTKEY) @@ -554,11 +690,15 @@ void initTransform(int mode, int context) { Trans.context = context; - calc_manipulator_stats(curarea); - Mat3CpyMat4(Trans.spacemtx, G.vd->twmat); - initTrans(&Trans); // internal data, mouse, vectors + if(Trans.spacetype==SPACE_VIEW3D) { + calc_manipulator_stats(curarea); + Mat3CpyMat4(Trans.spacemtx, G.vd->twmat); + } + else + Mat3One(Trans.spacemtx); + initTransModeFlags(&Trans, mode); // modal settings in struct Trans createTransData(&Trans); // make TransData structs from selection @@ -687,9 +827,7 @@ void Transform() special_aftertrans_update(&Trans); /* send events out for redraws */ - allqueue(REDRAWVIEW3D, 0); - allqueue(REDRAWBUTSOBJECT, 0); - scrarea_queue_headredraw(curarea); + viewRedrawPost(&Trans); } /* ************************** Manipulator init and main **************************** */ @@ -848,9 +986,7 @@ void ManipulatorTransform() special_aftertrans_update(&Trans); /* send events out for redraws */ - allqueue(REDRAWVIEW3D, 0); - allqueue(REDRAWBUTSOBJECT, 0); - scrarea_queue_headredraw(curarea); + viewRedrawPost(&Trans); } /* ************************** TRANSFORMATIONS **************************** */ @@ -878,8 +1014,8 @@ void initWarp(TransInfo *t) float center[3]; VECCOPY(center, t->data[i].center); Mat3MulVecfl(t->data[i].mtx, center); - Mat4MulVecfl(G.vd->viewmat, center); - VecSubf(center, center, G.vd->viewmat[3]); + Mat4MulVecfl(t->viewmat, center); + VecSubf(center, center, t->viewmat[3]); if (i) MinMax3(min, max, center); else { @@ -921,8 +1057,8 @@ int Warp(TransInfo *t, short mval[2]) VecSubf(gcursor, gcursor, G.obedit->obmat[3]); Mat3MulVecfl(t->data->smtx, gcursor); } - Mat4MulVecfl(G.vd->viewmat, cursor); - VecSubf(cursor, cursor, G.vd->viewmat[3]); + Mat4MulVecfl(t->viewmat, cursor); + VecSubf(cursor, cursor, t->viewmat[3]); // amount of degrees for warp, 450 = allow to create 360 degree warp circumfac= 450.0f*(mval[1] - t->imval[1]) / (float)(curarea->winy); @@ -955,8 +1091,8 @@ int Warp(TransInfo *t, short mval[2]) VECCOPY(vec, td->iloc); Mat3MulVecfl(td->mtx, vec); - Mat4MulVecfl(G.vd->viewmat, vec); - VecSubf(vec, vec, G.vd->viewmat[3]); + Mat4MulVecfl(t->viewmat, vec); + VecSubf(vec, vec, t->viewmat[3]); dist= vec[0]-cursor[0]; @@ -970,8 +1106,8 @@ int Warp(TransInfo *t, short mval[2]) loc[1]= co*vec[1]+cursor[1]; loc[2]= vec[2]; - Mat4MulVecfl(G.vd->viewinv, loc); - VecSubf(loc, loc, G.vd->viewinv[3]); + Mat4MulVecfl(t->viewinv, loc); + VecSubf(loc, loc, t->viewinv[3]); Mat3MulVecfl(td->smtx, loc); VecSubf(loc, loc, td->iloc); @@ -983,7 +1119,7 @@ int Warp(TransInfo *t, short mval[2]) headerprint(str); - force_draw(0); + viewRedrawForce(t); helpline(t, gcursor); @@ -1012,7 +1148,7 @@ int Shear(TransInfo *t, short mval[2]) int i; char str[50]; - Mat3CpyMat4(persmat, G.vd->viewmat); + Mat3CpyMat4(persmat, t->viewmat); Mat3Inv(persinv, persmat); value = -0.005f * ((float)(t->center2d[0] - mval[0]) - t->fac); @@ -1067,7 +1203,7 @@ int Shear(TransInfo *t, short mval[2]) headerprint(str); - force_draw(0); + viewRedrawForce(t); helpline (t, t->center); @@ -1119,7 +1255,10 @@ static void headerResize(TransInfo *t, float vec[3], char *str) { } } else { - sprintf(str, "Size X: %s Y: %s Z: %s%s %s", &tvec[0], &tvec[20], &tvec[40], t->con.text, t->proptext); + if (t->flag & T_2D_EDIT) + sprintf(str, "Size X: %s Y: %s%s %s", &tvec[0], &tvec[20], t->con.text, t->proptext); + else + sprintf(str, "Size X: %s Y: %s Z: %s%s %s", &tvec[0], &tvec[20], &tvec[40], t->con.text, t->proptext); } } @@ -1162,7 +1301,7 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) { } /* local constraint shouldn't alter center */ - if (G.vd->around == V3D_LOCAL) { + if (t->around == V3D_LOCAL) { if (t->flag & T_OBJECT) { VECCOPY(center, td->center); // not supported in editmode yet } @@ -1189,7 +1328,7 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) { Mat3ToSize(tmat, fsize); } - if ((G.vd->flag & V3D_ALIGN)==0) { // align mode doesn't rotate objects itself + if ((t->flag & T_V3D_ALIGN)==0) { // align mode doesn't rotate objects itself /* handle ipokeys? */ if(td->tdi) { TransDataIpokey *tdi= td->tdi; @@ -1224,7 +1363,7 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) { } } /* For individual element center, Editmode need to use iloc */ - if (t->flag & T_EDIT) + if (t->flag & T_POINTS) VecSubf(vec, td->iloc, center); else VecSubf(vec, td->center, center); @@ -1232,7 +1371,7 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) { Mat3MulVecfl(tmat, vec); VecAddf(vec, vec, center); - if (t->flag & T_EDIT) + if (t->flag & T_POINTS) VecSubf(vec, vec, td->iloc); else VecSubf(vec, vec, td->center); @@ -1254,7 +1393,7 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) { int Resize(TransInfo *t, short mval[2]) { - TransData *td = t->data; + TransData *td; float size[3], mat[3][3]; float ratio; int i; @@ -1292,18 +1431,29 @@ int Resize(TransInfo *t, short mval[2]) headerResize(t, size, str); - for(i = 0 ; i < t->total; i++, td++) { + for(i = 0, td=t->data; i < t->total; i++, td++) { if (td->flag & TD_NOACTION) break; ElementResize(t, td, mat); } + /* evil hack - redo resize if cliiping needeed */ + if (t->flag & T_CLIP_UV && clipUVTransform(t, size, 1)) { + SizeToMat3(size, mat); + + if (t->con.applySize) + t->con.applySize(t, NULL, mat); + + for(i = 0, td=t->data; i < t->total; i++, td++) + ElementResize(t, td, mat); + } + recalcData(t); headerprint(str); - force_draw(0); + viewRedrawForce(t); if(!(t->flag & T_USES_MANIPULATOR)) helpline (t, t->center); @@ -1387,7 +1537,7 @@ int ToSphere(TransInfo *t, short mval[2]) headerprint(str); - force_draw(0); + viewRedrawForce(t); return 1; } @@ -1410,7 +1560,7 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3]) { float vec[3], totmat[3][3], smat[3][3]; float eul[3], fmat[3][3], quat[4]; - if (t->flag & T_EDIT) { + if (t->flag & T_POINTS) { Mat3MulMat3(totmat, mat, td->mtx); Mat3MulMat3(smat, td->smtx, totmat); @@ -1434,7 +1584,7 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3]) { /* vec now is the location where the object has to be */ VecSubf(vec, vec, td->center); Mat3MulVecfl(td->smtx, vec); - + if(td->tdi) { TransDataIpokey *tdi= td->tdi; add_tdi_poin(tdi->locx, tdi->oldloc, vec[0]); @@ -1442,13 +1592,13 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3]) { add_tdi_poin(tdi->locz, tdi->oldloc+2, vec[2]); } else VecAddf(td->loc, td->iloc, vec); - + if(td->flag & TD_USEQUAT) { Mat3MulSerie(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0); Mat3ToQuat(fmat, quat); // Actual transform QuatMul(td->ext->quat, quat, td->ext->iquat); } - else if ((G.vd->flag & V3D_ALIGN)==0) { // align mode doesn't rotate objects itself + else if ((t->flag & T_V3D_ALIGN)==0) { // align mode doesn't rotate objects itself float obmat[3][3]; /* are there ipo keys? */ @@ -1507,7 +1657,7 @@ static void applyRotation(TransInfo *t, float angle, float axis[3]) int i; /* saving original center */ - if (G.vd->around == V3D_LOCAL) { + if (t->around == V3D_LOCAL) { VECCOPY(center, t->center); } @@ -1519,7 +1669,7 @@ static void applyRotation(TransInfo *t, float angle, float axis[3]) break; /* local constraint shouldn't alter center */ - if (G.vd->around == V3D_LOCAL) { + if (t->around == V3D_LOCAL) { if (t->flag & T_OBJECT) VECCOPY(t->center, td->center); // not supported in editmode yet } @@ -1536,7 +1686,7 @@ static void applyRotation(TransInfo *t, float angle, float axis[3]) } /* restoring original center */ - if (G.vd->around == V3D_LOCAL) { + if (t->around == V3D_LOCAL) { VECCOPY(t->center, center); } } @@ -1623,7 +1773,7 @@ int Rotation(TransInfo *t, short mval[2]) headerprint(str); - force_draw(0); + viewRedrawForce(t); if(!(t->flag & T_USES_MANIPULATOR)) helpline (t, t->center); @@ -1659,7 +1809,7 @@ static void applyTrackball(TransInfo *t, float axis1[3], float axis2[3], float a if (td->flag & TD_NOACTION) break; - if (G.vd->around == V3D_LOCAL) { + if (t->around == V3D_LOCAL) { if (t->flag & T_OBJECT) VECCOPY(t->center, td->center); // not supported in editmode yet } @@ -1725,7 +1875,7 @@ int Trackball(TransInfo *t, short mval[2]) headerprint(str); - force_draw(0); + viewRedrawForce(t); if(!(t->flag & T_USES_MANIPULATOR)) helpline (t, t->center); @@ -1736,33 +1886,49 @@ int Trackball(TransInfo *t, short mval[2]) void initTranslation(TransInfo *t) { - t->idx_max = 2; - t->num.idx_max = 2; - t->snap[0] = 0.0f; - t->snap[1] = G.vd->gridview * 1.0f; - t->snap[2] = t->snap[1] * 0.1f; + t->idx_max = (t->flag & T_2D_EDIT)? 1: 2; + t->num.idx_max = t->idx_max; t->transform = Translation; - /* initgrabz() defines a factor for perspective depth correction, used in window_to_3d() */ - if (G.obedit) { - float vec[3]; - - VECCOPY(vec, t->center); - Mat4MulVecfl(G.obedit->obmat, vec); - initgrabz(vec[0], vec[1], vec[2]); + if(t->spacetype == SPACE_VIEW3D) { + /* initgrabz() defines a factor for perspective depth correction, used in window_to_3d() */ + if(G.obedit) { + float vec[3]; + + VECCOPY(vec, t->center); + Mat4MulVecfl(G.obedit->obmat, vec); + initgrabz(vec[0], vec[1], vec[2]); + } + else initgrabz(t->center[0], t->center[1], t->center[2]); + + t->snap[0] = 0.0f; + t->snap[1] = G.vd->gridview * 1.0f; + t->snap[2] = t->snap[1] * 0.1f; + } + else if(t->spacetype == SPACE_IMAGE) { + t->snap[0] = 0.0f; + t->snap[1] = 0.125f; + t->snap[2] = 0.0625f; + } + else { + t->snap[0] = 0.0f; + t->snap[1] = t->snap[2] = 1.0f; } - else initgrabz(t->center[0], t->center[1], t->center[2]); } static void headerTranslation(TransInfo *t, float vec[3], char *str) { char tvec[60]; + float dvec[3]; + + convertVecToDisplayNum(vec, dvec); + if (hasNumInput(&t->num)) { outputNumInput(&(t->num), tvec); } else { - sprintf(&tvec[0], "%.4f", vec[0]); - sprintf(&tvec[20], "%.4f", vec[1]); - sprintf(&tvec[40], "%.4f", vec[2]); + sprintf(&tvec[0], "%.4f", dvec[0]); + sprintf(&tvec[20], "%.4f", dvec[1]); + sprintf(&tvec[40], "%.4f", dvec[2]); } if (t->con.mode & CON_APPLY) { @@ -1778,7 +1944,10 @@ static void headerTranslation(TransInfo *t, float vec[3], char *str) { } } else { - sprintf(str, "Dx: %s Dy: %s Dz: %s%s %s", &tvec[0], &tvec[20], &tvec[40], t->con.text, t->proptext); + if(t->flag & T_2D_EDIT) + sprintf(str, "Dx: %s Dy: %s%s %s", &tvec[0], &tvec[20], t->con.text, t->proptext); + else + sprintf(str, "Dx: %s Dy: %s Dz: %s%s %s", &tvec[0], &tvec[20], &tvec[40], t->con.text, t->proptext); } } @@ -1822,12 +1991,12 @@ int Translation(TransInfo *t, short mval[2]) if(t->flag & T_SHIFT_MOD) { float dvec[3]; /* calculate the main translation and the precise one separate */ - window_to_3d(dvec, (short)(mval[0] - t->shiftmval[0]), (short)(mval[1] - t->shiftmval[1])); + convertViewVec(t, dvec, (short)(mval[0] - t->shiftmval[0]), (short)(mval[1] - t->shiftmval[1])); VecMulf(dvec, 0.1f); - window_to_3d(t->vec, (short)(t->shiftmval[0] - t->imval[0]), (short)(t->shiftmval[1] - t->imval[1])); + convertViewVec(t, t->vec, (short)(t->shiftmval[0] - t->imval[0]), (short)(t->shiftmval[1] - t->imval[1])); VecAddf(t->vec, t->vec, dvec); } - else window_to_3d(t->vec, (short)(mval[0] - t->imval[0]), (short)(mval[1] - t->imval[1])); + else convertViewVec(t, t->vec, (short)(mval[0] - t->imval[0]), (short)(mval[1] - t->imval[1])); if (t->con.mode & CON_APPLY) { float pvec[3] = {0.0f, 0.0f, 0.0f}; @@ -1843,11 +2012,15 @@ int Translation(TransInfo *t, short mval[2]) applyTranslation(t, t->vec); + /* evil hack - redo translation if cliiping needeed */ + if (t->flag & T_CLIP_UV && clipUVTransform(t, t->vec, 0)) + applyTranslation(t, t->vec); + recalcData(t); headerprint(str); - force_draw(0); + viewRedrawForce(t); return 1; } @@ -1880,9 +2053,9 @@ int ShrinkFatten(TransInfo *t, short mval[2]) char str[50]; TransData *td = t->data; - window_to_3d(t->vec, (short)(mval[0] - t->imval[0]), (short)(mval[1] - t->imval[1])); - Projf(vec, t->vec, G.vd->viewinv[1]); - ratio = Inpf(G.vd->viewinv[1], vec) * -2.0f; + convertViewVec(t, t->vec, (short)(mval[0] - t->imval[0]), (short)(mval[1] - t->imval[1])); + Projf(vec, t->vec, t->viewinv[1]); + ratio = Inpf(t->viewinv[1], vec) * -2.0f; snapGrid(t, &ratio); @@ -1917,7 +2090,7 @@ int ShrinkFatten(TransInfo *t, short mval[2]) headerprint(str); - force_draw(0); + viewRedrawForce(t); return 1; } @@ -2002,7 +2175,7 @@ int Tilt(TransInfo *t, short mval[2]) headerprint(str); - force_draw(0); + viewRedrawForce(t); helpline (t, t->center); @@ -2031,9 +2204,9 @@ int PushPull(TransInfo *t, short mval[2]) char str[50]; TransData *td = t->data; - window_to_3d(t->vec, (short)(mval[0] - t->imval[0]), (short)(mval[1] - t->imval[1])); - Projf(vec, t->vec, G.vd->viewinv[1]); - distance = Inpf(G.vd->viewinv[1], vec) * 2.0f; + convertViewVec(t, t->vec, (short)(mval[0] - t->imval[0]), (short)(mval[1] - t->imval[1])); + Projf(vec, t->vec, t->viewinv[1]); + distance = Inpf(t->viewinv[1], vec) * 2.0f; snapGrid(t, &distance); @@ -2083,7 +2256,7 @@ int PushPull(TransInfo *t, short mval[2]) headerprint(str); - force_draw(0); + viewRedrawForce(t); return 1; } @@ -2174,7 +2347,7 @@ int Crease(TransInfo *t, short mval[2]) headerprint(str); - force_draw(0); + viewRedrawForce(t); helpline (t, t->center); @@ -2190,14 +2363,14 @@ void Mirror(short mode) float size[3]; int i; - Mat3One(mati); - Mat3CpyMat4(matview, G.vd->viewinv); - Mat3Ortho(matview); - Trans.context = CTX_NO_PET; initTrans(&Trans); // internal data, mouse, vectors + Mat3One(mati); + Mat3CpyMat4(matview, Trans.viewinv); // t->viewinv was set in initTrans + Mat3Ortho(matview); + initTransModeFlags(&Trans, TFM_MIRROR); // modal settings in struct Trans createTransData(&Trans); // make TransData structs from selection @@ -2277,9 +2450,7 @@ void Mirror(short mode) postTrans(&Trans); /* send events out for redraws */ - allqueue(REDRAWVIEW3D, 0); - allqueue(REDRAWBUTSOBJECT, 0); - scrarea_queue_headredraw(curarea); + viewRedrawPost(&Trans); } /* ******************** EditBone (B-bone) width scaling *************** */ @@ -2372,7 +2543,7 @@ int BoneSize(TransInfo *t, short mval[2]) headerprint(str); - force_draw(0); + viewRedrawForce(t); if(!(t->flag & T_USES_MANIPULATOR)) helpline (t, t->center); diff --git a/source/blender/src/transform_constraints.c b/source/blender/src/transform_constraints.c index 86e10793f06..7efe4a5cd55 100755 --- a/source/blender/src/transform_constraints.c +++ b/source/blender/src/transform_constraints.c @@ -62,6 +62,7 @@ #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" +#include "DNA_space_types.h" #include "DNA_view3d_types.h" #include "BIF_screen.h" @@ -512,8 +513,9 @@ void setLocalConstraint(TransInfo *t, int mode, const char text[]) { void setUserConstraint(TransInfo *t, int mode, const char ftext[]) { float mtx[3][3]; char text[40]; + short twmode= (t->spacetype==SPACE_VIEW3D)? G.vd->twmode: V3D_MANIP_GLOBAL; - switch(G.vd->twmode) { + switch(twmode) { case V3D_MANIP_GLOBAL: sprintf(text, ftext, "global"); Mat3One(mtx); @@ -630,13 +632,15 @@ void BIF_drawConstraint(void) TransInfo *t = BIF_GetTransInfo(); TransCon *tc = &(t->con); + if (t->spacetype!=SPACE_VIEW3D) + return; if (!(tc->mode & CON_APPLY)) return; if (t->flag & T_USES_MANIPULATOR) return; /* nasty exception for Z constraint in camera view */ - if( (t->flag & T_OBJECT) && G.vd->camera==OBACT && G.vd->persp>1) + if((t->flag & T_OBJECT) && G.vd->camera==OBACT && G.vd->persp>1) return; if (tc->drawExtra) { @@ -648,7 +652,7 @@ void BIF_drawConstraint(void) short mval[2]; char col2[3] = {255,255,255}; getmouseco_areawin(mval); - window_to_3d(vec, (short)(mval[0] - t->con.imval[0]), (short)(mval[1] - t->con.imval[1])); + convertViewVec(t, vec, (short)(mval[0] - t->con.imval[0]), (short)(mval[1] - t->con.imval[1])); VecAddf(vec, vec, tc->center); drawLine(tc->center, tc->mtx[0], 'x', 0); @@ -694,7 +698,7 @@ void BIF_drawPropCircle() mygetmatrix(tmat); Mat4Invert(imat, tmat); - + drawcircball(GL_LINE_LOOP, t->center, t->propsize, imat); /* if editmode we restore */ @@ -702,6 +706,16 @@ void BIF_drawPropCircle() } } +void BIF_getPropCenter(float *center) +{ + TransInfo *t = BIF_GetTransInfo(); + + if (t && t->flag & T_PROP_EDIT) { + VECCOPY(center, t->center); + } + else + center[0] = center[1] = center[2] = 0.0f; +} static void drawObjectConstraint(TransInfo *t) { int i; @@ -844,8 +858,8 @@ void setNearestAxis(TransInfo *t) of two 2D points 30 pixels apart (that's the last factor in the formula) after projecting them with window_to_3d and then get the length of that vector. */ - zfac= G.vd->persmat[0][3]*t->center[0]+ G.vd->persmat[1][3]*t->center[1]+ G.vd->persmat[2][3]*t->center[2]+ G.vd->persmat[3][3]; - zfac = VecLength(G.vd->persinv[0]) * 2.0f/curarea->winx * zfac * 30.0f; + zfac= t->persmat[0][3]*t->center[0]+ t->persmat[1][3]*t->center[1]+ t->persmat[2][3]*t->center[2]+ t->persmat[3][3]; + zfac = VecLength(t->persinv[0]) * 2.0f/curarea->winx * zfac * 30.0f; for (i = 0; i<3; i++) { VECCOPY(axis, t->con.mtx[i]); @@ -853,7 +867,7 @@ void setNearestAxis(TransInfo *t) VecMulf(axis, zfac); /* now we can project to get window coordinate */ VecAddf(axis, axis, t->con.center); - project_int(axis, icoord); + projectIntView(t, axis, icoord); axis[0] = (float)(icoord[0] - t->center2d[0]); axis[1] = (float)(icoord[1] - t->center2d[1]); diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c index 6c623a23d82..a54b83bea0b 100755 --- a/source/blender/src/transform_conversions.c +++ b/source/blender/src/transform_conversions.c @@ -39,6 +39,8 @@ #else #include #endif +#include +#include #include "MEM_guardedalloc.h" @@ -60,6 +62,7 @@ #include "DNA_object_force.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" +#include "DNA_space_types.h" #include "DNA_texture_types.h" #include "DNA_view3d_types.h" #include "DNA_world_types.h" @@ -81,6 +84,7 @@ #include "BKE_ipo.h" #include "BKE_lattice.h" #include "BKE_mball.h" +#include "BKE_mesh.h" #include "BKE_modifier.h" #include "BKE_object.h" #include "BKE_softbody.h" @@ -92,6 +96,7 @@ #include "BIF_editconstraint.h" #include "BIF_editarmature.h" #include "BIF_editmesh.h" +#include "BIF_editsima.h" #include "BIF_gl.h" #include "BIF_poseobject.h" #include "BIF_mywindow.h" @@ -209,14 +214,13 @@ static void sort_trans_data(TransInfo *t) } } - /* distance calculated from not-selected vertex to nearest selected vertex warning; this is loops inside loop, has minor N^2 issues, but by sorting list it is OK */ static void set_prop_dist(TransInfo *t, short with_dist) { TransData *tob; int a; - + for(a=0, tob= t->data; atotal; a++, tob++) { tob->rdist= 0.0f; // init, it was mallocced @@ -483,6 +487,7 @@ static void createTransPose(Object *ob, TransInfo *t) if (!(ob->lay & G.vd->lay)) return; /* count total */ + t->total= 0; count_bone_select(t, &arm->bonebase, 1); if(t->total==0 && t->mode==TFM_TRANSLATION) { @@ -490,7 +495,7 @@ static void createTransPose(Object *ob, TransInfo *t) count_bone_select(t, &arm->bonebase, 1); } if(t->total==0) return; - + t->flag |= T_POSE; t->poseobj= ob; // we also allow non-active objects to be transformed, in weightpaint @@ -1077,7 +1082,6 @@ static void editmesh_set_connectivity_distance(int total, float *vectors, EditVe } } - static void VertsToTransData(TransData *td, EditVert *eve) { td->flag = 0; @@ -1197,6 +1201,181 @@ static void createTransEditVerts(TransInfo *t) } +/* ********************* UV ****************** */ + +static void UVsToTransData(TransData *td, TransData2D *td2d, float *uv, int selected) +{ + float aspx, aspy; + + transform_aspect_ratio_tface_uv(&aspx, &aspy); + + /* uv coords are scaled by aspects. this is needed for rotations and + proportional editing to be consistent with the stretchted uv coords + that are displayed. this also means that for display and numinput, + and when the the uv coords are flushed, these are converted each time */ + td2d->loc[0] = uv[0]*aspx; + td2d->loc[1] = uv[1]*aspy; + td2d->loc[2] = 0.0f; + td2d->loc2d = uv; + + td->flag = 0; + td->loc = td2d->loc; + VECCOPY(td->center, td->loc); + VECCOPY(td->iloc, td->loc); + + memset(td->axismtx, 0, sizeof(td->axismtx)); + td->axismtx[2][2] = 1.0f; + + td->ext= NULL; td->tdi= NULL; td->val= NULL; + + if(selected) { + td->flag |= TD_SELECTED; + td->dist= 0.0; + } + else + td->dist= MAXFLOAT; + + Mat3One(td->mtx); + Mat3One(td->smtx); +} + +static void createTransUVs(TransInfo *t) +{ + TransData *td = NULL; + TransData2D *td2d = NULL; + Mesh *me; + TFace *tf; + MFace *mf; + int a, count=0, countsel=0; + int propmode = t->flag & T_PROP_EDIT; + + if(is_uv_tface_editing_allowed()==0) return; + me= get_mesh(OBACT); + + /* count */ + tf= me->tface; + mf= me->mface; + for(a=me->totface; a>0; a--, tf++, mf++) { + if(mf->v3 && tf->flag & TF_SELECT) { + if(tf->flag & TF_SEL1) countsel++; + if(tf->flag & TF_SEL2) countsel++; + if(tf->flag & TF_SEL3) countsel++; + if(mf->v4 && (tf->flag & TF_SEL4)) countsel++; + if(propmode) + count += (mf->v4)? 4: 3; + } + } + + /* note: in prop mode we need at least 1 selected */ + if (countsel==0) return; + + t->total= (propmode)? count: countsel; + t->data= MEM_mallocN(t->total*sizeof(TransData), "TransObData(UV Editing)"); + /* for each 2d uv coord a 3d vector is allocated, so that they can be + treated just as if they were 3d verts */ + t->data2d= MEM_mallocN(t->total*sizeof(TransData2D), "TransObData2D(UV Editing)"); + + if(G.sima->flag & SI_CLIP_UV) + t->flag |= T_CLIP_UV; + + td= t->data; + td2d= t->data2d; + tf= me->tface; + mf= me->mface; + for(a=me->totface; a>0; a--, tf++, mf++) { + if(mf->v3 && tf->flag & TF_SELECT) { + if(tf->flag & TF_SEL1 || propmode) + UVsToTransData(td++, td2d++, tf->uv[0], (tf->flag & TF_SEL1)); + if(tf->flag & TF_SEL2 || propmode) + UVsToTransData(td++, td2d++, tf->uv[1], (tf->flag & TF_SEL2)); + if(tf->flag & TF_SEL3 || propmode) + UVsToTransData(td++, td2d++, tf->uv[2], (tf->flag & TF_SEL3)); + + if(mf->v4 && (tf->flag & TF_SEL4 || propmode)) + UVsToTransData(td++, td2d++, tf->uv[3], (tf->flag & TF_SEL4)); + } + } +} + +void flushTransUVs(TransInfo *t) +{ + TransData2D *td; + int a, width, height; + Object *ob= OBACT; + Mesh *me= get_mesh(ob); + float aspx, aspy, invx, invy; + + transform_aspect_ratio_tface_uv(&aspx, &aspy); + transform_width_height_tface_uv(&width, &height); + invx= 1.0f/aspx; + invy= 1.0f/aspy; + + /* flush to 2d vector from internally used 3d vector */ + for(a=0, td= t->data2d; atotal; a++, td++) { + td->loc2d[0]= td->loc[0]*invx; + td->loc2d[1]= td->loc[1]*invy; + + if((G.sima->flag & SI_PIXELSNAP) && (t->state != TRANS_CANCEL)) { + td->loc2d[0]= floor(width*td->loc2d[0])/width; + td->loc2d[1]= floor(height*td->loc2d[1])/height; + } + } + + if((G.sima->flag & SI_BE_SQUARE) && (t->state != TRANS_CANCEL)) + be_square_tface_uv(me); + + /* this is overkill if G.sima->lock is not set, but still needed */ + object_uvs_changed(ob); +} + +int clipUVTransform(TransInfo *t, float *vec, int resize) +{ + TransData *td; + int a, clipx=1, clipy=1; + float aspx, aspy, min[2], max[2]; + + transform_aspect_ratio_tface_uv(&aspx, &aspy); + min[0]= min[1]= 0.0f; + max[0]= aspx; max[1]= aspy; + + for(a=0, td= t->data; atotal; a++, td++) { + DO_MINMAX2(td->loc, min, max); + } + + if(resize) { + if(min[0] < 0.0f && t->center[0] > 0.0f && t->center[0] < aspx*0.5f) + vec[0] *= t->center[0]/(t->center[0] - min[0]); + else if(max[0] > aspx && t->center[0] < aspx) + vec[0] *= (t->center[0] - aspx)/(t->center[0] - max[0]); + else + clipx= 0; + + if(min[1] < 0.0f && t->center[1] > 0.0f && t->center[1] < aspy*0.5f) + vec[1] *= t->center[1]/(t->center[1] - min[1]); + else if(max[1] > aspy && t->center[1] < aspy) + vec[1] *= (t->center[1] - aspy)/(t->center[1] - max[1]); + else + clipy= 0; + } + else { + if(min[0] < 0.0f) + vec[0] -= min[0]; + else if(max[0] > aspx) + vec[0] -= max[0]-aspx; + else + clipx= 0; + + if(min[1] < 0.0f) + vec[1] -= min[1]; + else if(max[1] > aspy) + vec[1] -= max[1]-aspy; + else + clipy= 0; + } + + return (clipx || clipy); +} + /* **************** IpoKey stuff, for Object TransData ********** */ /* storage of bezier triple. thats why -3 and +3! */ @@ -1527,8 +1706,8 @@ void special_aftertrans_update(TransInfo *t) reset_slowparents(); /* note; should actually only be done for all objects when a lamp is moved... (ton) */ - if(G.vd->drawtype == OB_SHADED) reshadeall_displist(); - + if(t->spacetype==SPACE_VIEW3D && G.vd->drawtype == OB_SHADED) + reshadeall_displist(); } static void createTransObject(TransInfo *t) @@ -1664,6 +1843,15 @@ void createTransData(TransInfo *t) sort_trans_data_dist(t); } } + else if (t->spacetype == SPACE_IMAGE) { + t->flag |= T_POINTS|T_2D_EDIT; + createTransUVs(t); + if(t->data && (t->flag & T_PROP_EDIT)) { + sort_trans_data(t); // makes selected become first in array + set_prop_dist(t, 1); + sort_trans_data_dist(t); + } + } else if (G.obedit) { t->ext = NULL; if (G.obedit->type == OB_MESH) { @@ -1697,11 +1885,12 @@ void createTransData(TransInfo *t) sort_trans_data_dist(t); } } - t->flag |= T_EDIT; + + t->flag |= T_EDIT|T_POINTS; /* exception... hackish, we want bonesize to use bone orientation matrix (ton) */ if(t->mode==TFM_BONESIZE) { - t->flag &= ~T_EDIT; + t->flag &= ~(T_EDIT|T_POINTS); t->flag |= T_POSE; t->poseobj= ob; /* <- tsk tsk, this is going to give issues one day */ } diff --git a/source/blender/src/transform_generics.c b/source/blender/src/transform_generics.c index 1ba6dd45345..b16b59d0cfa 100755 --- a/source/blender/src/transform_generics.c +++ b/source/blender/src/transform_generics.c @@ -43,6 +43,9 @@ #include "DNA_view3d_types.h" #include "DNA_userdef_types.h" #include "DNA_constraint_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" +#include "DNA_mesh_types.h" #include "BIF_screen.h" #include "BIF_resources.h" @@ -50,6 +53,7 @@ #include "BIF_gl.h" #include "BIF_editarmature.h" #include "BIF_editmesh.h" +#include "BIF_editsima.h" #include "BKE_action.h" #include "BKE_anim.h" @@ -61,6 +65,7 @@ #include "BKE_global.h" #include "BKE_ipo.h" #include "BKE_lattice.h" +#include "BKE_mesh.h" #include "BKE_object.h" #include "BKE_utildefines.h" @@ -83,8 +88,11 @@ extern TransInfo Trans; /* From transform.c */ /* ************************** Functions *************************** */ -void getViewVector(float coord[3], float vec[3]) { - if (G.vd->persp) +void getViewVector(float coord[3], float vec[3]) +{ + TransInfo *t = BIF_GetTransInfo(); + + if (t->persp) { float p1[4], p2[4]; @@ -92,18 +100,18 @@ void getViewVector(float coord[3], float vec[3]) { p1[3] = 1.0f; VECCOPY(p2, p1); p2[3] = 1.0f; - Mat4MulVec4fl(G.vd->viewmat, p2); + Mat4MulVec4fl(t->viewmat, p2); p2[0] = 2.0f * p2[0]; p2[1] = 2.0f * p2[1]; p2[2] = 2.0f * p2[2]; - Mat4MulVec4fl(G.vd->viewinv, p2); + Mat4MulVec4fl(t->viewinv, p2); VecSubf(vec, p1, p2); } else { - VECCOPY(vec, G.vd->viewinv[2]); + VECCOPY(vec, t->viewinv[2]); } Normalise(vec); } @@ -224,6 +232,9 @@ void recalcData(TransInfo *t) else where_is_pose(ob); } + else if(t->spacetype==SPACE_IMAGE) { + flushTransUVs(t); + } else { Base *base; @@ -256,7 +267,8 @@ void recalcData(TransInfo *t) } /* update shaded drawmode while transform */ - if(G.vd->drawtype == OB_SHADED) reshadeall_displist(); + if(t->spacetype==SPACE_VIEW3D && G.vd->drawtype == OB_SHADED) + reshadeall_displist(); } @@ -366,9 +378,15 @@ void initTrans (TransInfo *t) Mat3One(t->mat); - Mat4CpyMat4(t->viewmat, G.vd->viewmat); - Mat4CpyMat4(t->viewinv, G.vd->viewinv); - Mat4CpyMat4(t->persinv, G.vd->persinv); + t->spacetype = curarea->spacetype; + if(t->spacetype==SPACE_VIEW3D) { + if(G.vd->flag & V3D_ALIGN) t->flag |= T_V3D_ALIGN; + t->around = G.vd->around; + } + else + t->around = V3D_CENTRE; + + setTransformViewMatrices(t); } /* Here I would suggest only TransInfo related issues, like free data & reset vars. Not redraws */ @@ -391,18 +409,30 @@ void postTrans (TransInfo *t) } if (t->ext) MEM_freeN(t->ext); - + if (t->data2d) { + MEM_freeN(t->data2d); + t->data2d= NULL; + } } -static void apply_grid3(float *val, int max_index, float fac1, float fac2, float fac3) +static void apply_grid3(TransInfo *t, float *val, int max_index, float fac1, float fac2, float fac3) { /* fac1 is for 'nothing', fac2 for CTRL, fac3 for SHIFT */ int invert = U.flag & USER_AUTOGRABGRID; int ctrl; int i; + float asp= 1.0f; for (i=0; i<=max_index; i++) { + /* evil hack - snapping needs to be adapted for image aspect ratio */ + if(t->spacetype==SPACE_IMAGE) { + float aspx, aspy; + transform_aspect_ratio_tface_uv(&aspx, &aspy); + if(i==0) asp= aspx; + else asp= aspy; + } + if(invert) { if(G.qual & LR_CTRLKEY) ctrl= 0; else ctrl= 1; @@ -412,21 +442,21 @@ static void apply_grid3(float *val, int max_index, float fac1, float fac2, float if(ctrl && (G.qual & LR_SHIFTKEY)) { if(fac3!= 0.0) { for (i=0; i<=max_index; i++) { - val[i]= fac3*(float)floor(val[i]/fac3 +.5); + val[i]= fac3*asp*(float)floor(val[i]/(fac3*asp) +.5); } } } else if(ctrl) { if(fac2!= 0.0) { for (i=0; i<=max_index; i++) { - val[i]= fac2*(float)floor(val[i]/fac2 +.5); + val[i]= fac2*asp*(float)floor(val[i]/(fac2*asp) +.5); } } } else { if(fac1!= 0.0) { for (i=0; i<=max_index; i++) { - val[i]= fac1*(float)floor(val[i]/fac1 +.5); + val[i]= fac1*asp*(float)floor(val[i]/(fac1*asp) +.5); } } } @@ -434,7 +464,7 @@ static void apply_grid3(float *val, int max_index, float fac1, float fac2, float } void snapGrid(TransInfo *t, float *val) { - apply_grid3(val, t->idx_max, t->snap[0], t->snap[1], t->snap[2]); + apply_grid3(t, val, t->idx_max, t->snap[0], t->snap[1], t->snap[2]); } void applyTransObjects(TransInfo *t) @@ -530,10 +560,10 @@ void calculateCenterCursor(TransInfo *t) VECCOPY(vec, t->center); Mat4MulVecfl(ob->obmat, vec); - project_int(vec, t->center2d); + projectIntView(t, vec, t->center2d); } else { - project_int(t->center, t->center2d); + projectIntView(t, t->center, t->center2d); } } @@ -562,10 +592,10 @@ void calculateCenterMedian(TransInfo *t) VECCOPY(vec, t->center); Mat4MulVecfl(ob->obmat, vec); - project_int(vec, t->center2d); + projectIntView(t, vec, t->center2d); } else { - project_int(t->center, t->center2d); + projectIntView(t, t->center, t->center2d); } } @@ -601,16 +631,16 @@ void calculateCenterBound(TransInfo *t) VECCOPY(vec, t->center); Mat4MulVecfl(ob->obmat, vec); - project_int(vec, t->center2d); + projectIntView(t, vec, t->center2d); } else { - project_int(t->center, t->center2d); + projectIntView(t, t->center, t->center2d); } } void calculateCenter(TransInfo *t) { - switch(G.vd->around) { + switch(t->around) { case V3D_CENTRE: calculateCenterBound(t); break; @@ -631,7 +661,7 @@ void calculateCenter(TransInfo *t) Object *ob= OBACT; if(ob) { VECCOPY(t->center, ob->obmat[3]); - project_int(t->center, t->center2d); + projectIntView(t, t->center, t->center2d); } } @@ -649,7 +679,7 @@ void calculateCenter(TransInfo *t) if( G.vd->camera==OBACT && G.vd->persp>1) { float axis[3]; /* persinv is nasty, use viewinv instead, always right */ - VECCOPY(axis, G.vd->viewinv[2]); + VECCOPY(axis, t->viewinv[2]); Normalise(axis); /* 6.0 = 6 grid units */ @@ -657,13 +687,15 @@ void calculateCenter(TransInfo *t) axis[1]= t->center[1]- 6.0f*axis[1]; axis[2]= t->center[2]- 6.0f*axis[2]; - project_int(axis, t->center2d); + projectIntView(t, axis, t->center2d); /* rotate only needs correct 2d center, grab needs initgrabz() value */ if(t->mode==TFM_TRANSLATION) VECCOPY(t->center, axis); } } - initgrabz(t->center[0], t->center[1], t->center[2]); + + if(t->spacetype==SPACE_VIEW3D) + initgrabz(t->center[0], t->center[1], t->center[2]); } void calculatePropRatio(TransInfo *t) diff --git a/source/blender/src/transform_numinput.c b/source/blender/src/transform_numinput.c index 6c254697011..aa35af7d312 100755 --- a/source/blender/src/transform_numinput.c +++ b/source/blender/src/transform_numinput.c @@ -103,8 +103,11 @@ short hasNumInput(NumInput *n) void applyNumInput(NumInput *n, float *vec) { short i, j; + float val[3]; if (hasNumInput(n)) { + convertDisplayNumToVec(n->val, val); + for (j=0; j<=n->idx_max; j++) { /* if AFFECTALL and no number typed and cursor not on number, use first number */ if (n->flag & NUM_AFFECT_ALL && n->idx != j && n->ctrl[j] == 0) @@ -115,11 +118,11 @@ void applyNumInput(NumInput *n, float *vec) if (n->ctrl[i] == 0 && n->flag & NUM_NULL_ONE) { vec[j] = 1.0f; } - else if (n->val[i] == 0.0f && n->flag & NUM_NO_ZERO) { + else if (val[i] == 0.0f && n->flag & NUM_NO_ZERO) { vec[j] = 0.0001f; } else { - vec[j] = n->val[i]; + vec[j] = val[i]; } } }