diff --git a/source/blender/include/BDR_editface.h b/source/blender/include/BDR_editface.h index c2ae5835910..c3a7821c11d 100644 --- a/source/blender/include/BDR_editface.h +++ b/source/blender/include/BDR_editface.h @@ -37,6 +37,7 @@ struct TFace; struct Mesh; void set_lasttface(void); +void calculate_uv_map(unsigned short mapmode); void default_uv(float uv[][2], float size); void default_tface(struct TFace *tface); void make_tfaces(struct Mesh *me); @@ -46,7 +47,7 @@ void select_linked_tfaces(void); void deselectall_tface(void); void selectswap_tface(void); void rotate_uv_tface(void); -unsigned int face_pick(struct Mesh *me, short x, short y); +int face_pick(struct Mesh *me, short x, short y); void face_select(void); void face_borderselect(void); float CalcNormUV(float *a, float *b, float *c); diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h index a2e153ef519..7d0ad46a98e 100644 --- a/source/blender/include/butspace.h +++ b/source/blender/include/butspace.h @@ -74,9 +74,6 @@ extern void do_mballbuts(unsigned short event); extern void do_latticebuts(unsigned short event); extern void do_fpaintbuts(unsigned short event); -/* dont like it here , rather make a BIF_Buttons_Editing.h or so BM*/ -extern int Buttons_Editing_GetFaceShadows(); - /* shading */ extern void material_panels(void); extern void do_matbuts(unsigned short event); @@ -532,7 +529,6 @@ enum { B_CONSTRAINT_ADD_DISTANCELIMIT }; -/*+++ BM */ /* *********************** */ #define B_UVAUTOCALCBUTS 3400 enum { @@ -558,10 +554,6 @@ enum { B_UVAUTO_ALIGNY }; /* *********************** */ -/*--- BM */ -/* *********************** */ - - /* *********************** */ /* BUTTON BUT: > 4000 */ diff --git a/source/blender/src/butspace.c b/source/blender/src/butspace.c index 1bb4d9e48ca..9727c43688c 100644 --- a/source/blender/src/butspace.c +++ b/source/blender/src/butspace.c @@ -315,6 +315,9 @@ void do_butspace(unsigned short event) else if(event<=B_CONSTRAINTBUTS) { do_constraintbuts(event); } + else if(event<=B_UVAUTOCALCBUTS) { + do_uvautocalculationbuts(event); + } else if(event==REDRAWVIEW3D) allqueue(event, 1); // 1=do header too else if(event>REDRAWVIEW3D) allqueue(event, 0); } diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 19cfb5d291c..2b546b190c6 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -158,7 +158,8 @@ static float extr_offs= 1.0; static float editbutweight=1.0; short editbutflag= 1; float doublimit= 0.001, editbutvweight=1, editbutsize=0.1; - +float uv_calc_radius= 1.0, uv_calc_cubesize= 1.0; +short uv_calc_mapdir= 1, uv_calc_mapalign= 1, facesel_draw_edges= 0; /* *************************** MESH DECIMATE ******************************** */ @@ -2116,6 +2117,95 @@ static void editing_panel_mesh_texface(void) } +void do_uvautocalculationbuts(unsigned short event) +{ + switch(event) { + case B_UVAUTO_STD1: + case B_UVAUTO_STD2: + case B_UVAUTO_STD4: + case B_UVAUTO_STD8: + case B_UVAUTO_CUBE: + calculate_uv_map(event); + break; + case B_UVAUTO_BOUNDS1: + case B_UVAUTO_BOUNDS2: + case B_UVAUTO_BOUNDS4: + case B_UVAUTO_BOUNDS8: + case B_UVAUTO_SPHERE: + case B_UVAUTO_CYLINDER: + case B_UVAUTO_WINDOW: + if(select_area(SPACE_VIEW3D)) calculate_uv_map(event); + break; + } +} + +static void editing_panel_mesh_uvautocalculation(void) +{ + uiBlock *block; + int butH= 19, butHB= 20, row= 180, butS= 10; + + block= uiNewBlock(&curarea->uiblocks, "editing_panel_mesh_uvautocalculation", UI_EMBOSS, UI_HELV, curarea->win); + /* make this a tab of "Texture face" to save screen space*/ + uiNewPanelTabbed("Texture face", "Editing"); + if(uiNewPanel(curarea, block, "UV Calculation", "Editing", 960, 0, 318, 204)==0) + return; + + uiBlockBeginAlign(block); + uiDefBut(block, BUT, B_UVAUTO_STD1,"Standard 1/1",100,row,200,butH, 0, 0, 0, 0, 0, "Applies standard UV mapping"); + uiDefBut(block, BUT, B_UVAUTO_STD2,"1/2",100,row-butHB,66,butH, 0, 0, 0, 0, 0, "Applies standard UV mapping 1/2"); + uiDefBut(block, BUT, B_UVAUTO_STD4,"1/4",166,row-butHB,67,butH, 0, 0, 0, 0, 0, "Applies standard UV mapping 1/4"); + uiDefBut(block, BUT, B_UVAUTO_STD8,"1/8",234,row-butHB,66,butH, 0, 0, 0, 0, 0, "Applies standard UV mapping 1/8"); + uiBlockEndAlign(block); + row-= 2*butHB+butS; + + uiBlockBeginAlign(block); + uiDefBut(block, BUT, B_UVAUTO_BOUNDS1,"Bounds 1/1",100,row,200,butH, 0, 0, 0, 0, 0, "Applies planar UV mapping with bounds 1/1"); + uiDefBut(block, BUT, B_UVAUTO_BOUNDS2,"1/2",100,row-butHB,66,butH, 0, 0, 0, 0, 0, "Applies planar UV mapping with bounds 1/2"); + uiDefBut(block, BUT, B_UVAUTO_BOUNDS4,"1/4",166,row-butHB,67,butH, 0, 0, 0, 0, 0, "Applies planar UV mapping with bounds 1/4"); + uiDefBut(block, BUT, B_UVAUTO_BOUNDS8,"1/8",234,row-butHB,66,butH, 0, 0, 0, 0, 0, "Applies planar UV mapping with bounds 1/8"); + uiDefBut(block, BUT, B_UVAUTO_WINDOW,"From Window",100,row-2*butH,200,butH, 0, 0, 0, 0, 0, "Applies planar UV mapping from window"); + uiBlockEndAlign(block); + row-= 3*butHB+butS; + + uiBlockBeginAlign(block); + uiDefButS(block,ROW,REDRAWVIEW3D,"No Edges",100,row,200,butH,&facesel_draw_edges, 2.0, 0, 0, 0, "Draw edges in 3D view"); + uiDefButS(block,ROW,REDRAWVIEW3D,"Draw Edges",100,row-butH,200,butH,&facesel_draw_edges, 2.0, 1.0, 0, 0, "Draw edges in 3D view"); + uiDefButS(block,ROW,REDRAWVIEW3D,"All Edges",100,row-2*butH,200,butH,&facesel_draw_edges, 2.0, 2.0, 0, 0, "Draw edges in 3D view"); + uiBlockEndAlign(block); + row-= 3*butHB+butS; + + row= 180; + + uiBlockBeginAlign(block); + uiDefBut(block, BUT, B_UVAUTO_CUBE,"Cube",315,row,200,butH, 0, 0, 0, 0, 0, "Applies cube UV mapping"); + uiDefButF(block, NUM,B_UVAUTO_CUBESIZE ,"Size:",315,row-butHB,200,butH, &uv_calc_cubesize, 0.0001, 100.0, 10, 0, "Defines the cubemap size"); + uiBlockEndAlign(block); + row-= 2*butHB+butS; + + uiBlockBeginAlign(block); + uiDefBut(block, BUT, B_UVAUTO_SPHERE,"Sphere",315,row,200,butH, 0, 0, 0, 0, 0, "Applies spherical UV mapping"); + uiBlockEndAlign(block); + row-= butHB+butS; + + uiBlockBeginAlign(block); + uiDefBut(block, BUT, B_UVAUTO_CYLINDER,"Cylinder",315,row,200,butH, 0, 0, 0, 0, 0, "Applies cylindrical UV mapping"); + uiDefButF(block, NUM,B_UVAUTO_CYLRADIUS ,"Radius:",315,row-butHB,200,butH, &uv_calc_radius, 0.1, 100.0, 10, 0, "Defines the radius of the UV mapping cylinder"); + uiBlockEndAlign(block); + row-= 2*butHB+butS; + + + uiBlockBeginAlign(block); + uiDefButS(block, ROW,B_UVAUTO_FACE,"View Aligns Face",315,row,200,butH, &uv_calc_mapdir,2.0, 1.0, 0.0,0.0, "View is on aequator for cylindrical and spherical UV mapping"); + uiDefButS(block, ROW,B_UVAUTO_TOP,"VA Top",315,row-butHB,100,butH, &uv_calc_mapdir,2.0, 0.0, 0.0,0.0, "View is on poles for cylindrical and spherical UV mapping"); + uiDefButS(block, ROW,B_UVAUTO_TOP,"Al Obj",415,row-butHB,100,butH, &uv_calc_mapdir,2.0, 2.0, 0.0,0.0, "Align to object for cylindrical and spherical UV mapping"); + uiBlockEndAlign(block); + row-= 2*butHB+butS; + + uiBlockBeginAlign(block); + uiDefButS(block, ROW,B_UVAUTO_ALIGNX,"Polar ZX",315,row,100,butH, &uv_calc_mapalign,2.0, 0.0, 0.0,0.0, "Polar 0 is X for cylindrical and spherical UV mapping"); + uiDefButS(block, ROW,B_UVAUTO_ALIGNY,"Polar ZY",415,row,100,butH, &uv_calc_mapalign,2.0, 1.0, 0.0,0.0, "Polar 0 is Y for cylindrical and spherical UV mapping"); + uiBlockEndAlign(block); +} /* this is a mode context sensitive system */ @@ -2141,8 +2231,10 @@ void editing_panels() editing_panel_mesh_tools1(ob, ob->data); // no editmode! } else { - if(G.f & G_FACESELECT) + if(G.f & G_FACESELECT) { editing_panel_mesh_texface(); + editing_panel_mesh_uvautocalculation(); + } if(G.f & (G_VERTEXPAINT | G_TEXTUREPAINT | G_WEIGHTPAINT) ) editing_panel_mesh_paint(); diff --git a/source/blender/src/drawmesh.c b/source/blender/src/drawmesh.c index b524ce1f9a7..6ce53b4adaf 100644 --- a/source/blender/src/drawmesh.c +++ b/source/blender/src/drawmesh.c @@ -536,52 +536,42 @@ void draw_tfaces3D(Object *ob, Mesh *me) MFace *mface; TFace *tface; DispList *dl; - float *v1, *v2, *v3, *v4, *extverts= NULL; - int a; - char col[4]; + float *v1, *v2, *v3, *v4; + float *av1= NULL, *av2= NULL, *av3= NULL, *av4= NULL, *extverts= NULL; + int a, activeFaceInSelection= 0; + extern short facesel_draw_edges; if(me==0 || me->tface==0) return; - glEnable(GL_DEPTH_TEST); - - /* Draw Faces, selected in the UV editor */ - if(G.f & G_DRAWFACES) { + dl= find_displist(&ob->disp, DL_VERTS); + if (dl) extverts= dl->verts; + + /* shadow view */ + if(facesel_draw_edges>0){ + if(facesel_draw_edges==2) glDisable(GL_DEPTH_TEST); + else glEnable(GL_DEPTH_TEST); + cpack(0x00); + mface= me->mface; tface= me->tface; - - BIF_GetThemeColor4ubv(TH_FACE_SELECT, col); - - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - glDepthMask(0); // disable write in zbuffer, needed for nice transp - for(a=me->totface; a>0; a--, mface++, tface++) { - if(mface->v3 && (tface->flag & TF_SELECT)) { - if(!(~tface->flag & (TF_SEL1|TF_SEL2|TF_SEL3)) && - (!mface->v4 || tface->flag & TF_SEL4)) { - glColor4ub(col[0], col[1], col[2], col[3]); - glBegin(mface->v4?GL_QUADS:GL_TRIANGLES); - glVertex3fv((me->mvert+mface->v1)->co); - glVertex3fv((me->mvert+mface->v2)->co); - glVertex3fv((me->mvert+mface->v3)->co); - if(mface->v4) glVertex3fv((me->mvert+mface->v4)->co); - glEnd(); - } - } + v1= (me->mvert+mface->v1)->co; + v2= (me->mvert+mface->v2)->co; + v3= (me->mvert+mface->v3)->co; + v4= mface->v4?(me->mvert+mface->v4)->co: NULL; + glBegin(GL_LINE_LOOP); + glVertex3fv(v1); + glVertex3fv(v2); + glVertex3fv(v3); + if(v4) glVertex3fv(v4); + glEnd(); } - - glDisable(GL_BLEND); - glDepthMask(1); // restore write in zbuffer } glDisable(GL_DEPTH_TEST); mface= me->mface; tface= me->tface; - - dl= find_displist(&ob->disp, DL_VERTS); - if (dl) extverts= dl->verts; - /* SELECT faces */ for(a=me->totface; a>0; a--, mface++, tface++) { if(mface->v3==0) continue; @@ -601,13 +591,8 @@ void draw_tfaces3D(Object *ob, Mesh *me) } if(tface->flag & TF_ACTIVE) { - /* colors: R=x G=y */ - cpack(0xFF); - glBegin(GL_LINE_STRIP); glVertex3fv(v1); if(v4) glVertex3fv(v4); else glVertex3fv(v3); glEnd(); - cpack(0xFF00); - glBegin(GL_LINE_STRIP); glVertex3fv(v1); glVertex3fv(v2); glEnd(); - cpack(0x0); - glBegin(GL_LINE_STRIP); glVertex3fv(v2); glVertex3fv(v3); if(v4) glVertex3fv(v4); glEnd(); + activeFaceInSelection= (tface->flag & TF_SELECT); + av1= v1; av2= v2; av3= v3; av4= v4; } else { cpack(0x0); @@ -618,7 +603,7 @@ void draw_tfaces3D(Object *ob, Mesh *me) if(v4) glVertex3fv( v4 ); glEnd(); } - + if(tface->flag & TF_SELECT) { cpack(0xFFFFFF); setlinestyle(1); @@ -633,6 +618,33 @@ void draw_tfaces3D(Object *ob, Mesh *me) } } + /* draw active face on top */ + /* colors: R=x G=y */ + if(av1) { + cpack(0xFF); + glBegin(GL_LINE_STRIP); + glVertex3fv(av1); + if(av4) glVertex3fv(av4); + else glVertex3fv(av3); + glEnd(); + + cpack(0xFF00); + glBegin(GL_LINE_STRIP); + glVertex3fv(av1); + glVertex3fv(av2); + glEnd(); + + if(activeFaceInSelection) cpack(0x00FFFF); + else cpack(0xFF00FF); + + glBegin(GL_LINE_STRIP); + glVertex3fv(av2); + glVertex3fv(av3); + if(av4) glVertex3fv(av4); + glEnd(); + setlinestyle(0); + } + glEnable(GL_DEPTH_TEST); } diff --git a/source/blender/src/editface.c b/source/blender/src/editface.c index 822744afd8b..ee35b916019 100644 --- a/source/blender/src/editface.c +++ b/source/blender/src/editface.c @@ -87,6 +87,7 @@ #include "mydevice.h" #include "blendef.h" #include "render.h" +#include "butspace.h" #include "TPT_DependKludge.h" @@ -95,9 +96,400 @@ #include "BSE_trans_types.h" #endif /* NAN_TPT */ -static float cumapsize= 1.0; TFace *lasttface=0; +static void uv_calc_center_vector(float *result, Object *ob, Mesh *me) +{ + float min[3], max[3], *cursx; + int a; + TFace *tface; + MFace *mface; + + switch (G.vd->around) + { + case V3D_CENTRE: /* bounding box center */ + min[0]= min[1]= min[2]= 1e20f; + max[0]= max[1]= max[2]= -1e20f; + + tface= me->tface; + mface= me->mface; + for(a=0; atotface; a++, mface++, tface++) { + if(tface->flag & TF_SELECT && mface->v3) { + DO_MINMAX((me->mvert+mface->v1)->co, min, max); + DO_MINMAX((me->mvert+mface->v2)->co, min, max); + DO_MINMAX((me->mvert+mface->v3)->co, min, max); + if(mface->v4) DO_MINMAX((me->mvert+mface->v4)->co, min, max); + } + } + VecMidf(result, min, max); + break; + case V3D_CURSOR: /*cursor center*/ + cursx= give_cursor(); + /* shift to objects world */ + result[0]= cursx[0]-ob->obmat[3][0]; + result[1]= cursx[1]-ob->obmat[3][1]; + result[2]= cursx[2]-ob->obmat[3][2]; + break; + case V3D_LOCAL: /*object center*/ + case V3D_CENTROID: /* multiple objects centers, only one object here*/ + default: + result[0]= result[1]= result[2]= 0.0; + break; + } +} + +static void uv_calc_map_matrix(float result[][4], Object *ob, float upangledeg, float sideangledeg, float radius) +{ + float rotup[4][4], rotside[4][4], viewmatrix[4][4], rotobj[4][4]; + float sideangle= 0.0, upangle= 0.0; + int k; + + /* get rotation of the current view matrix */ + Mat4CpyMat4(viewmatrix,G.vd->viewmat); + /* but shifting */ + for( k= 0; k< 4; k++) viewmatrix[3][k] =0.0; + + /* get rotation of the current object matrix */ + Mat4CpyMat4(rotobj,ob->obmat); + /* but shifting */ + for( k= 0; k< 4; k++) rotobj[3][k] =0.0; + + Mat4Clr(*rotup); + Mat4Clr(*rotside); + + /* compensate front/side.. against opengl x,y,z world definition */ + /* this is "kanonen gegen spatzen", a few plus minus 1 will do here */ + /* i wanted to keep the reason here, so we're rotating*/ + sideangle= M_PI * (sideangledeg + 180.0) /180.0; + rotside[0][0]= (float)cos(sideangle); + rotside[0][1]= -(float)sin(sideangle); + rotside[1][0]= (float)sin(sideangle); + rotside[1][1]= (float)cos(sideangle); + rotside[2][2]= 1.0f; + + upangle= M_PI * upangledeg /180.0; + rotup[1][1]= (float)cos(upangle)/radius; + rotup[1][2]= -(float)sin(upangle)/radius; + rotup[2][1]= (float)sin(upangle)/radius; + rotup[2][2]= (float)cos(upangle)/radius; + rotup[0][0]= (float)1.0/radius; + + /* calculate transforms*/ + Mat4MulSerie(result,rotup,rotside,viewmatrix,rotobj,NULL,NULL,NULL,NULL); +} + +static void uv_calc_shift_project(float *target, float *shift, float rotmat[][4], int projectionmode, float *source, float *min, float *max) +{ + float pv[3]; + + VecSubf(pv, source, shift); + Mat4MulVecfl(rotmat, pv); + + switch(projectionmode) { + case B_UVAUTO_CYLINDER: + tubemap(pv[0], pv[1], pv[2], &target[0],&target[1]); + /* split line is always zero */ + if (target[0] >= 1.0f) target[0] -= 1.0f; + break; + + case B_UVAUTO_SPHERE: + spheremap(pv[0], pv[1], pv[2], &target[0],&target[1]); + /* split line is always zero */ + if (target[0] >= 1.0f) target[0] -= 1.0f; + break; + + case 3: /* ortho special case for BOUNDS */ + target[0] = -pv[0]; + target[1] = pv[2]; + break; + + case 4: + { + /* very special case for FROM WINDOW */ + float pv4[4], dx, dy, x= 0.0, y= 0.0; + + dx= G.vd->area->winx; + dy= G.vd->area->winy; + + VecCopyf(pv4, source); + pv4[3] = 1.0; + + /* rotmat is the object matrix in this case */ + Mat4MulVec4fl(rotmat,pv4); + + /* almost project_short */ + Mat4MulVec4fl(G.vd->persmat,pv4); + if (fabs(pv[3]) > 0.00001) { /* avoid division by zero */ + target[0] = dx/2.0 + (dx/2.0)*pv4[0]/pv4[3]; + target[1] = dy/2.0 + (dy/2.0)*pv4[1]/pv4[3]; + } + else { + /* scaling is lost but give a valid result */ + target[0] = dx/2.0 + (dx/2.0)*pv4[0]; + target[1] = dy/2.0 + (dy/2.0)*pv4[1]; + } + + /* G.vd->persmat seems to do this funky scaling */ + if(dx > dy) { + y= (dx-dy)/2.0; + dy = dx; + } + else { + x= (dy-dx)/2.0; + dx = dy; + } + target[0]= (x + target[0])/dx; + target[1]= (y + target[1])/dy; + + } + break; + + default: + target[0] = 0.0; + target[1] = 1.0; + } + + /* we know the values here and may need min_max later */ + /* max requests independand from min; not fastest but safest */ + if(min) { + min[0] = MIN2(target[0], min[0]); + min[1] = MIN2(target[1], min[1]); + } + if(max) { + max[0] = MAX2(target[0], max[0]); + max[1] = MAX2(target[1], max[1]); + } +} + +void calculate_uv_map(unsigned short mapmode) +{ + Mesh *me; + TFace *tface; + MFace *mface; + Object *ob; + float dx, dy, rotatematrix[4][4], radius= 1.0, min[3], cent[3], max[3]; + float fac= 1.0, upangledeg= 0.0, sideangledeg= 90.0; + int i, b, mi, a, n; + /* settings from buttonswindow */ + extern float uv_calc_radius, uv_calc_cubesize; + extern short uv_calc_mapdir, uv_calc_mapalign; + + if(uv_calc_mapdir==1) { + upangledeg= 90.0; + sideangledeg= 0.0; + } + else { + upangledeg= 0.0; + if(uv_calc_mapalign==1) sideangledeg= 0.0; + else sideangledeg= 90.0; + } + + me= get_mesh(ob=OBACT); + if(me==0 || me->tface==0) return; + if(me->totface==0) return; + + switch(mapmode) { + case B_UVAUTO_BOUNDS1: + case B_UVAUTO_BOUNDS2: + case B_UVAUTO_BOUNDS4: + case B_UVAUTO_BOUNDS8: + switch(mapmode) { + case B_UVAUTO_BOUNDS2: fac = 0.5; break; + case B_UVAUTO_BOUNDS4: fac = 0.25; break; + case B_UVAUTO_BOUNDS8: fac = 0.125; break; + } + + min[0]= min[1]= 1.0; + max[0]= max[1]= 0.0; + + uv_calc_center_vector(cent, ob, me); + uv_calc_map_matrix(rotatematrix, ob, upangledeg, sideangledeg, 1.0f); + + tface= me->tface; + mface= me->mface; + for(a=0; atotface; a++, mface++, tface++) { + if(tface->flag & TF_SELECT && mface->v3) { + uv_calc_shift_project(tface->uv[0],cent,rotatematrix,3,(me->mvert+mface->v1)->co,min,max); + uv_calc_shift_project(tface->uv[1],cent,rotatematrix,3,(me->mvert+mface->v2)->co,min,max); + uv_calc_shift_project(tface->uv[2],cent,rotatematrix,3,(me->mvert+mface->v3)->co,min,max); + if(mface->v4) + uv_calc_shift_project(tface->uv[3],cent,rotatematrix,3,(me->mvert+mface->v4)->co,min,max); + } + } + + /* rescale UV to be in 0..1,1/2,1/4,1/8 */ + dx= (max[0]-min[0]); + dy= (max[1]-min[1]); + + tface= me->tface; + mface= me->mface; + for(a=0; atotface; a++, mface++, tface++) { + if(tface->flag & TF_SELECT && mface->v3) { + if(mface->v4) b= 3; else b= 2; + for(; b>=0; b--) { + tface->uv[b][0]= ((tface->uv[b][0]-min[0])*fac)/dx; + tface->uv[b][1]= 1.0-fac+((tface->uv[b][1]-min[1])*fac)/dy; + } + } + } + break; + + case B_UVAUTO_WINDOW: + cent[0] = cent[1] = cent[2] = 0.0; + Mat4CpyMat4(rotatematrix,ob->obmat); + + tface= me->tface; + mface= me->mface; + for(a=0; atotface; a++, mface++, tface++) { + if(tface->flag & TF_SELECT && mface->v3) { + uv_calc_shift_project(tface->uv[0],cent,rotatematrix,4,(me->mvert+mface->v1)->co,NULL,NULL); + uv_calc_shift_project(tface->uv[1],cent,rotatematrix,4,(me->mvert+mface->v2)->co,NULL,NULL); + uv_calc_shift_project(tface->uv[2],cent,rotatematrix,4,(me->mvert+mface->v3)->co,NULL,NULL); + if(mface->v4) + uv_calc_shift_project(tface->uv[3],cent,rotatematrix,4,(me->mvert+mface->v4)->co,NULL,NULL); + } + } + break; + + case B_UVAUTO_STD8: + case B_UVAUTO_STD4: + case B_UVAUTO_STD2: + case B_UVAUTO_STD1: + switch(mapmode) { + case B_UVAUTO_STD8: fac = 0.125; break; + case B_UVAUTO_STD4: fac = 0.25; break; + case B_UVAUTO_STD2: fac = 0.5; break; + } + + tface= me->tface; + for(a=0; atotface; a++, tface++) + if(tface->flag & TF_SELECT) + default_uv(tface->uv, fac); + break; + + case B_UVAUTO_CYLINDER: + case B_UVAUTO_SPHERE: + uv_calc_center_vector(cent, ob, me); + + if(mapmode==B_UVAUTO_CYLINDER) radius = uv_calc_radius; + + /* be compatible to the "old" sphere/cylinder mode */ + if (uv_calc_mapdir== 2) + Mat4One(rotatematrix); + else + uv_calc_map_matrix(rotatematrix,ob,upangledeg,sideangledeg,radius); + + tface= me->tface; + mface= me->mface; + for(a=0; atotface; a++, mface++, tface++) { + if(tface->flag & TF_SELECT && mface->v3) { + uv_calc_shift_project(tface->uv[0],cent,rotatematrix,mapmode,(me->mvert+mface->v1)->co,NULL,NULL); + uv_calc_shift_project(tface->uv[1],cent,rotatematrix,mapmode,(me->mvert+mface->v2)->co,NULL,NULL); + uv_calc_shift_project(tface->uv[2],cent,rotatematrix,mapmode,(me->mvert+mface->v3)->co,NULL,NULL); + n = 3; + if(mface->v4) { + uv_calc_shift_project(tface->uv[3],cent,rotatematrix,mapmode,(me->mvert+mface->v4)->co,NULL,NULL); + n=4; + } + + mi = 0; + for (i = 1; i < n; i++) + if (tface->uv[i][0] > tface->uv[mi][0]) mi = i; + + for (i = 0; i < n; i++) { + if (i != mi) { + dx = tface->uv[mi][0] - tface->uv[i][0]; + if (dx > 0.5) tface->uv[i][0] += 1.0; + } + } + } + } + + break; + + case B_UVAUTO_CUBE: + { + /* choose x,y,z axis for projetion depending on the largest normal */ + /* component, but clusters all together around the center of map */ + float no[3]; + short cox, coy; + float *loc= ob->obmat[3]; + MVert *mv= me->mvert; + + tface= me->tface; + mface= me->mface; + for(a=0; atotface; a++, mface++, tface++) { + if(tface->flag & TF_SELECT && mface->v3) { + CalcNormFloat((mv+mface->v1)->co, (mv+mface->v2)->co, (mv+mface->v3)->co, no); + + no[0]= fabs(no[0]); + no[1]= fabs(no[1]); + no[2]= fabs(no[2]); + + cox=0; coy= 1; + if(no[2]>=no[0] && no[2]>=no[1]); + else if(no[1]>=no[0] && no[1]>=no[2]) coy= 2; + else { cox= 1; coy= 2; } + + tface->uv[0][0]= 0.5+0.5*uv_calc_cubesize*(loc[cox] + (mv+mface->v1)->co[cox]); + tface->uv[0][1]= 0.5+0.5*uv_calc_cubesize*(loc[coy] + (mv+mface->v1)->co[coy]); + dx = floor(tface->uv[0][0]); + dy = floor(tface->uv[0][1]); + tface->uv[0][0] -= dx; + tface->uv[0][1] -= dy; + tface->uv[1][0]= 0.5+0.5*uv_calc_cubesize*(loc[cox] + (mv+mface->v2)->co[cox]); + tface->uv[1][1]= 0.5+0.5*uv_calc_cubesize*(loc[coy] + (mv+mface->v2)->co[coy]); + tface->uv[1][0] -= dx; + tface->uv[1][1] -= dy; + tface->uv[2][0]= 0.5+0.5*uv_calc_cubesize*(loc[cox] + (mv+mface->v3)->co[cox]); + tface->uv[2][1]= 0.5+0.5*uv_calc_cubesize*(loc[coy] + (mv+mface->v3)->co[coy]); + tface->uv[2][0] -= dx; + tface->uv[2][1] -= dy; + if(mface->v4) { + tface->uv[3][0]= 0.5+0.5*uv_calc_cubesize*(loc[cox] + (mv+mface->v4)->co[cox]); + tface->uv[3][1]= 0.5+0.5*uv_calc_cubesize*(loc[coy] + (mv+mface->v4)->co[coy]); + tface->uv[3][0] -= dx; + tface->uv[3][1] -= dy; + } + } + } + } + break; + default: + return; + } /* end switch mapmode */ + + /* clipping and wrapping */ + if(G.sima && G.sima->flag & SI_CLIP_UV) { + tface= me->tface; + mface= me->mface; + for(a=0; atotface; a++, mface++, tface++) { + if(!(tface->flag & TF_SELECT && mface->v3)) return; + + dx= dy= 0; + if(mface->v4) b= 3; else b= 2; + for(; b>=0; b--) { + while(tface->uv[b][0] + dx < 0.0) dx+= 0.5; + while(tface->uv[b][0] + dx > 1.0) dx-= 0.5; + while(tface->uv[b][1] + dy < 0.0) dy+= 0.5; + while(tface->uv[b][1] + dy > 1.0) dy-= 0.5; + } + + if(mface->v4) b= 3; else b= 2; + for(; b>=0; b--) { + tface->uv[b][0]+= dx; + CLAMP(tface->uv[b][0], 0.0, 1.0); + + tface->uv[b][1]+= dy; + CLAMP(tface->uv[b][1], 0.0, 1.0); + } + } + } + + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWIMAGE, 0); +} + void set_lasttface() { Mesh *me; @@ -349,7 +741,6 @@ void deselectall_tface() } allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWIMAGE, 0); - } void selectswap_tface(void) @@ -453,7 +844,7 @@ void rotate_uv_tface() * @param y the y-coordinate to pick at * @return the face under the cursor (-1 if there was no face found) */ -unsigned int face_pick(Mesh *me, short x, short y) +int face_pick(Mesh *me, short x, short y) { unsigned int col; int index; @@ -497,8 +888,7 @@ void face_select() TFace *tface, *tsel; MFace *msel; short mval[2]; - int a; - unsigned int index; + int a, index; /* Get the face under the cursor */ ob = OBACT; @@ -519,39 +909,22 @@ void face_select() tface = me->tface; a = me->totface; while (a--) { - if (G.qual & LR_SHIFTKEY) { + if (G.qual & LR_SHIFTKEY) tface->flag &= ~TF_ACTIVE; - } - else { + else tface->flag &= ~(TF_ACTIVE+TF_SELECT); - if (G.qual & LR_ALTKEY) - tface->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4); - } tface++; } tsel->flag |= TF_ACTIVE; - if (G.qual & LR_ALTKEY) { - if(tsel->flag & TF_SELECT && !(~tsel->flag & (TF_SEL1|TF_SEL2|TF_SEL3)) - && (!msel->v4 || tsel->flag & TF_SEL4)) - tsel->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4); - else { - tsel->flag |= TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4; - tsel->flag |= TF_SELECT; - } - } - else if (G.qual & LR_SHIFTKEY) { - if (tsel->flag & TF_SELECT) { + if (G.qual & LR_SHIFTKEY) { + if (tsel->flag & TF_SELECT) tsel->flag &= ~TF_SELECT; - } - else { + else tsel->flag |= TF_SELECT; - } - } - else { - tsel->flag |= TF_SELECT; } + else tsel->flag |= TF_SELECT; lasttface = tsel; @@ -665,458 +1038,48 @@ float CalcNormUV(float *a, float *b, float *c) void uv_autocalc_tface() { - Mesh *me; - TFace *tface; - MFace *mface; - MVert *mv; - Object *ob; - float dx, dy, x, y, min[3], cent[3], max[3], no[3], *loc, mat[4][4]; - float fac = 1.0; - - int i, n, mi; /* strubi */ - int a, b; - short cox, coy, mode, adr[2]; - - areawinset(curarea->win); - persp(PERSP_VIEW); - - me= get_mesh(ob=OBACT); - if(me==0 || me->tface==0) return; - if(me->totface==0) return; - + short mode; mode= pupmenu(MENUTITLE("UV Calculation") - MENUSTRING("Cube", UV_CUBE_MAPPING) "|" - MENUSTRING("Cylinder", UV_CYL_MAPPING) "|" - MENUSTRING("Sphere", UV_SPHERE_MAPPING) "|" - MENUSTRING("Bounds to 1/8", UV_BOUNDS8_MAPPING) "|" - MENUSTRING("Bounds to 1/4", UV_BOUNDS4_MAPPING) "|" - MENUSTRING("Bounds to 1/2", UV_BOUNDS2_MAPPING) "|" - MENUSTRING("Bounds to 1/1", UV_BOUNDS1_MAPPING) "|" - MENUSTRING("Standard 1/8", UV_STD8_MAPPING) "|" - MENUSTRING("Standard 1/4", UV_STD4_MAPPING) "|" - MENUSTRING("Standard 1/2", UV_STD2_MAPPING) "|" - MENUSTRING("Standard 1/1", UV_STD1_MAPPING) "|" - MENUSTRING("From Window", UV_WINDOW_MAPPING) "|" - MENUSTRING("From Window To Sphere", UV_SPHERE_EX) "|" - MENUSTRING("From Window To Cylinder", UV_CYL_EX) ); - + MENUSTRING("Cube", UV_CUBE_MAPPING) "|" + MENUSTRING("Cylinder", UV_CYL_MAPPING) "|" + MENUSTRING("Sphere", UV_SPHERE_MAPPING) "|" + MENUSTRING("Bounds to 1/8", UV_BOUNDS8_MAPPING) "|" + MENUSTRING("Bounds to 1/4", UV_BOUNDS4_MAPPING) "|" + MENUSTRING("Bounds to 1/2", UV_BOUNDS2_MAPPING) "|" + MENUSTRING("Bounds to 1/1", UV_BOUNDS1_MAPPING) "|" + MENUSTRING("Standard 1/8", UV_STD8_MAPPING) "|" + MENUSTRING("Standard 1/4", UV_STD4_MAPPING) "|" + MENUSTRING("Standard 1/2", UV_STD2_MAPPING) "|" + MENUSTRING("Standard 1/1", UV_STD1_MAPPING) "|" + MENUSTRING("From Window", UV_WINDOW_MAPPING) ); + + switch(mode) { case UV_CUBE_MAPPING: - tface= me->tface; - mface= me->mface; - mv= me->mvert; - loc= ob->obmat[3]; - - fbutton(&cumapsize, 0.0001, 100.0, "Cubemap size"); - - for(a=0; atotface; a++, mface++, tface++) { - if(tface->flag & TF_SELECT) { - if(mface->v3==0) continue; - - CalcNormFloat((mv+mface->v1)->co, (mv+mface->v2)->co, (mv+mface->v3)->co, no); - - no[0]= fabs(no[0]); - no[1]= fabs(no[1]); - no[2]= fabs(no[2]); - - cox=0; coy= 1; - if(no[2]>=no[0] && no[2]>=no[1]); - else if(no[1]>=no[0] && no[1]>=no[2]) coy= 2; - else { cox= 1; coy= 2;} - - tface->uv[0][0]= 0.5+0.5*cumapsize*(loc[cox] + (mv+mface->v1)->co[cox]); - tface->uv[0][1]= 0.5+0.5*cumapsize*(loc[coy] + (mv+mface->v1)->co[coy]); - dx = floor(tface->uv[0][0]); - dy = floor(tface->uv[0][1]); - tface->uv[0][0] -= dx; - tface->uv[0][1] -= dy; - tface->uv[1][0]= 0.5+0.5*cumapsize*(loc[cox] + (mv+mface->v2)->co[cox]); - tface->uv[1][1]= 0.5+0.5*cumapsize*(loc[coy] + (mv+mface->v2)->co[coy]); - tface->uv[1][0] -= dx; - tface->uv[1][1] -= dy; - tface->uv[2][0]= 0.5+0.5*cumapsize*(loc[cox] + (mv+mface->v3)->co[cox]); - tface->uv[2][1]= 0.5+0.5*cumapsize*(loc[coy] + (mv+mface->v3)->co[coy]); - tface->uv[2][0] -= dx; - tface->uv[2][1] -= dy; - if(mface->v4) { - tface->uv[3][0]= 0.5+0.5*cumapsize*(loc[cox] + (mv+mface->v4)->co[cox]); - tface->uv[3][1]= 0.5+0.5*cumapsize*(loc[coy] + (mv+mface->v4)->co[coy]); - tface->uv[3][0] -= dx; - tface->uv[3][1] -= dy; - } - - } - } - - case UV_BOUNDS8_MAPPING: - fac = 0.125; - goto bounds_mapping; - case UV_BOUNDS4_MAPPING: - fac = 0.25; - goto bounds_mapping; - case UV_BOUNDS2_MAPPING: - fac = 0.5; - goto bounds_mapping; - case UV_BOUNDS1_MAPPING: - // fac = 1.0; was already initialized as 1.0 - case UV_WINDOW_MAPPING: - bounds_mapping: - mymultmatrix(ob->obmat); - MTC_Mat4SwapMat4(G.vd->persmat, mat); - mygetsingmatrix(G.vd->persmat); - - tface= me->tface; - mface= me->mface; - - dx= curarea->winx; - dy= curarea->winy; - - x= y= 0.0; - if (dx > dy) { - y= (dx-dy)/ 2.0; - dy= dx; - } - else { - x= (dy-dx)/ 2.0; - dx= dy; - } - - for(a=0; atotface; a++, mface++, tface++) { - if(tface->flag & TF_SELECT) { - - if(mface->v3==0) continue; - - project_short( (me->mvert+mface->v1)->co, adr); - if(adr[0]!=3200) { - tface->uv[0][0]= (x+((float)adr[0]))/dx; - tface->uv[0][1]= (y+((float)adr[1]))/dy; - } - project_short( (me->mvert+mface->v2)->co, adr); - if(adr[0]!=3200) { - tface->uv[1][0]= (x+((float)adr[0]))/dx; - tface->uv[1][1]= (y+((float)adr[1]))/dy; - } - project_short( (me->mvert+mface->v3)->co, adr); - if(adr[0]!=3200) { - tface->uv[2][0]= (x+((float)adr[0]))/dx; - tface->uv[2][1]= (y+((float)adr[1]))/dy; - } - if(mface->v4) { - project_short( (me->mvert+mface->v4)->co, adr); - if(adr[0]!=3200) { - tface->uv[3][0]= (x+((float)adr[0]))/dx; - tface->uv[3][1]= (y+((float)adr[1]))/dy; - } - } - } - } - - //stop here if WINDOW_MAPPING: - if (mode == UV_WINDOW_MAPPING) break; - - /* minmax */ - min[0]= min[1]= 1.0; - max[0]= max[1]= 0.0; - tface= me->tface; - mface= me->mface; - for(a=0; atotface; a++, mface++, tface++) { - if(tface->flag & TF_SELECT) { - if(mface->v3==0) continue; - - if(mface->v4) b= 3; else b= 2; - for(; b>=0; b--) { - min[0]= MIN2(tface->uv[b][0], min[0]); - min[1]= MIN2(tface->uv[b][1], min[1]); - max[0]= MAX2(tface->uv[b][0], max[0]); - max[1]= MAX2(tface->uv[b][1], max[1]); - } - } - } - - dx= max[0]-min[0]; - dy= max[1]-min[1]; - - tface= me->tface; - mface= me->mface; - for(a=0; atotface; a++, mface++, tface++) { - if(tface->flag & TF_SELECT) { - if(mface->v3==0) continue; - - if(mface->v4) b= 3; else b= 2; - for(; b>=0; b--) { - tface->uv[b][0]= ((tface->uv[b][0] - min[0])* fac) / dx; - tface->uv[b][1]= 1.0 - fac + ((tface->uv[b][1] - min[1]) * fac) /dy; - } - } - } - break; - + calculate_uv_map(B_UVAUTO_CUBE); break; + case UV_CYL_MAPPING: + calculate_uv_map(B_UVAUTO_CYLINDER); break; + case UV_SPHERE_MAPPING: + calculate_uv_map(B_UVAUTO_SPHERE); break; + case UV_BOUNDS8_MAPPING: + calculate_uv_map(B_UVAUTO_BOUNDS8); break; + case UV_BOUNDS4_MAPPING: + calculate_uv_map(B_UVAUTO_BOUNDS4); break; + case UV_BOUNDS2_MAPPING: + calculate_uv_map(B_UVAUTO_BOUNDS2); break; + case UV_BOUNDS1_MAPPING: + calculate_uv_map(B_UVAUTO_BOUNDS1); break; case UV_STD8_MAPPING: - fac = 0.125; - goto standard_mapping; + calculate_uv_map(B_UVAUTO_STD8); break; case UV_STD4_MAPPING: - fac = 0.25; - goto standard_mapping; + calculate_uv_map(B_UVAUTO_STD4); break; case UV_STD2_MAPPING: - fac = 0.5; - goto standard_mapping; + calculate_uv_map(B_UVAUTO_STD2); break; case UV_STD1_MAPPING: - fac = 1.0; - - standard_mapping: - tface= me->tface; - for(a=0; atotface; a++, tface++) { - if(tface->flag & TF_SELECT) { - default_uv(tface->uv, fac); - } - } - break; - - case UV_SPHERE_MAPPING: - case UV_CYL_MAPPING: - - /* calc centre */ - - INIT_MINMAX(min, max); - - tface= me->tface; - mface= me->mface; - for(a=0; atotface; a++, mface++, tface++) { - if(tface->flag & TF_SELECT) { - if(mface->v3==0) continue; - - DO_MINMAX( (me->mvert+mface->v1)->co, min, max); - DO_MINMAX( (me->mvert+mface->v2)->co, min, max); - DO_MINMAX( (me->mvert+mface->v3)->co, min, max); - if(mface->v4) DO_MINMAX( (me->mvert+mface->v3)->co, min, max); - } - } - - VecMidf(cent, min, max); - - tface= me->tface; - mface= me->mface; - for(a=0; atotface; a++, mface++, tface++) { - if(tface->flag & TF_SELECT) { - if(mface->v3==0) continue; - - VecSubf(no, (me->mvert+mface->v1)->co, cent); - if(mode==UV_CYL_MAPPING) tubemap(no[0], no[1], no[2], tface->uv[0], &tface->uv[0][1]); - else spheremap(no[0], no[1], no[2], tface->uv[0], &tface->uv[0][1]); - - VecSubf(no, (me->mvert+mface->v2)->co, cent); - if(mode==UV_CYL_MAPPING) tubemap(no[0], no[1], no[2], tface->uv[1], &tface->uv[1][1]); - else spheremap(no[0], no[1], no[2], tface->uv[1], &tface->uv[1][1]); - - VecSubf(no, (me->mvert+mface->v3)->co, cent); - if(mode==UV_CYL_MAPPING) tubemap(no[0], no[1], no[2], tface->uv[2], &tface->uv[2][1]); - else spheremap(no[0], no[1], no[2], tface->uv[2], &tface->uv[2][1]); - n = 3; - - if(mface->v4) { - VecSubf(no, (me->mvert+mface->v4)->co, cent); - if(mode==3) tubemap(no[0], no[1], no[2], tface->uv[3], &tface->uv[3][1]); - else spheremap(no[0], no[1], no[2], tface->uv[3], &tface->uv[3][1]); - n = 4; - } - mi = 0; - for (i = 1; i < n; i++) - { - if (tface->uv[i][0] > tface->uv[mi][0]) mi = i; - } - for (i = 0; i < n; i++) - { - if (i != mi) { - dx = tface->uv[mi][0] - tface->uv[i][0]; - if (dx > 0.5) { - tface->uv[i][0] += 1.0; - } - } - } - } - } - break; - case UV_CYL_EX: - case UV_SPHERE_EX: - { - float rotup[4][4],rotside[4][4], viewmatrix[4][4], finalmatrix[4][4],rotobj[4][4]; - int k; - float upangle = 0.0, sideangle = 0.0, radius = 1.0; - static float upangledeg = 0.0, sideangledeg = 90.0; - short centermode; - - centermode = G.vd->around; - /* check if we can do this, do it, otherways tell the user we can't and quit */ - switch (centermode) - { - case V3D_CENTRE : /*bounding box center*/ - INIT_MINMAX(min, max); - - tface= me->tface; - mface= me->mface; - for(a=0; atotface; a++, mface++, tface++) { - if(tface->flag & TF_SELECT) { - if(mface->v3==0) continue; /* this is not realy a face */ - - DO_MINMAX( (me->mvert+mface->v1)->co, min, max); - DO_MINMAX( (me->mvert+mface->v2)->co, min, max); - DO_MINMAX( (me->mvert+mface->v3)->co, min, max); - if(mface->v4) DO_MINMAX( (me->mvert+mface->v3)->co, min, max); - } - } - VecMidf(cent, min, max); - break; - case V3D_CURSOR : /*cursor center*/ - { - float *cursx; - cursx= give_cursor(); - /* shift to objects world */ - cent[0]= cursx[0]-ob->obmat[3][0]; - cent[1]= cursx[1]-ob->obmat[3][1]; - cent[2]= cursx[2]-ob->obmat[3][2]; - } - break; - case V3D_LOCAL : /*object center*/ - case V3D_CENTROID : /*median refers to multiple objects centers. only one object here*/ - cent[0]= cent[1]= cent[2]= 0.0; - break; - default : /* covered all known modes, but if there was a new one */ - /* say something to the user if we can't*/ - okee("this operation center does not work here!"); - return; - } - - if(mode==UV_CYL_EX){ - static float cylradius = 1.0; /* static to remeber last user response */ - if (fbutton(&cylradius, 0.1, 90.0, "radius") == 0) return; - radius = cylradius; - } - - /* get rotation of the current view matrix */ - Mat4CpyMat4(viewmatrix,G.vd->viewmat); - /* but shifting */ - for( k= 0; k< 4; k++) { - viewmatrix[3][k] =0.0; - } - - /* get rotation of the current object matrix */ - Mat4CpyMat4(rotobj,ob->obmat); - /* but shifting */ - for( k= 0; k< 4; k++){ - rotobj[3][k] =0.0; - } - - /* never assume local variables to be zeroed */ - Mat4Clr(*rotup); - Mat4Clr(*rotside); - - /* need this to compensate front/side.. against opengl x,y,z world definition */ - /* this is "kanonen gegen spatzen" i know, a few plus minus 1 will do here */ - /* i wanted to keep the reason here, so we're rotating*/ - /* debug helper if (fbutton(&sideangledeg, -180.0, 180, "Side angle") ==0) return; */ - sideangle = M_PI * (sideangledeg + 180.0) /180.0; - rotside[0][0] = cos(sideangle); rotside[0][1] = -sin(sideangle); - rotside[1][0] = sin(sideangle); rotside[1][1] = cos(sideangle); - rotside[2][2] = 1.0; - - /* debug helper if (fbutton(&upangledeg, -90.0, 90.0, "Up angle") ==0) return; */ - upangle = M_PI * upangledeg /180.0; - rotup[1][1] = cos(upangle)/radius; rotup[1][2] = -sin(upangle)/radius; - rotup[2][1] = sin(upangle)/radius; rotup[2][2] = cos(upangle)/radius; - rotup[0][0] = 1.0/radius; - /* calculate transforms*/ - Mat4MulSerie(finalmatrix,rotup,rotside,viewmatrix,rotobj,NULL,NULL,NULL,NULL); - /* now finalmatrix holds what we want */ - - tface= me->tface; - mface= me->mface; - for(a=0; atotface; a++, mface++, tface++) { /* go for all faces of the given mesh */ - if(tface->flag & TF_SELECT) { /* if this face is selected in UI */ - if(mface->v3==0) continue; /* must be ploygon with more than 2 vertices */ - /* repeating this for all 3(4) vertices sucks. better make function*/ - VecSubf(no, (me->mvert+mface->v1)->co, cent); /* shift to make cent the origin */ - Mat4MulVecfl(finalmatrix, no); - if(mode==UV_CYL_EX) tubemap(no[0], no[1], no[2], tface->uv[0], &tface->uv[0][1]); - else spheremap(no[0], no[1], no[2], tface->uv[0], &tface->uv[0][1]); - - VecSubf(no, (me->mvert+mface->v2)->co, cent); - Mat4MulVecfl(finalmatrix, no); - if(mode==UV_CYL_EX) tubemap(no[0], no[1], no[2], tface->uv[1], &tface->uv[1][1]); - else spheremap(no[0], no[1], no[2], tface->uv[1], &tface->uv[1][1]); - - VecSubf(no, (me->mvert+mface->v3)->co, cent); - Mat4MulVecfl(finalmatrix, no); - if(mode==UV_CYL_EX) tubemap(no[0], no[1], no[2], tface->uv[2], &tface->uv[2][1]); - else spheremap(no[0], no[1], no[2], tface->uv[2], &tface->uv[2][1]); - n = 3; - - if(mface->v4) { - - VecSubf(no, (me->mvert+mface->v4)->co, cent); - Mat4MulVecfl(finalmatrix, no); - if(mode==UV_CYL_EX) tubemap(no[0], no[1], no[2], tface->uv[3], &tface->uv[3][1]); - else spheremap(no[0], no[1], no[2], tface->uv[3], &tface->uv[3][1]); - n = 4; - } - mi = 0; /* maximum index */ - - for (i = 1; i < n; i++) { - if (tface->uv[i][0] > tface->uv[mi][0]) mi = i; - } - for (i = 0; i < n; i++) { - if (i != mi) { - dx = tface->uv[mi][0] - tface->uv[i][0]; - if (dx > 0.5) { - tface->uv[i][0] += 1.0; - } - } - } - } - } + calculate_uv_map(B_UVAUTO_STD1); break; + case UV_WINDOW_MAPPING: + calculate_uv_map(B_UVAUTO_WINDOW); break; } - break; - default: - return; - } // end switch - - /* clipping and wrapping */ - if(G.sima && G.sima->flag & SI_CLIP_UV) { - tface= me->tface; - mface= me->mface; - for(a=0; atotface; a++, mface++, tface++) { - if(tface->flag & TF_SELECT) { - if(mface->v3==0) continue; - - dx= dy= 0; - if(mface->v4) b= 3; else b= 2; - for(; b>=0; b--) { - while(tface->uv[b][0] + dx < 0.0) dx+= 0.5; - while(tface->uv[b][0] + dx > 1.0) dx-= 0.5; - while(tface->uv[b][1] + dy < 0.0) dy+= 0.5; - while(tface->uv[b][1] + dy > 1.0) dy-= 0.5; - } - - if(mface->v4) b= 3; else b= 2; - for(; b>=0; b--) { - tface->uv[b][0]+= dx; - CLAMP(tface->uv[b][0], 0.0, 1.0); - - tface->uv[b][1]+= dy; - CLAMP(tface->uv[b][1], 0.0, 1.0); - } - } - } - } - - makeDispList(OBACT); - - allqueue(REDRAWVIEW3D, 0); - allqueue(REDRAWIMAGE, 0); - myloadmatrix(G.vd->viewmat); - MTC_Mat4SwapMat4(G.vd->persmat, mat); - - persp(PERSP_WIN); - } void set_faceselect() /* toggle */ @@ -1421,8 +1384,7 @@ void face_draw() Image *img=NULL, *img_old = NULL; IMG_BrushPtr brush; IMG_CanvasPtr canvas = 0; - int rowBytes; - unsigned int face_index; + int rowBytes, face_index; char *warn_packed_file = 0; float uv[2], uv_old[2]; extern VPaint Gvp; diff --git a/source/blender/src/editsima.c b/source/blender/src/editsima.c index a0a94caa2a9..54dccca6512 100644 --- a/source/blender/src/editsima.c +++ b/source/blender/src/editsima.c @@ -1132,9 +1132,7 @@ void mouse_select_sima(void) *flagpoin |= val; } - if(redraw || G.f & G_DRAWFACES) { - force_draw_plus(SPACE_VIEW3D); - } + if(redraw || G.f & G_DRAWFACES) force_draw(); else { glDrawBuffer(GL_FRONT); draw_tfaces(); @@ -1281,7 +1279,7 @@ void uvedit_selectionCB(short selecting, Object *editobj, short *mval, float rad if(G.f & G_DRAWFACES) { /* full redraw only if necessary */ draw_sel_circle(0, 0, 0, 0, 0); /* signal */ - force_draw_plus(SPACE_VIEW3D); + force_draw(); } else { /* force_draw() is no good here... */ glDrawBuffer(GL_FRONT);