diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-02-09 23:58:31 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-02-09 23:58:31 +0300 |
commit | 283926aa2d0c6366d92a4f38e994e843b73659f6 (patch) | |
tree | 2bd35e5609efa63882ab81eab9e8009a691c5acb /source/blender/editors/mesh/editface.c | |
parent | c02bc1ce5379356b5c17034457a59aebf6e41725 (diff) |
2.5: UV Editor module porting pretty much finished now, only missing
still is mirror transform. This commits adds the remaining operators:
* UV mapping operators (U key menu): cube, sphere, cylinder, etc.
* Hide/Show operators.
And solves most XXX's, including:
* Fix bad includes and calls into space image.
* Aspect ratio correction.
* Create UVs if they don't exist yet on unwrap.
* Assign image to UVs.
* Drawing proportional edit circle.
Diffstat (limited to 'source/blender/editors/mesh/editface.c')
-rw-r--r-- | source/blender/editors/mesh/editface.c | 544 |
1 files changed, 0 insertions, 544 deletions
diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c index f2dd68973b8..6c17dff3428 100644 --- a/source/blender/editors/mesh/editface.c +++ b/source/blender/editors/mesh/editface.c @@ -81,27 +81,6 @@ /* own include */ #include "mesh_intern.h" - -/* Pupmenu codes: */ -#define UV_CUBE_MAPPING 2 -#define UV_CYL_MAPPING 3 -#define UV_SPHERE_MAPPING 4 -#define UV_BOUNDS_MAPPING 5 -#define UV_RESET_MAPPING 6 -#define UV_WINDOW_MAPPING 7 -#define UV_UNWRAP_MAPPING 8 -#define UV_CYL_EX 32 -#define UV_SPHERE_EX 34 - -/* Some macro tricks to make pupmenu construction look nicer :-) - Sorry, just did it for fun. */ - -#define _STR(x) " " #x -#define STRING(x) _STR(x) - -#define MENUSTRING(string, code) string " %x" STRING(code) -#define MENUTITLE(string) string " %t|" - /* ***************** XXX **************** */ static int sample_backbuf_rect() {return 0;} static int sample_backbuf() {return 0;} @@ -139,462 +118,6 @@ int facesel_face_pick(View3D *v3d, Mesh *me, short *mval, unsigned int *index, s return 1; } -/* only operates on the edit object - this is all thats needed at the moment */ -static void uv_calc_center_vector(Scene *scene, View3D *v3d, float *result, Object *ob, EditMesh *em) -{ - float min[3], max[3], *cursx; - - EditFace *efa; - switch (v3d->around) - { - case V3D_CENTER: /* bounding box center */ - min[0]= min[1]= min[2]= 1e20f; - max[0]= max[1]= max[2]= -1e20f; - - for (efa= em->faces.first; efa; efa= efa->next) { - if (efa->f & SELECT) { - DO_MINMAX(efa->v1->co, min, max); - DO_MINMAX(efa->v2->co, min, max); - DO_MINMAX(efa->v3->co, min, max); - if(efa->v4) DO_MINMAX(efa->v4->co, min, max); - } - } - VecMidf(result, min, max); - break; - case V3D_CURSOR: /*cursor center*/ - cursx= give_cursor(scene, v3d); - /* 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], RegionView3D *rv3d, 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, rv3d->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(ARegion *ar, View3D *v3d, float *target, float *shift, float rotmat[][4], int projectionmode, float *source, float *min, float *max) -{ - RegionView3D *rv3d= ar->regiondata; - 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= ar->winx; - dy= ar->winy; - - VecCopyf(pv4, source); - pv4[3] = 1.0; - - /* rotmat is the object matrix in this case */ - Mat4MulVec4fl(rotmat, pv4); - - /* almost project_short */ - Mat4MulVec4fl(rv3d->persmat, pv4); - if (fabs(pv4[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]; - } - - /* v3d->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]); - } -} - -static void correct_uv_aspect( EditMesh *em ) -{ - float aspx=1, aspy=1; - EditFace *efa = EM_get_actFace(em, 1); - MTFace *tface; - - if (efa) { - tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); -// XXX image_final_aspect(tface->tpage, &aspx, &aspy); - } - - if (aspx != aspy) { - - float scale; - - if (aspx > aspy) { - scale = aspy/aspx; - for (efa= em->faces.first; efa; efa= efa->next) { - if (efa->f & SELECT) { - tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - tface->uv[0][0] = ((tface->uv[0][0]-0.5)*scale)+0.5; - tface->uv[1][0] = ((tface->uv[1][0]-0.5)*scale)+0.5; - tface->uv[2][0] = ((tface->uv[2][0]-0.5)*scale)+0.5; - if(efa->v4) { - tface->uv[3][0] = ((tface->uv[3][0]-0.5)*scale)+0.5; - } - } - } - } else { - scale = aspx/aspy; - for (efa= em->faces.first; efa; efa= efa->next) { - if (efa->f & SELECT) { - tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - tface->uv[0][1] = ((tface->uv[0][1]-0.5)*scale)+0.5; - tface->uv[1][1] = ((tface->uv[1][1]-0.5)*scale)+0.5; - tface->uv[2][1] = ((tface->uv[2][1]-0.5)*scale)+0.5; - if(efa->v4) { - tface->uv[3][1] = ((tface->uv[3][1]-0.5)*scale)+0.5; - } - } - } - } - } -} - -static void default_uv(float uv[][2], float size) -{ - int dy; - - if(size>1.0) size= 1.0; - - dy= 1.0-size; - - uv[0][0]= 0; - uv[0][1]= size+dy; - - uv[1][0]= 0; - uv[1][1]= dy; - - uv[2][0]= size; - uv[2][1]= dy; - - uv[3][0]= size; - uv[3][1]= size+dy; -} - -static void calculate_uv_map(Scene *scene, ARegion *ar, View3D *v3d, EditMesh *em, unsigned short mapmode) -{ - RegionView3D *rv3d= ar->regiondata; - MTFace *tface; - Object *ob; - EditFace *efa; - 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, n; - - if(scene->toolsettings->uvcalc_mapdir==1) { - upangledeg= 90.0; - sideangledeg= 0.0; - } else { - upangledeg= 0.0; - if(scene->toolsettings->uvcalc_mapalign==1) sideangledeg= 0.0; - else sideangledeg= 90.0; - } - - /* add uvs if there not here */ - if (!EM_texFaceCheck(em)) { - if (em && em->faces.first) - EM_add_data_layer(em, &em->fdata, CD_MTFACE); - -// XXX if (G.sima && G.sima->image) /* this is a bit of a kludge, but assume they want the image on their mesh when UVs are added */ -// image_changed(G.sima, G.sima->image); - - if (!EM_texFaceCheck(em)) - return; - - /* select new UV's */ -// XX if ((G.sima && G.sima->flag & SI_SYNC_UVSEL)==0) { -// for(efa=em->faces.first; efa; efa=efa->next) { -// MTFace *tf= (MTFace *)CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); -// simaFaceSel_Set(efa, tf); -// } - - } - - ob=OBACT; - - switch(mapmode) { - case B_UVAUTO_BOUNDS: - min[0]= min[1]= 10000000.0; - max[0]= max[1]= -10000000.0; - - cent[0] = cent[1] = cent[2] = 0.0; - uv_calc_map_matrix(rotatematrix, rv3d, ob, upangledeg, sideangledeg, 1.0f); - - for (efa= em->faces.first; efa; efa= efa->next) { - if (efa->f & SELECT) { - tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - uv_calc_shift_project(ar, v3d, tface->uv[0],cent,rotatematrix,3, efa->v1->co, min,max); - uv_calc_shift_project(ar, v3d, tface->uv[1],cent,rotatematrix,3, efa->v2->co, min,max); - uv_calc_shift_project(ar, v3d, tface->uv[2],cent,rotatematrix,3, efa->v3->co,min,max); - if(efa->v4) - uv_calc_shift_project(ar, v3d, tface->uv[3],cent,rotatematrix,3, efa->v4->co,min,max); - } - } - - /* rescale UV to be in 1/1 */ - dx= (max[0]-min[0]); - dy= (max[1]-min[1]); - - for (efa= em->faces.first; efa; efa= efa->next) { - if (efa->f & SELECT) { - tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - if(efa->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); - for (efa= em->faces.first; efa; efa= efa->next) { - if (efa->f & SELECT) { - tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - uv_calc_shift_project(ar, v3d, tface->uv[0],cent,rotatematrix,4, efa->v1->co, NULL,NULL); - uv_calc_shift_project(ar, v3d, tface->uv[1],cent,rotatematrix,4, efa->v2->co, NULL,NULL); - uv_calc_shift_project(ar, v3d, tface->uv[2],cent,rotatematrix,4, efa->v3->co, NULL,NULL); - if(efa->v4) - uv_calc_shift_project(ar, v3d, tface->uv[3],cent,rotatematrix,4, efa->v4->co, NULL,NULL); - } - } - break; - - case B_UVAUTO_RESET: - for (efa= em->faces.first; efa; efa= efa->next) { - if (efa->f & SELECT) { - tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - default_uv(tface->uv, 1.0); - } - } - break; - - case B_UVAUTO_CYLINDER: - case B_UVAUTO_SPHERE: - uv_calc_center_vector(scene, v3d, cent, ob, em); - - if(mapmode==B_UVAUTO_CYLINDER) radius = scene->toolsettings->uvcalc_radius; - - /* be compatible to the "old" sphere/cylinder mode */ - if (scene->toolsettings->uvcalc_mapdir== 2) - Mat4One(rotatematrix); - else - uv_calc_map_matrix(rotatematrix, rv3d, ob, upangledeg,sideangledeg,radius); - for (efa= em->faces.first; efa; efa= efa->next) { - if (efa->f & SELECT) { - tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - uv_calc_shift_project(ar, v3d, tface->uv[0],cent,rotatematrix,mapmode, efa->v1->co, NULL,NULL); - uv_calc_shift_project(ar, v3d, tface->uv[1],cent,rotatematrix,mapmode, efa->v2->co, NULL,NULL); - uv_calc_shift_project(ar, v3d, tface->uv[2],cent,rotatematrix,mapmode, efa->v3->co, NULL,NULL); - n = 3; - if(efa->v4) { - uv_calc_shift_project(ar, v3d, tface->uv[3],cent,rotatematrix,mapmode, efa->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;*/ - float cubesize = scene->toolsettings->uvcalc_cubesize; - - for (efa= em->faces.first; efa; efa= efa->next) { - if (efa->f & SELECT) { - tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - CalcNormFloat(efa->v1->co, efa->v2->co, efa->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*cubesize*(loc[cox] + efa->v1->co[cox]); - tface->uv[0][1]= 0.5+0.5*cubesize*(loc[coy] + efa->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*cubesize*(loc[cox] + efa->v2->co[cox]); - tface->uv[1][1]= 0.5+0.5*cubesize*(loc[coy] + efa->v2->co[coy]); - tface->uv[1][0] -= dx; - tface->uv[1][1] -= dy; - tface->uv[2][0]= 0.5+0.5*cubesize*(loc[cox] + efa->v3->co[cox]); - tface->uv[2][1]= 0.5+0.5*cubesize*(loc[coy] + efa->v3->co[coy]); - tface->uv[2][0] -= dx; - tface->uv[2][1] -= dy; - if(efa->v4) { - tface->uv[3][0]= 0.5+0.5*cubesize*(loc[cox] + efa->v4->co[cox]); - tface->uv[3][1]= 0.5+0.5*cubesize*(loc[coy] + efa->v4->co[coy]); - tface->uv[3][0] -= dx; - tface->uv[3][1] -= dy; - } - } - } - break; - } - default: - if ((scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT)==0) - correct_uv_aspect(em); - return; - } /* end switch mapmode */ - - /* clipping and wrapping */ - if(0) { // XXX (make it uv layer property!) G.sima && G.sima->flag & SI_CLIP_UV) { - for (efa= em->faces.first; efa; efa= efa->next) { - if (!(efa->f & SELECT)) continue; - tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - - dx= dy= 0; - if(efa->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(efa->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); - } - } - } - - if ( (mapmode!=B_UVAUTO_BOUNDS) && - (mapmode!=B_UVAUTO_RESET) && - (scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT)==0 - ) { - correct_uv_aspect(em); - } - -// XXX notifier object_uvs_changed(OBACT); - -} - /* last_sel, use em->act_face otherwise get the last selected face in the editselections * at the moment, last_sel is mainly useful for gaking sure the space image dosnt flicker */ MTFace *EM_get_active_mtface(EditMesh *em, EditFace **act_efa, MCol **mcol, int sloppy) @@ -1211,73 +734,6 @@ void face_borderselect(Scene *scene, ARegion *ar) #endif } -void uv_autocalc_tface(Scene *scene, ARegion *ar, View3D *v3d, EditMesh *em) -{ - short mode; -#ifndef DISABLE_PYTHON -// short i=0, has_pymenu=0; /* pymenu must be bigger then UV_*_MAPPING */ -// XXX BPyMenu *pym; -// char menu_number[3]; -#endif - - /* uvmenu, will add python items */ - char uvmenu[4096]=MENUTITLE("UV Calculation") - MENUSTRING("Unwrap", UV_UNWRAP_MAPPING) "|%l|" - - MENUSTRING("Cube Projection", UV_CUBE_MAPPING) "|" - MENUSTRING("Cylinder from View", UV_CYL_MAPPING) "|" - MENUSTRING("Sphere from View", UV_SPHERE_MAPPING) "|%l|" - - MENUSTRING("Project From View", UV_WINDOW_MAPPING) "|" - MENUSTRING("Project from View (Bounds)",UV_BOUNDS_MAPPING) "|%l|" - - MENUSTRING("Reset", UV_RESET_MAPPING); -#ifndef DISABLE_PYTHON -#if 0 - XXX - /* note that we account for the 10 previous entries with i+10: */ - for (pym = BPyMenuTable[PYMENU_UVCALCULATION]; pym; pym = pym->next, i++) { - - if (!has_pymenu) { - strcat(uvmenu, "|%l"); - has_pymenu = 1; - } - - strcat(uvmenu, "|"); - strcat(uvmenu, pym->name); - strcat(uvmenu, " %x"); - sprintf(menu_number, "%d", i+10); - strcat(uvmenu, menu_number); - } -#endif -#endif - - mode= pupmenu(uvmenu); -#ifndef DISABLE_PYTHON -// if (mode >= 10) { -// BPY_menu_do_python(PYMENU_UVCALCULATION, mode - 10); -// return; -// } -#endif - switch(mode) { - case UV_CUBE_MAPPING: - calculate_uv_map(scene, ar, v3d, em, B_UVAUTO_CUBE); break; - case UV_CYL_MAPPING: - calculate_uv_map(scene, ar, v3d, em, B_UVAUTO_CYLINDER); break; - case UV_SPHERE_MAPPING: - calculate_uv_map(scene, ar, v3d, em, B_UVAUTO_SPHERE); break; - case UV_BOUNDS_MAPPING: - calculate_uv_map(scene, ar, v3d, em, B_UVAUTO_BOUNDS); break; - case UV_RESET_MAPPING: - calculate_uv_map(scene, ar, v3d, em, B_UVAUTO_RESET); break; - case UV_WINDOW_MAPPING: - calculate_uv_map(scene, ar, v3d, em, B_UVAUTO_WINDOW); break; - case UV_UNWRAP_MAPPING: -// XXX unwrap_lscm(0); - break; - } -} - /* Texture Paint */ void set_texturepaint(Scene *scene) /* toggle */ |