Bretch's patch for 2D transform. Thanks

Using new transform code to handle UV window.

With the ground work done, Transform could more easily be extended to handle IPO window now.

Tracker item: http://projects.blender.org/tracker/?func=detail&atid=127&aid=2946&group_id=9
This commit is contained in:
Martin Poirier 2005-08-23 18:13:30 +00:00
parent 207cbbd535
commit e12e2469c8
15 changed files with 654 additions and 737 deletions

@ -46,7 +46,7 @@ void image_viewmove(int mode);
void image_viewzoom(unsigned short event, int invert); void image_viewzoom(unsigned short event, int invert);
void image_viewcentre(void); void image_viewcentre(void);
void uvco_to_areaco(float *vec, short *mval); 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); void what_image(struct SpaceImage *sima);
#endif #endif

@ -30,6 +30,8 @@
* ***** END GPL/BL DUAL LICENSE BLOCK ***** * ***** END GPL/BL DUAL LICENSE BLOCK *****
*/ */
struct Mesh;
#define TF_PIN_MASK(id) (TF_PIN1 << id) #define TF_PIN_MASK(id) (TF_PIN1 << id)
#define TF_SEL_MASK(id) (TF_SEL1 << 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(void);
int is_uv_tface_editing_allowed_silent(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 borderselect_sima(void);
void mouseco_to_curtile(void); void mouseco_to_curtile(void);
void mouse_select_sima(void); void mouse_select_sima(void);
void select_swap_tface_uv(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 mirrormenu_tface_uv(void);
void mirror_tface_uv(char mirroraxis); void mirror_tface_uv(char mirroraxis);
void hide_tface_uv(int swap); void hide_tface_uv(int swap);
@ -55,8 +62,7 @@ void unlink_selection(void);
void select_linked_tface_uv(int mode); void select_linked_tface_uv(int mode);
void toggle_uv_select(int mode); void toggle_uv_select(int mode);
void pin_tface_uv(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_menu_tface_uv(void);
void weld_align_tface_uv(char tool); void weld_align_tface_uv(char tool);
void get_connected_limit_tface_uv(float *limit); void be_square_tface_uv(struct Mesh *me);

@ -74,6 +74,7 @@ void BIF_setLocalAxisConstraint(char axis, char *text);
void BIF_setLocalLockConstraint(char axis, char *text); void BIF_setLocalLockConstraint(char axis, char *text);
void BIF_drawConstraint(void); void BIF_drawConstraint(void);
void BIF_drawPropCircle(void); void BIF_drawPropCircle(void);
void BIF_getPropCenter(float *center);
void BIF_TransformSetUndo(char *str); void BIF_TransformSetUndo(char *str);

@ -105,6 +105,11 @@ typedef struct TransDataExtension {
float obmat[3][3]; /* Object matrix */ float obmat[3][3]; /* Object matrix */
} TransDataExtension; } 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 { typedef struct TransData {
float dist; /* Distance needed to affect element (for Proportionnal Editing) */ float dist; /* Distance needed to affect element (for Proportionnal Editing) */
float rdist; /* Distance to the nearest 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 */ int total; /* total number of transformed data */
TransData *data; /* transformed data (array) */ TransData *data; /* transformed data (array) */
TransDataExtension *ext; /* transformed data extension (array) */ TransDataExtension *ext; /* transformed data extension (array) */
TransData2D *data2d; /* transformed data for 2d (array) */
TransCon con; /* transformed constraint */ TransCon con; /* transformed constraint */
NumInput num; /* numerical input */ NumInput num; /* numerical input */
char redraw; /* redraw flag */ char redraw; /* redraw flag */
@ -147,9 +153,13 @@ typedef struct TransInfo {
short idx_max; /* maximum index on the input vector */ short idx_max; /* maximum index on the input vector */
float snap[3]; /* Snapping Gears */ float snap[3]; /* Snapping Gears */
float viewmat[4][4]; /* copy from G.vd, prevents feedback */ float viewmat[4][4]; /* copy from G.vd, prevents feedback, */
float viewinv[4][4]; 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]; float persinv[4][4];
short persp;
short around;
char spacetype; /* spacetype where transforming is */
float vec[3]; /* translation, to show for widget */ float vec[3]; /* translation, to show for widget */
float mat[3][3]; /* rot/rescale, 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 #define T_CAMERA 16
// when shift pressed, higher resolution transform. cannot rely on G.qual, need event! // when shift pressed, higher resolution transform. cannot rely on G.qual, need event!
#define T_SHIFT_MOD 32 #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 // for manipulator exceptions, like scaling using center point, drawing help lines
#define T_USES_MANIPULATOR 128 #define T_USES_MANIPULATOR 128
@ -198,6 +210,9 @@ typedef struct TransInfo {
/* if MMB is pressed or not */ /* 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 */ /* transinfo->con->mode */
#define CON_APPLY 1 #define CON_APPLY 1
@ -218,6 +233,14 @@ typedef struct TransInfo {
void checkFirstTime(void); 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); void initWarp(TransInfo *t);
int Warp(TransInfo *t, short mval[2]); int Warp(TransInfo *t, short mval[2]);
@ -260,6 +283,8 @@ int BoneEnvelope(TransInfo *t, short mval[2]);
/*********************** transform_conversions.c ********** */ /*********************** transform_conversions.c ********** */
struct ListBase; struct ListBase;
void count_bone_select(TransInfo *t, struct ListBase *lb, int do_it); 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 ********** */ /*********************** exported from transform_manipulator.c ********** */
struct ScrArea; struct ScrArea;

@ -80,6 +80,7 @@
#include "BIF_glutil.h" #include "BIF_glutil.h"
#include "BIF_space.h" #include "BIF_space.h"
#include "BIF_screen.h" #include "BIF_screen.h"
#include "BIF_transform.h"
#include "BSE_trans_types.h" #include "BSE_trans_types.h"
#include "BSE_view.h" #include "BSE_view.h"
@ -89,8 +90,6 @@
#include "blendef.h" #include "blendef.h"
#include "butspace.h" // event codes #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 * Sets up the fields of the View2D member of the SpaceImage struct
* This routine can be called in two modes: * 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; float x, y;
@ -509,28 +508,12 @@ static unsigned int *get_part_from_ibuf(ImBuf *ibuf, short startx, short starty,
return rectmain; return rectmain;
} }
/* now only in use by drawimage.c */ static void draw_image_transform(ImBuf *ibuf)
static void draw_prop_circle()
{ {
if (G.scene->proportional) {
float tmat[4][4], imat[4][4];
if(G.moving) { if(G.moving) {
BIF_ThemeColor(TH_GRID); float aspx, aspy, center[3];
mygetmatrix(tmat); BIF_drawConstraint();
Mat4Invert(imat, tmat);
drawcircball(GL_LINE_LOOP, prop_cent, prop_size, imat);
}
}
}
static void draw_image_prop_circle(ImBuf *ibuf)
{
float aspx, aspy;
if(G.moving && G.scene->proportional) {
if(ibuf==0 || ibuf->rect==0 || ibuf->x==0 || ibuf->y==0) { if(ibuf==0 || ibuf->rect==0 || ibuf->x==0 || ibuf->y==0) {
aspx= aspy= 1.0; aspx= aspy= 1.0;
@ -540,12 +523,16 @@ static void draw_image_prop_circle(ImBuf *ibuf)
aspy= 256.0/ibuf->y; aspy= 256.0/ibuf->y;
} }
BIF_getPropCenter(center);
/* scale and translate the circle into place and draw it */ /* scale and translate the circle into place and draw it */
glPushMatrix(); glPushMatrix();
glScalef(aspx, aspy, 1.0); glScalef(aspx, aspy, 1.0);
glTranslatef((1/aspx)*prop_cent[0] - prop_cent[0], glTranslatef((1/aspx)*center[0] - center[0],
(1/aspy)*prop_cent[1] - prop_cent[1], 0.0); (1/aspy)*center[1] - center[1], 0.0);
draw_prop_circle();
BIF_drawPropCircle();
glPopMatrix(); glPopMatrix();
} }
} }
@ -937,7 +924,7 @@ void drawimagespace(ScrArea *sa, void *spacedata)
calc_image_view(G.sima, 'f'); /* float */ 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); myortho2(-0.375, sa->winx-0.375, -0.375, sa->winy-0.375);
draw_image_view_icon(); draw_image_view_icon();
@ -1111,7 +1098,7 @@ void image_viewcentre(void)
if(size<=0.01) size= 0.01; 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'); calc_image_view(G.sima, 'p');

@ -3441,6 +3441,10 @@ void std_rmouse_transform(void (*xf_func)(int, int))
#endif #endif
Transform(); Transform();
} }
else if(curarea->spacetype==SPACE_IMAGE) {
initTransform(TFM_TRANSLATION, CTX_NONE);
Transform();
}
else if(xf_func) else if(xf_func)
xf_func('g', 0); xf_func('g', 0);

@ -74,6 +74,7 @@
#include "BIF_space.h" #include "BIF_space.h"
#include "BIF_editsima.h" #include "BIF_editsima.h"
#include "BIF_toolbox.h" #include "BIF_toolbox.h"
#include "BIF_transform.h"
#include "BIF_mywindow.h" #include "BIF_mywindow.h"
#include "BSE_drawipo.h" #include "BSE_drawipo.h"
@ -241,41 +242,7 @@ void clever_numbuts_sima(void)
} }
} }
static void sima_pixelgrid(float *loc, float sx, float sy) void be_square_tface_uv(Mesh *me)
{
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)
{ {
TFace *tface; TFace *tface;
MFace *mface; 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; int w, h;
TFace *tface;
int a, b;
if( is_uv_tface_editing_allowed()==0 ) return;
me= get_mesh(OBACT);
tface= me->tface;
for(a=0; a<me->totface; 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);
}
}
}
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) { if(G.sima->image && G.sima->image->ibuf) {
xim= G.sima->image->ibuf->x; *width= G.sima->image->ibuf->x;
yim= G.sima->image->ibuf->y; *height= G.sima->image->ibuf->y;
} }
else { 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]<min[0]) xdist= tv->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]<min[1]) ydist= tv->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; a<tot; a++, tv++) {
x= tv->oldloc[0]+tv->fac*vec[0];
y= tv->oldloc[1]+tv->fac*vec[1];
sima_pixelgrid(tv->loc, x, y);
}
} else {
for(a=0; a<tot; a++, tv++) {
x= tv->oldloc[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; a<tot; a++, tv++) {
if(propmode) {
co= cos(phi*tv->fac);
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; a<tot; a++, tv++) {
x= (tv->fac*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; a<tot; a++, tv++) {
x= size[0]*(tv->oldloc[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; a<tot; a++, tv++) {
tv->loc[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) void mirror_tface_uv(char mirroraxis)
{ {
MFace *mface; Mirror((short)mirroraxis);
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);
} }
void mirrormenu_tface_uv(void) void mirrormenu_tface_uv(void)
@ -938,6 +415,7 @@ void weld_align_menu_tface_uv(void)
if(mode==1) BIF_undo_push("Weld UV"); if(mode==1) BIF_undo_push("Weld UV");
else if(mode==2 || mode==3) BIF_undo_push("Align UV"); else if(mode==2 || mode==3) BIF_undo_push("Align UV");
} }
void select_swap_tface_uv(void) void select_swap_tface_uv(void)
{ {
Mesh *me; Mesh *me;
@ -997,8 +475,8 @@ static void find_nearest_tface(TFace **nearesttf, MFace **nearestmf)
Mesh *me; Mesh *me;
TFace *tf; TFace *tf;
MFace *mf; MFace *mf;
int a, i, nverts, mindist, dist, fcenter[2]; int a, i, nverts, mindist, dist, fcenter[2], uval[2];
short mval[2], uval[2]; short mval[2];
getmouseco_areawin(mval); 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; float m[3], v1[3], v2[3], c1, c2;
int id1, id2; int id1, id2;
@ -1066,8 +544,8 @@ static void find_nearest_uv(TFace **nearesttf, unsigned int *nearestv, int *near
Mesh *me; Mesh *me;
TFace *tf; TFace *tf;
MFace *mf; MFace *mf;
int a, i, nverts, mindist, dist; int a, i, nverts, mindist, dist, uval[2];
short mval[2], uval[2]; short mval[2];
getmouseco_areawin(mval); getmouseco_areawin(mval);
@ -1263,7 +741,7 @@ void mouse_select_sima(void)
force_draw(1); force_draw(1);
BIF_undo_push("Select UV"); BIF_undo_push("Select UV");
std_rmouse_transform(transform_tface_uv); rightmouse_transform();
} }
void borderselect_sima(void) void borderselect_sima(void)
@ -1651,7 +1129,6 @@ void stitch_uv_tface(int mode)
MEM_freeN(sortblock); MEM_freeN(sortblock);
if(G.sima->flag & SI_BE_SQUARE) be_square_tface_uv(me); 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"); BIF_undo_push("Stitch UV");

@ -781,19 +781,23 @@ int gesture(void)
if(i) { if(i) {
if(curarea->spacetype==SPACE_IPO) transform_ipo(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 if(curarea->spacetype==SPACE_OOPS) transform_oops('g', 0);
else { else {
int context;
if(curarea->spacetype==SPACE_IMAGE) context= CTX_NONE;
else context= CTX_NONE;
if(i=='g') { if(i=='g') {
initTransform(TFM_TRANSLATION, CTX_NONE); initTransform(TFM_TRANSLATION, context);
Transform(); Transform();
} }
else if(i=='r') { else if(i=='r') {
initTransform(TFM_ROTATION, CTX_NONE); initTransform(TFM_ROTATION, context);
Transform(); Transform();
} }
else { else {
initTransform(TFM_RESIZE, CTX_NONE); initTransform(TFM_RESIZE, context);
Transform(); Transform();
} }
} }

@ -70,6 +70,7 @@
#include "BIF_space.h" #include "BIF_space.h"
#include "BIF_toets.h" #include "BIF_toets.h"
#include "BIF_toolbox.h" #include "BIF_toolbox.h"
#include "BIF_transform.h"
#include "BIF_writeimage.h" #include "BIF_writeimage.h"
#include "BSE_filesel.h" #include "BSE_filesel.h"
@ -300,12 +301,6 @@ void do_image_buttons(unsigned short event)
} }
break; break;
case B_CLIP_UV:
tface_do_clip();
if (OBACT) object_uvs_changed(OBACT);
break;
case B_SIMAGEPAINTTOOL: case B_SIMAGEPAINTTOOL:
// check for packed file here // check for packed file here
allqueue(REDRAWIMAGE, 0); allqueue(REDRAWIMAGE, 0);
@ -843,13 +838,16 @@ static void do_image_uvs_transformmenu(void *arg, int event)
{ {
switch(event) { switch(event) {
case 0: /* Grab */ case 0: /* Grab */
transform_tface_uv('g', 0); initTransform(TFM_TRANSLATION, CTX_NONE);
Transform();
break; break;
case 1: /* Rotate */ case 1: /* Rotate */
transform_tface_uv('r', 0); initTransform(TFM_ROTATION, CTX_NONE);
Transform();
break; break;
case 2: /* Scale */ case 2: /* Scale */
transform_tface_uv('s', 0); initTransform(TFM_RESIZE, CTX_NONE);
Transform();
break; break;
} }
} }

@ -3871,8 +3871,10 @@ static void winqreadimagespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
unwrap_lscm(); unwrap_lscm();
break; break;
case GKEY: case GKEY:
if((G.qual==0)) if((G.qual==0) && is_uv_tface_editing_allowed()) {
transform_tface_uv('g', 0); initTransform(TFM_TRANSLATION, CTX_NONE);
Transform();
}
break; break;
case HKEY: case HKEY:
if(G.qual==LR_ALTKEY) if(G.qual==LR_ALTKEY)
@ -3916,12 +3918,16 @@ static void winqreadimagespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
pin_tface_uv(1); pin_tface_uv(1);
break; break;
case RKEY: case RKEY:
if((G.qual==0)) if((G.qual==0) && is_uv_tface_editing_allowed()) {
transform_tface_uv('r', 0); initTransform(TFM_ROTATION, CTX_NONE);
Transform();
}
break; break;
case SKEY: case SKEY:
if((G.qual==0)) if((G.qual==0) && is_uv_tface_editing_allowed()) {
transform_tface_uv('s', 0); initTransform(TFM_RESIZE, CTX_NONE);
Transform();
}
break; break;
case VKEY: case VKEY:
if((G.qual==0)) if((G.qual==0))

@ -60,6 +60,7 @@
#include "DNA_texture_types.h" #include "DNA_texture_types.h"
#include "DNA_userdef_types.h" #include "DNA_userdef_types.h"
#include "DNA_view3d_types.h" #include "DNA_view3d_types.h"
#include "DNA_space_types.h"
#include "BIF_editview.h" /* arrows_move_cursor */ #include "BIF_editview.h" /* arrows_move_cursor */
#include "BIF_gl.h" #include "BIF_gl.h"
@ -71,6 +72,8 @@
#include "BIF_mywindow.h" /* warp_pointer */ #include "BIF_mywindow.h" /* warp_pointer */
#include "BIF_toolbox.h" /* notice */ #include "BIF_toolbox.h" /* notice */
#include "BIF_editmesh.h" #include "BIF_editmesh.h"
#include "BIF_editsima.h"
#include "BIF_drawimage.h" /* uvco_to_areaco_noclip */
#include "BKE_global.h" #include "BKE_global.h"
#include "BKE_utildefines.h" #include "BKE_utildefines.h"
@ -116,7 +119,7 @@ static void helpline(TransInfo *t, float *vec)
} }
getmouseco_areawin(mval); 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) { if(cent[0]!=IS_CLIPPED) {
persp(PERSP_WIN); persp(PERSP_WIN);
@ -161,7 +164,7 @@ float InputScaleRatio(TransInfo *t, short mval[2]) {
float InputHorizontalRatio(TransInfo *t, short mval[2]) { float InputHorizontalRatio(TransInfo *t, short mval[2]) {
int y, pad; int y, pad;
pad = G.vd->area->winx / 10; pad = curarea->winx / 10;
if (t->flag & T_SHIFT_MOD) { if (t->flag & T_SHIFT_MOD) {
/* deal with Shift key by adding motion / 10 to motion before shift press */ /* 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 { else {
y = mval[0]; 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 **************************** */ /* ************************** TRANSFORMATIONS **************************** */
@ -247,11 +386,8 @@ static void view_editmove(unsigned short event)
break; break;
} }
if (refresh) { if (refresh)
Mat4CpyMat4(Trans.viewmat, G.vd->viewmat); setTransformViewMatrices(&Trans);
Mat4CpyMat4(Trans.viewinv, G.vd->viewinv);
Mat4CpyMat4(Trans.persinv, G.vd->persinv);
}
} }
void checkFirstTime() { void checkFirstTime() {
@ -316,7 +452,7 @@ static void transformEvent(unsigned short event, short val) {
break; break;
case SPACEKEY: case SPACEKEY:
if (G.qual & LR_ALTKEY) { if ((Trans.spacetype==SPACE_VIEW3D) && (G.qual & LR_ALTKEY)) {
short mval[2]; short mval[2];
getmouseco_sc(mval); getmouseco_sc(mval);
@ -421,14 +557,14 @@ static void transformEvent(unsigned short event, short val) {
else { else {
if (G.qual == 0) if (G.qual == 0)
setUserConstraint(&Trans, (CON_AXIS0), "along %s X"); 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"); setUserConstraint(&Trans, (CON_AXIS1|CON_AXIS2), "locking %s X");
} }
} }
else { else {
if (G.qual == 0) if (G.qual == 0)
setConstraint(&Trans, mati, (CON_AXIS0), "along global X"); 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"); setConstraint(&Trans, mati, (CON_AXIS1|CON_AXIS2), "locking global X");
} }
Trans.redraw = 1; Trans.redraw = 1;
@ -443,14 +579,14 @@ static void transformEvent(unsigned short event, short val) {
else { else {
if (G.qual == 0) if (G.qual == 0)
setUserConstraint(&Trans, (CON_AXIS1), "along %s Y"); 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"); setUserConstraint(&Trans, (CON_AXIS0|CON_AXIS2), "locking %s Y");
} }
} }
else { else {
if (G.qual == 0) if (G.qual == 0)
setConstraint(&Trans, mati, (CON_AXIS1), "along global Y"); 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"); setConstraint(&Trans, mati, (CON_AXIS0|CON_AXIS2), "locking global Y");
} }
Trans.redraw = 1; Trans.redraw = 1;
@ -465,11 +601,11 @@ static void transformEvent(unsigned short event, short val) {
else { else {
if (G.qual == 0) if (G.qual == 0)
setUserConstraint(&Trans, (CON_AXIS2), "along %s Z"); 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"); setUserConstraint(&Trans, (CON_AXIS0|CON_AXIS1), "locking %s Z");
} }
} }
else { else if ((Trans.flag & T_2D_EDIT)==0) {
if (G.qual == 0) if (G.qual == 0)
setConstraint(&Trans, mati, (CON_AXIS2), "along global Z"); setConstraint(&Trans, mati, (CON_AXIS2), "along global Z");
else if (G.qual == LR_SHIFTKEY) else if (G.qual == LR_SHIFTKEY)
@ -554,10 +690,14 @@ void initTransform(int mode, int context) {
Trans.context = context; Trans.context = context;
initTrans(&Trans); // internal data, mouse, vectors
if(Trans.spacetype==SPACE_VIEW3D) {
calc_manipulator_stats(curarea); calc_manipulator_stats(curarea);
Mat3CpyMat4(Trans.spacemtx, G.vd->twmat); Mat3CpyMat4(Trans.spacemtx, G.vd->twmat);
}
initTrans(&Trans); // internal data, mouse, vectors else
Mat3One(Trans.spacemtx);
initTransModeFlags(&Trans, mode); // modal settings in struct Trans initTransModeFlags(&Trans, mode); // modal settings in struct Trans
@ -687,9 +827,7 @@ void Transform()
special_aftertrans_update(&Trans); special_aftertrans_update(&Trans);
/* send events out for redraws */ /* send events out for redraws */
allqueue(REDRAWVIEW3D, 0); viewRedrawPost(&Trans);
allqueue(REDRAWBUTSOBJECT, 0);
scrarea_queue_headredraw(curarea);
} }
/* ************************** Manipulator init and main **************************** */ /* ************************** Manipulator init and main **************************** */
@ -848,9 +986,7 @@ void ManipulatorTransform()
special_aftertrans_update(&Trans); special_aftertrans_update(&Trans);
/* send events out for redraws */ /* send events out for redraws */
allqueue(REDRAWVIEW3D, 0); viewRedrawPost(&Trans);
allqueue(REDRAWBUTSOBJECT, 0);
scrarea_queue_headredraw(curarea);
} }
/* ************************** TRANSFORMATIONS **************************** */ /* ************************** TRANSFORMATIONS **************************** */
@ -878,8 +1014,8 @@ void initWarp(TransInfo *t)
float center[3]; float center[3];
VECCOPY(center, t->data[i].center); VECCOPY(center, t->data[i].center);
Mat3MulVecfl(t->data[i].mtx, center); Mat3MulVecfl(t->data[i].mtx, center);
Mat4MulVecfl(G.vd->viewmat, center); Mat4MulVecfl(t->viewmat, center);
VecSubf(center, center, G.vd->viewmat[3]); VecSubf(center, center, t->viewmat[3]);
if (i) if (i)
MinMax3(min, max, center); MinMax3(min, max, center);
else { else {
@ -921,8 +1057,8 @@ int Warp(TransInfo *t, short mval[2])
VecSubf(gcursor, gcursor, G.obedit->obmat[3]); VecSubf(gcursor, gcursor, G.obedit->obmat[3]);
Mat3MulVecfl(t->data->smtx, gcursor); Mat3MulVecfl(t->data->smtx, gcursor);
} }
Mat4MulVecfl(G.vd->viewmat, cursor); Mat4MulVecfl(t->viewmat, cursor);
VecSubf(cursor, cursor, G.vd->viewmat[3]); VecSubf(cursor, cursor, t->viewmat[3]);
// amount of degrees for warp, 450 = allow to create 360 degree warp // amount of degrees for warp, 450 = allow to create 360 degree warp
circumfac= 450.0f*(mval[1] - t->imval[1]) / (float)(curarea->winy); 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); VECCOPY(vec, td->iloc);
Mat3MulVecfl(td->mtx, vec); Mat3MulVecfl(td->mtx, vec);
Mat4MulVecfl(G.vd->viewmat, vec); Mat4MulVecfl(t->viewmat, vec);
VecSubf(vec, vec, G.vd->viewmat[3]); VecSubf(vec, vec, t->viewmat[3]);
dist= vec[0]-cursor[0]; dist= vec[0]-cursor[0];
@ -970,8 +1106,8 @@ int Warp(TransInfo *t, short mval[2])
loc[1]= co*vec[1]+cursor[1]; loc[1]= co*vec[1]+cursor[1];
loc[2]= vec[2]; loc[2]= vec[2];
Mat4MulVecfl(G.vd->viewinv, loc); Mat4MulVecfl(t->viewinv, loc);
VecSubf(loc, loc, G.vd->viewinv[3]); VecSubf(loc, loc, t->viewinv[3]);
Mat3MulVecfl(td->smtx, loc); Mat3MulVecfl(td->smtx, loc);
VecSubf(loc, loc, td->iloc); VecSubf(loc, loc, td->iloc);
@ -983,7 +1119,7 @@ int Warp(TransInfo *t, short mval[2])
headerprint(str); headerprint(str);
force_draw(0); viewRedrawForce(t);
helpline(t, gcursor); helpline(t, gcursor);
@ -1012,7 +1148,7 @@ int Shear(TransInfo *t, short mval[2])
int i; int i;
char str[50]; char str[50];
Mat3CpyMat4(persmat, G.vd->viewmat); Mat3CpyMat4(persmat, t->viewmat);
Mat3Inv(persinv, persmat); Mat3Inv(persinv, persmat);
value = -0.005f * ((float)(t->center2d[0] - mval[0]) - t->fac); value = -0.005f * ((float)(t->center2d[0] - mval[0]) - t->fac);
@ -1067,7 +1203,7 @@ int Shear(TransInfo *t, short mval[2])
headerprint(str); headerprint(str);
force_draw(0); viewRedrawForce(t);
helpline (t, t->center); helpline (t, t->center);
@ -1119,6 +1255,9 @@ static void headerResize(TransInfo *t, float vec[3], char *str) {
} }
} }
else { else {
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); 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 */ /* local constraint shouldn't alter center */
if (G.vd->around == V3D_LOCAL) { if (t->around == V3D_LOCAL) {
if (t->flag & T_OBJECT) { if (t->flag & T_OBJECT) {
VECCOPY(center, td->center); // not supported in editmode yet 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); 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? */ /* handle ipokeys? */
if(td->tdi) { if(td->tdi) {
TransDataIpokey *tdi= 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 */ /* For individual element center, Editmode need to use iloc */
if (t->flag & T_EDIT) if (t->flag & T_POINTS)
VecSubf(vec, td->iloc, center); VecSubf(vec, td->iloc, center);
else else
VecSubf(vec, td->center, center); VecSubf(vec, td->center, center);
@ -1232,7 +1371,7 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) {
Mat3MulVecfl(tmat, vec); Mat3MulVecfl(tmat, vec);
VecAddf(vec, vec, center); VecAddf(vec, vec, center);
if (t->flag & T_EDIT) if (t->flag & T_POINTS)
VecSubf(vec, vec, td->iloc); VecSubf(vec, vec, td->iloc);
else else
VecSubf(vec, vec, td->center); 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]) int Resize(TransInfo *t, short mval[2])
{ {
TransData *td = t->data; TransData *td;
float size[3], mat[3][3]; float size[3], mat[3][3];
float ratio; float ratio;
int i; int i;
@ -1292,18 +1431,29 @@ int Resize(TransInfo *t, short mval[2])
headerResize(t, size, str); 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) if (td->flag & TD_NOACTION)
break; break;
ElementResize(t, td, mat); 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); recalcData(t);
headerprint(str); headerprint(str);
force_draw(0); viewRedrawForce(t);
if(!(t->flag & T_USES_MANIPULATOR)) helpline (t, t->center); if(!(t->flag & T_USES_MANIPULATOR)) helpline (t, t->center);
@ -1387,7 +1537,7 @@ int ToSphere(TransInfo *t, short mval[2])
headerprint(str); headerprint(str);
force_draw(0); viewRedrawForce(t);
return 1; 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 vec[3], totmat[3][3], smat[3][3];
float eul[3], fmat[3][3], quat[4]; float eul[3], fmat[3][3], quat[4];
if (t->flag & T_EDIT) { if (t->flag & T_POINTS) {
Mat3MulMat3(totmat, mat, td->mtx); Mat3MulMat3(totmat, mat, td->mtx);
Mat3MulMat3(smat, td->smtx, totmat); Mat3MulMat3(smat, td->smtx, totmat);
@ -1448,7 +1598,7 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3]) {
Mat3ToQuat(fmat, quat); // Actual transform Mat3ToQuat(fmat, quat); // Actual transform
QuatMul(td->ext->quat, quat, td->ext->iquat); 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]; float obmat[3][3];
/* are there ipo keys? */ /* are there ipo keys? */
@ -1507,7 +1657,7 @@ static void applyRotation(TransInfo *t, float angle, float axis[3])
int i; int i;
/* saving original center */ /* saving original center */
if (G.vd->around == V3D_LOCAL) { if (t->around == V3D_LOCAL) {
VECCOPY(center, t->center); VECCOPY(center, t->center);
} }
@ -1519,7 +1669,7 @@ static void applyRotation(TransInfo *t, float angle, float axis[3])
break; break;
/* local constraint shouldn't alter center */ /* local constraint shouldn't alter center */
if (G.vd->around == V3D_LOCAL) { if (t->around == V3D_LOCAL) {
if (t->flag & T_OBJECT) if (t->flag & T_OBJECT)
VECCOPY(t->center, td->center); // not supported in editmode yet 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 */ /* restoring original center */
if (G.vd->around == V3D_LOCAL) { if (t->around == V3D_LOCAL) {
VECCOPY(t->center, center); VECCOPY(t->center, center);
} }
} }
@ -1623,7 +1773,7 @@ int Rotation(TransInfo *t, short mval[2])
headerprint(str); headerprint(str);
force_draw(0); viewRedrawForce(t);
if(!(t->flag & T_USES_MANIPULATOR)) helpline (t, t->center); 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) if (td->flag & TD_NOACTION)
break; break;
if (G.vd->around == V3D_LOCAL) { if (t->around == V3D_LOCAL) {
if (t->flag & T_OBJECT) if (t->flag & T_OBJECT)
VECCOPY(t->center, td->center); // not supported in editmode yet VECCOPY(t->center, td->center); // not supported in editmode yet
} }
@ -1725,7 +1875,7 @@ int Trackball(TransInfo *t, short mval[2])
headerprint(str); headerprint(str);
force_draw(0); viewRedrawForce(t);
if(!(t->flag & T_USES_MANIPULATOR)) helpline (t, t->center); if(!(t->flag & T_USES_MANIPULATOR)) helpline (t, t->center);
@ -1736,15 +1886,13 @@ int Trackball(TransInfo *t, short mval[2])
void initTranslation(TransInfo *t) void initTranslation(TransInfo *t)
{ {
t->idx_max = 2; t->idx_max = (t->flag & T_2D_EDIT)? 1: 2;
t->num.idx_max = 2; t->num.idx_max = t->idx_max;
t->snap[0] = 0.0f;
t->snap[1] = G.vd->gridview * 1.0f;
t->snap[2] = t->snap[1] * 0.1f;
t->transform = Translation; t->transform = Translation;
if(t->spacetype == SPACE_VIEW3D) {
/* initgrabz() defines a factor for perspective depth correction, used in window_to_3d() */ /* initgrabz() defines a factor for perspective depth correction, used in window_to_3d() */
if (G.obedit) { if(G.obedit) {
float vec[3]; float vec[3];
VECCOPY(vec, t->center); VECCOPY(vec, t->center);
@ -1752,17 +1900,35 @@ void initTranslation(TransInfo *t)
initgrabz(vec[0], vec[1], vec[2]); initgrabz(vec[0], vec[1], vec[2]);
} }
else initgrabz(t->center[0], t->center[1], t->center[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;
}
} }
static void headerTranslation(TransInfo *t, float vec[3], char *str) { static void headerTranslation(TransInfo *t, float vec[3], char *str) {
char tvec[60]; char tvec[60];
float dvec[3];
convertVecToDisplayNum(vec, dvec);
if (hasNumInput(&t->num)) { if (hasNumInput(&t->num)) {
outputNumInput(&(t->num), tvec); outputNumInput(&(t->num), tvec);
} }
else { else {
sprintf(&tvec[0], "%.4f", vec[0]); sprintf(&tvec[0], "%.4f", dvec[0]);
sprintf(&tvec[20], "%.4f", vec[1]); sprintf(&tvec[20], "%.4f", dvec[1]);
sprintf(&tvec[40], "%.4f", vec[2]); sprintf(&tvec[40], "%.4f", dvec[2]);
} }
if (t->con.mode & CON_APPLY) { if (t->con.mode & CON_APPLY) {
@ -1778,6 +1944,9 @@ static void headerTranslation(TransInfo *t, float vec[3], char *str) {
} }
} }
else { else {
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); 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) { if(t->flag & T_SHIFT_MOD) {
float dvec[3]; float dvec[3];
/* calculate the main translation and the precise one separate */ /* 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); 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); 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) { if (t->con.mode & CON_APPLY) {
float pvec[3] = {0.0f, 0.0f, 0.0f}; float pvec[3] = {0.0f, 0.0f, 0.0f};
@ -1843,11 +2012,15 @@ int Translation(TransInfo *t, short mval[2])
applyTranslation(t, t->vec); 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); recalcData(t);
headerprint(str); headerprint(str);
force_draw(0); viewRedrawForce(t);
return 1; return 1;
} }
@ -1880,9 +2053,9 @@ int ShrinkFatten(TransInfo *t, short mval[2])
char str[50]; char str[50];
TransData *td = t->data; TransData *td = t->data;
window_to_3d(t->vec, (short)(mval[0] - t->imval[0]), (short)(mval[1] - t->imval[1])); convertViewVec(t, t->vec, (short)(mval[0] - t->imval[0]), (short)(mval[1] - t->imval[1]));
Projf(vec, t->vec, G.vd->viewinv[1]); Projf(vec, t->vec, t->viewinv[1]);
ratio = Inpf(G.vd->viewinv[1], vec) * -2.0f; ratio = Inpf(t->viewinv[1], vec) * -2.0f;
snapGrid(t, &ratio); snapGrid(t, &ratio);
@ -1917,7 +2090,7 @@ int ShrinkFatten(TransInfo *t, short mval[2])
headerprint(str); headerprint(str);
force_draw(0); viewRedrawForce(t);
return 1; return 1;
} }
@ -2002,7 +2175,7 @@ int Tilt(TransInfo *t, short mval[2])
headerprint(str); headerprint(str);
force_draw(0); viewRedrawForce(t);
helpline (t, t->center); helpline (t, t->center);
@ -2031,9 +2204,9 @@ int PushPull(TransInfo *t, short mval[2])
char str[50]; char str[50];
TransData *td = t->data; TransData *td = t->data;
window_to_3d(t->vec, (short)(mval[0] - t->imval[0]), (short)(mval[1] - t->imval[1])); convertViewVec(t, t->vec, (short)(mval[0] - t->imval[0]), (short)(mval[1] - t->imval[1]));
Projf(vec, t->vec, G.vd->viewinv[1]); Projf(vec, t->vec, t->viewinv[1]);
distance = Inpf(G.vd->viewinv[1], vec) * 2.0f; distance = Inpf(t->viewinv[1], vec) * 2.0f;
snapGrid(t, &distance); snapGrid(t, &distance);
@ -2083,7 +2256,7 @@ int PushPull(TransInfo *t, short mval[2])
headerprint(str); headerprint(str);
force_draw(0); viewRedrawForce(t);
return 1; return 1;
} }
@ -2174,7 +2347,7 @@ int Crease(TransInfo *t, short mval[2])
headerprint(str); headerprint(str);
force_draw(0); viewRedrawForce(t);
helpline (t, t->center); helpline (t, t->center);
@ -2190,14 +2363,14 @@ void Mirror(short mode)
float size[3]; float size[3];
int i; int i;
Mat3One(mati);
Mat3CpyMat4(matview, G.vd->viewinv);
Mat3Ortho(matview);
Trans.context = CTX_NO_PET; Trans.context = CTX_NO_PET;
initTrans(&Trans); // internal data, mouse, vectors 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 initTransModeFlags(&Trans, TFM_MIRROR); // modal settings in struct Trans
createTransData(&Trans); // make TransData structs from selection createTransData(&Trans); // make TransData structs from selection
@ -2277,9 +2450,7 @@ void Mirror(short mode)
postTrans(&Trans); postTrans(&Trans);
/* send events out for redraws */ /* send events out for redraws */
allqueue(REDRAWVIEW3D, 0); viewRedrawPost(&Trans);
allqueue(REDRAWBUTSOBJECT, 0);
scrarea_queue_headredraw(curarea);
} }
/* ******************** EditBone (B-bone) width scaling *************** */ /* ******************** EditBone (B-bone) width scaling *************** */
@ -2372,7 +2543,7 @@ int BoneSize(TransInfo *t, short mval[2])
headerprint(str); headerprint(str);
force_draw(0); viewRedrawForce(t);
if(!(t->flag & T_USES_MANIPULATOR)) helpline (t, t->center); if(!(t->flag & T_USES_MANIPULATOR)) helpline (t, t->center);

@ -62,6 +62,7 @@
#include "DNA_object_types.h" #include "DNA_object_types.h"
#include "DNA_scene_types.h" #include "DNA_scene_types.h"
#include "DNA_screen_types.h" #include "DNA_screen_types.h"
#include "DNA_space_types.h"
#include "DNA_view3d_types.h" #include "DNA_view3d_types.h"
#include "BIF_screen.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[]) { void setUserConstraint(TransInfo *t, int mode, const char ftext[]) {
float mtx[3][3]; float mtx[3][3];
char text[40]; 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: case V3D_MANIP_GLOBAL:
sprintf(text, ftext, "global"); sprintf(text, ftext, "global");
Mat3One(mtx); Mat3One(mtx);
@ -630,13 +632,15 @@ void BIF_drawConstraint(void)
TransInfo *t = BIF_GetTransInfo(); TransInfo *t = BIF_GetTransInfo();
TransCon *tc = &(t->con); TransCon *tc = &(t->con);
if (t->spacetype!=SPACE_VIEW3D)
return;
if (!(tc->mode & CON_APPLY)) if (!(tc->mode & CON_APPLY))
return; return;
if (t->flag & T_USES_MANIPULATOR) if (t->flag & T_USES_MANIPULATOR)
return; return;
/* nasty exception for Z constraint in camera view */ /* 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; return;
if (tc->drawExtra) { if (tc->drawExtra) {
@ -648,7 +652,7 @@ void BIF_drawConstraint(void)
short mval[2]; short mval[2];
char col2[3] = {255,255,255}; char col2[3] = {255,255,255};
getmouseco_areawin(mval); 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); VecAddf(vec, vec, tc->center);
drawLine(tc->center, tc->mtx[0], 'x', 0); drawLine(tc->center, tc->mtx[0], 'x', 0);
@ -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) { static void drawObjectConstraint(TransInfo *t) {
int i; 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 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. 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= 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(G.vd->persinv[0]) * 2.0f/curarea->winx * zfac * 30.0f; zfac = VecLength(t->persinv[0]) * 2.0f/curarea->winx * zfac * 30.0f;
for (i = 0; i<3; i++) { for (i = 0; i<3; i++) {
VECCOPY(axis, t->con.mtx[i]); VECCOPY(axis, t->con.mtx[i]);
@ -853,7 +867,7 @@ void setNearestAxis(TransInfo *t)
VecMulf(axis, zfac); VecMulf(axis, zfac);
/* now we can project to get window coordinate */ /* now we can project to get window coordinate */
VecAddf(axis, axis, t->con.center); VecAddf(axis, axis, t->con.center);
project_int(axis, icoord); projectIntView(t, axis, icoord);
axis[0] = (float)(icoord[0] - t->center2d[0]); axis[0] = (float)(icoord[0] - t->center2d[0]);
axis[1] = (float)(icoord[1] - t->center2d[1]); axis[1] = (float)(icoord[1] - t->center2d[1]);

@ -39,6 +39,8 @@
#else #else
#include <io.h> #include <io.h>
#endif #endif
#include <string.h>
#include <math.h>
#include "MEM_guardedalloc.h" #include "MEM_guardedalloc.h"
@ -60,6 +62,7 @@
#include "DNA_object_force.h" #include "DNA_object_force.h"
#include "DNA_scene_types.h" #include "DNA_scene_types.h"
#include "DNA_screen_types.h" #include "DNA_screen_types.h"
#include "DNA_space_types.h"
#include "DNA_texture_types.h" #include "DNA_texture_types.h"
#include "DNA_view3d_types.h" #include "DNA_view3d_types.h"
#include "DNA_world_types.h" #include "DNA_world_types.h"
@ -81,6 +84,7 @@
#include "BKE_ipo.h" #include "BKE_ipo.h"
#include "BKE_lattice.h" #include "BKE_lattice.h"
#include "BKE_mball.h" #include "BKE_mball.h"
#include "BKE_mesh.h"
#include "BKE_modifier.h" #include "BKE_modifier.h"
#include "BKE_object.h" #include "BKE_object.h"
#include "BKE_softbody.h" #include "BKE_softbody.h"
@ -92,6 +96,7 @@
#include "BIF_editconstraint.h" #include "BIF_editconstraint.h"
#include "BIF_editarmature.h" #include "BIF_editarmature.h"
#include "BIF_editmesh.h" #include "BIF_editmesh.h"
#include "BIF_editsima.h"
#include "BIF_gl.h" #include "BIF_gl.h"
#include "BIF_poseobject.h" #include "BIF_poseobject.h"
#include "BIF_mywindow.h" #include "BIF_mywindow.h"
@ -209,7 +214,6 @@ static void sort_trans_data(TransInfo *t)
} }
} }
/* distance calculated from not-selected vertex to nearest selected vertex /* 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 */ 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) static void set_prop_dist(TransInfo *t, short with_dist)
@ -483,6 +487,7 @@ static void createTransPose(Object *ob, TransInfo *t)
if (!(ob->lay & G.vd->lay)) return; if (!(ob->lay & G.vd->lay)) return;
/* count total */ /* count total */
t->total= 0;
count_bone_select(t, &arm->bonebase, 1); count_bone_select(t, &arm->bonebase, 1);
if(t->total==0 && t->mode==TFM_TRANSLATION) { if(t->total==0 && t->mode==TFM_TRANSLATION) {
@ -1077,7 +1082,6 @@ static void editmesh_set_connectivity_distance(int total, float *vectors, EditVe
} }
} }
static void VertsToTransData(TransData *td, EditVert *eve) static void VertsToTransData(TransData *td, EditVert *eve)
{ {
td->flag = 0; 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; a<t->total; 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; a<t->total; 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 ********** */ /* **************** IpoKey stuff, for Object TransData ********** */
/* storage of bezier triple. thats why -3 and +3! */ /* storage of bezier triple. thats why -3 and +3! */
@ -1527,8 +1706,8 @@ void special_aftertrans_update(TransInfo *t)
reset_slowparents(); reset_slowparents();
/* note; should actually only be done for all objects when a lamp is moved... (ton) */ /* 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) static void createTransObject(TransInfo *t)
@ -1664,6 +1843,15 @@ void createTransData(TransInfo *t)
sort_trans_data_dist(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) { else if (G.obedit) {
t->ext = NULL; t->ext = NULL;
if (G.obedit->type == OB_MESH) { if (G.obedit->type == OB_MESH) {
@ -1697,11 +1885,12 @@ void createTransData(TransInfo *t)
sort_trans_data_dist(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) */ /* exception... hackish, we want bonesize to use bone orientation matrix (ton) */
if(t->mode==TFM_BONESIZE) { if(t->mode==TFM_BONESIZE) {
t->flag &= ~T_EDIT; t->flag &= ~(T_EDIT|T_POINTS);
t->flag |= T_POSE; t->flag |= T_POSE;
t->poseobj= ob; /* <- tsk tsk, this is going to give issues one day */ t->poseobj= ob; /* <- tsk tsk, this is going to give issues one day */
} }

@ -43,6 +43,9 @@
#include "DNA_view3d_types.h" #include "DNA_view3d_types.h"
#include "DNA_userdef_types.h" #include "DNA_userdef_types.h"
#include "DNA_constraint_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_screen.h"
#include "BIF_resources.h" #include "BIF_resources.h"
@ -50,6 +53,7 @@
#include "BIF_gl.h" #include "BIF_gl.h"
#include "BIF_editarmature.h" #include "BIF_editarmature.h"
#include "BIF_editmesh.h" #include "BIF_editmesh.h"
#include "BIF_editsima.h"
#include "BKE_action.h" #include "BKE_action.h"
#include "BKE_anim.h" #include "BKE_anim.h"
@ -61,6 +65,7 @@
#include "BKE_global.h" #include "BKE_global.h"
#include "BKE_ipo.h" #include "BKE_ipo.h"
#include "BKE_lattice.h" #include "BKE_lattice.h"
#include "BKE_mesh.h"
#include "BKE_object.h" #include "BKE_object.h"
#include "BKE_utildefines.h" #include "BKE_utildefines.h"
@ -83,8 +88,11 @@ extern TransInfo Trans; /* From transform.c */
/* ************************** Functions *************************** */ /* ************************** Functions *************************** */
void getViewVector(float coord[3], float vec[3]) { void getViewVector(float coord[3], float vec[3])
if (G.vd->persp) {
TransInfo *t = BIF_GetTransInfo();
if (t->persp)
{ {
float p1[4], p2[4]; float p1[4], p2[4];
@ -92,18 +100,18 @@ void getViewVector(float coord[3], float vec[3]) {
p1[3] = 1.0f; p1[3] = 1.0f;
VECCOPY(p2, p1); VECCOPY(p2, p1);
p2[3] = 1.0f; p2[3] = 1.0f;
Mat4MulVec4fl(G.vd->viewmat, p2); Mat4MulVec4fl(t->viewmat, p2);
p2[0] = 2.0f * p2[0]; p2[0] = 2.0f * p2[0];
p2[1] = 2.0f * p2[1]; p2[1] = 2.0f * p2[1];
p2[2] = 2.0f * p2[2]; p2[2] = 2.0f * p2[2];
Mat4MulVec4fl(G.vd->viewinv, p2); Mat4MulVec4fl(t->viewinv, p2);
VecSubf(vec, p1, p2); VecSubf(vec, p1, p2);
} }
else { else {
VECCOPY(vec, G.vd->viewinv[2]); VECCOPY(vec, t->viewinv[2]);
} }
Normalise(vec); Normalise(vec);
} }
@ -224,6 +232,9 @@ void recalcData(TransInfo *t)
else else
where_is_pose(ob); where_is_pose(ob);
} }
else if(t->spacetype==SPACE_IMAGE) {
flushTransUVs(t);
}
else { else {
Base *base; Base *base;
@ -256,7 +267,8 @@ void recalcData(TransInfo *t)
} }
/* update shaded drawmode while transform */ /* 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); Mat3One(t->mat);
Mat4CpyMat4(t->viewmat, G.vd->viewmat); t->spacetype = curarea->spacetype;
Mat4CpyMat4(t->viewinv, G.vd->viewinv); if(t->spacetype==SPACE_VIEW3D) {
Mat4CpyMat4(t->persinv, G.vd->persinv); 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 */ /* 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->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 */ /* fac1 is for 'nothing', fac2 for CTRL, fac3 for SHIFT */
int invert = U.flag & USER_AUTOGRABGRID; int invert = U.flag & USER_AUTOGRABGRID;
int ctrl; int ctrl;
int i; int i;
float asp= 1.0f;
for (i=0; i<=max_index; i++) { 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(invert) {
if(G.qual & LR_CTRLKEY) ctrl= 0; if(G.qual & LR_CTRLKEY) ctrl= 0;
else ctrl= 1; 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(ctrl && (G.qual & LR_SHIFTKEY)) {
if(fac3!= 0.0) { if(fac3!= 0.0) {
for (i=0; i<=max_index; i++) { 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) { else if(ctrl) {
if(fac2!= 0.0) { if(fac2!= 0.0) {
for (i=0; i<=max_index; i++) { 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 { else {
if(fac1!= 0.0) { if(fac1!= 0.0) {
for (i=0; i<=max_index; i++) { 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) { 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) void applyTransObjects(TransInfo *t)
@ -530,10 +560,10 @@ void calculateCenterCursor(TransInfo *t)
VECCOPY(vec, t->center); VECCOPY(vec, t->center);
Mat4MulVecfl(ob->obmat, vec); Mat4MulVecfl(ob->obmat, vec);
project_int(vec, t->center2d); projectIntView(t, vec, t->center2d);
} }
else { 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); VECCOPY(vec, t->center);
Mat4MulVecfl(ob->obmat, vec); Mat4MulVecfl(ob->obmat, vec);
project_int(vec, t->center2d); projectIntView(t, vec, t->center2d);
} }
else { 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); VECCOPY(vec, t->center);
Mat4MulVecfl(ob->obmat, vec); Mat4MulVecfl(ob->obmat, vec);
project_int(vec, t->center2d); projectIntView(t, vec, t->center2d);
} }
else { else {
project_int(t->center, t->center2d); projectIntView(t, t->center, t->center2d);
} }
} }
void calculateCenter(TransInfo *t) void calculateCenter(TransInfo *t)
{ {
switch(G.vd->around) { switch(t->around) {
case V3D_CENTRE: case V3D_CENTRE:
calculateCenterBound(t); calculateCenterBound(t);
break; break;
@ -631,7 +661,7 @@ void calculateCenter(TransInfo *t)
Object *ob= OBACT; Object *ob= OBACT;
if(ob) { if(ob) {
VECCOPY(t->center, ob->obmat[3]); 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) { if( G.vd->camera==OBACT && G.vd->persp>1) {
float axis[3]; float axis[3];
/* persinv is nasty, use viewinv instead, always right */ /* persinv is nasty, use viewinv instead, always right */
VECCOPY(axis, G.vd->viewinv[2]); VECCOPY(axis, t->viewinv[2]);
Normalise(axis); Normalise(axis);
/* 6.0 = 6 grid units */ /* 6.0 = 6 grid units */
@ -657,12 +687,14 @@ void calculateCenter(TransInfo *t)
axis[1]= t->center[1]- 6.0f*axis[1]; axis[1]= t->center[1]- 6.0f*axis[1];
axis[2]= t->center[2]- 6.0f*axis[2]; 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 */ /* rotate only needs correct 2d center, grab needs initgrabz() value */
if(t->mode==TFM_TRANSLATION) VECCOPY(t->center, axis); if(t->mode==TFM_TRANSLATION) VECCOPY(t->center, axis);
} }
} }
if(t->spacetype==SPACE_VIEW3D)
initgrabz(t->center[0], t->center[1], t->center[2]); initgrabz(t->center[0], t->center[1], t->center[2]);
} }

@ -103,8 +103,11 @@ short hasNumInput(NumInput *n)
void applyNumInput(NumInput *n, float *vec) void applyNumInput(NumInput *n, float *vec)
{ {
short i, j; short i, j;
float val[3];
if (hasNumInput(n)) { if (hasNumInput(n)) {
convertDisplayNumToVec(n->val, val);
for (j=0; j<=n->idx_max; j++) { for (j=0; j<=n->idx_max; j++) {
/* if AFFECTALL and no number typed and cursor not on number, use first number */ /* 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) 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) { if (n->ctrl[i] == 0 && n->flag & NUM_NULL_ONE) {
vec[j] = 1.0f; 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; vec[j] = 0.0001f;
} }
else { else {
vec[j] = n->val[i]; vec[j] = val[i];
} }
} }
} }