diff options
22 files changed, 1350 insertions, 1119 deletions
diff --git a/source/blender/editors/include/ED_image.h b/source/blender/editors/include/ED_image.h index 84225d85877..f015001c0d5 100644 --- a/source/blender/editors/include/ED_image.h +++ b/source/blender/editors/include/ED_image.h @@ -33,9 +33,23 @@ struct bContext; /* space_image.c, exported for transform */ struct Image *ED_space_image(struct SpaceImage *sima); +void ED_space_image_set(struct SpaceImage *sima, struct Scene *scene, struct Object *obedit, struct Image *ima); + +struct ImBuf *ED_space_image_buffer(struct SpaceImage *sima); void ED_space_image_size(struct SpaceImage *sima, int *width, int *height); +void ED_space_image_aspect(struct SpaceImage *sima, float *aspx, float *aspy); +void ED_space_image_zoom(struct SpaceImage *sima, struct ARegion *ar, float *zoomx, float *zoomy); void ED_space_image_uv_aspect(struct SpaceImage *sima, float *aspx, float *aspy); +void ED_image_size(struct Image *ima, int *width, int *height); +void ED_image_aspect(struct Image *ima, float *aspx, float *aspy); +void ED_image_uv_aspect(struct Image *ima, float *aspx, float *aspy); + +int ED_space_image_show_render(struct SpaceImage *sima); +int ED_space_image_show_paint(struct SpaceImage *sima); +int ED_space_image_show_uvedit(struct SpaceImage *sima, struct Object *obedit); +int ED_space_image_show_uvshadow(struct SpaceImage *sima, struct Object *obedit); + /* image_render.c, export for screen_ops.c, render operator */ void ED_space_image_output(struct bContext *C); diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index bd997e93e9b..e32243fc28f 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -119,6 +119,7 @@ void EM_deselect_flush(struct EditMesh *em); void EM_selectmode_set(struct EditMesh *em); void EM_select_flush(struct EditMesh *em); void EM_convertsel(struct EditMesh *em, short oldmode, short selectmode); +void EM_validate_selections(struct EditMesh *em); /* exported to transform */ int EM_get_actSelection(struct EditMesh *em, struct EditSelection *ese); @@ -139,6 +140,9 @@ void EM_free_backbuf(void); int EM_init_backbuf_border(struct ViewContext *vc, short xmin, short ymin, short xmax, short ymax); int EM_init_backbuf_circle(struct ViewContext *vc, short xs, short ys, short rads); +void EM_hide_mesh(struct EditMesh *em, int swap); +void EM_reveal_mesh(struct EditMesh *em); + /* editface.c */ struct MTFace *EM_get_active_mtface(struct EditMesh *em, struct EditFace **act_efa, struct MCol **mcol, int sloppy); diff --git a/source/blender/editors/include/ED_uvedit.h b/source/blender/editors/include/ED_uvedit.h index fa106ff4360..74a9be75db6 100644 --- a/source/blender/editors/include/ED_uvedit.h +++ b/source/blender/editors/include/ED_uvedit.h @@ -28,6 +28,7 @@ #ifndef ED_UVEDIT_H #define ED_UVEDIT_H +struct bContext; struct Scene; struct Object; struct MTFace; @@ -40,7 +41,7 @@ void ED_operatortypes_uvedit(void); void ED_keymap_uvedit(struct wmWindowManager *wm); void ED_uvedit_assign_image(struct Scene *scene, struct Object *obedit, struct Image *ima, struct Image *previma); -void ED_uvedit_set_tile(struct Scene *scene, struct Object *obedit, struct Image *ima, int curtile, int dotile); +void ED_uvedit_set_tile(struct bContext *C, struct Scene *scene, struct Object *obedit, struct Image *ima, int curtile, int dotile); int ED_uvedit_minmax(struct Scene *scene, struct Image *ima, struct Object *obedit, float *min, float *max); int ED_uvedit_test_silent(struct Object *obedit); diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index f5f5a98129d..696fde4b512 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -240,7 +240,9 @@ ARegion *ui_add_temporary_region(bScreen *sc) void ui_remove_temporary_region(bContext *C, bScreen *sc, ARegion *ar) { - wm_draw_region_clear(CTX_wm_window(C), ar); + if(CTX_wm_window(C)) + wm_draw_region_clear(CTX_wm_window(C), ar); + ED_region_exit(C, ar); BKE_area_region_free(NULL, ar); /* NULL: no spacetype */ BLI_freelinkN(&sc->regionbase, ar); @@ -1938,7 +1940,7 @@ uiPopupBlockHandle *ui_popup_menu_create(bContext *C, ARegion *butregion, uiBut uiMenuInfo info; head= MEM_callocN(sizeof(uiMenuItem), "menu dummy"); - head->opcontext= WM_OP_EXEC_REGION_WIN; + head->opcontext= WM_OP_INVOKE_REGION_WIN; menu_func(C, head, arg); 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 */ diff --git a/source/blender/editors/mesh/editmesh_lib.c b/source/blender/editors/mesh/editmesh_lib.c index 0ee4d2f8274..738cdd7a77f 100644 --- a/source/blender/editors/mesh/editmesh_lib.c +++ b/source/blender/editors/mesh/editmesh_lib.c @@ -219,6 +219,7 @@ void EM_validate_selections(EditMesh *em) EditSelection *ese, *nextese; ese = em->selected.first; + while(ese){ nextese = ese->next; if(ese->type == EDITVERT && !(((EditVert*)ese->data)->f & SELECT)) BLI_freelinkN(&(em->selected), ese); diff --git a/source/blender/editors/mesh/editmesh_mods.c b/source/blender/editors/mesh/editmesh_mods.c index 77fa456a76c..bd878946bb9 100644 --- a/source/blender/editors/mesh/editmesh_mods.c +++ b/source/blender/editors/mesh/editmesh_mods.c @@ -2533,9 +2533,8 @@ void MESH_OT_select_linked(wmOperatorType *ot) /* ************************* */ - /* swap is 0 or 1, if 1 it hides not selected */ -static void hide_mesh(EditMesh *em, int swap) +void EM_hide_mesh(EditMesh *em, int swap) { EditVert *eve; EditEdge *eed; @@ -2642,7 +2641,7 @@ static int hide_mesh_exec(bContext *C, wmOperator *op) Object *obedit= CTX_data_edit_object(C); EditMesh *em= ((Mesh *)obedit->data)->edit_mesh; - hide_mesh(em, RNA_boolean_get(op->ptr, "invert")); + EM_hide_mesh(em, RNA_boolean_get(op->ptr, "invert")); WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); return OPERATOR_FINISHED; @@ -2665,7 +2664,7 @@ void MESH_OT_hide(wmOperatorType *ot) RNA_def_boolean(ot->srna, "invert", 0, "Invert", ""); } -void reveal_mesh(EditMesh *em) +void EM_reveal_mesh(EditMesh *em) { EditVert *eve; EditEdge *eed; @@ -2706,8 +2705,8 @@ static int reveal_mesh_exec(bContext *C, wmOperator *op) Object *obedit= CTX_data_edit_object(C); EditMesh *em= ((Mesh *)obedit->data)->edit_mesh; - reveal_mesh(em); - + EM_reveal_mesh(em); + WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); return OPERATOR_FINISHED; } @@ -2726,228 +2725,6 @@ void MESH_OT_reveal(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } -void hide_tface_uv(EditMesh *em, int swap) -{ -#if 0 - /* no space image here */ - EditFace *efa; - MTFace *tface; - - if( is_uv_tface_editing_allowed()==0 ) return; - - /* call the mesh function if we are in mesh sync sel */ - if (G.sima->flag & SI_SYNC_UVSEL) { - hide_mesh(swap); - return; - } - - if(swap) { - for (efa= em->faces.first; efa; efa= efa->next) { - if(efa->f & SELECT) { - tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - if (G.sima->flag & SI_SELACTFACE) { - /* Pretend face mode */ - if (( (efa->v4==NULL && - ( tface->flag & (TF_SEL1|TF_SEL2|TF_SEL3)) == (TF_SEL1|TF_SEL2|TF_SEL3) ) || - ( tface->flag & (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4)) == (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4) ) == 0) { - - if (em->selectmode == SCE_SELECT_FACE) { - efa->f &= ~SELECT; - /* must re-select after */ - efa->e1->f &= ~SELECT; - efa->e2->f &= ~SELECT; - efa->e3->f &= ~SELECT; - if(efa->e4) efa->e4->f &= ~SELECT; - } else { - EM_select_face(efa, 0); - } - } - tface->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4); - } else if (em->selectmode == SCE_SELECT_FACE) { - if((tface->flag & (TF_SEL1|TF_SEL2|TF_SEL3))==0) { - if(!efa->v4) - EM_select_face(efa, 0); - else if(!(tface->flag & TF_SEL4)) - EM_select_face(efa, 0); - tface->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4); - } - } else { - /* EM_deselect_flush will deselect the face */ - if((tface->flag & TF_SEL1)==0) efa->v1->f &= ~SELECT; - if((tface->flag & TF_SEL2)==0) efa->v2->f &= ~SELECT; - if((tface->flag & TF_SEL3)==0) efa->v3->f &= ~SELECT; - if((efa->v4) && (tface->flag & TF_SEL4)==0) efa->v4->f &= ~SELECT; - tface->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4); - } - } - } - } else { - for (efa= em->faces.first; efa; efa= efa->next) { - if(efa->f & SELECT) { - tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - if (G.sima->flag & SI_SELACTFACE) { - if ( (efa->v4==NULL && - ( tface->flag & (TF_SEL1|TF_SEL2|TF_SEL3)) == (TF_SEL1|TF_SEL2|TF_SEL3) ) || - ( tface->flag & (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4)) == (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4) ) { - - if (em->selectmode == SCE_SELECT_FACE) { - efa->f &= ~SELECT; - /* must re-select after */ - efa->e1->f &= ~SELECT; - efa->e2->f &= ~SELECT; - efa->e3->f &= ~SELECT; - if(efa->e4) efa->e4->f &= ~SELECT; - } else { - EM_select_face(efa, 0); - } - } - tface->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4); - } else if (em->selectmode == SCE_SELECT_FACE) { - if(tface->flag & (TF_SEL1|TF_SEL2|TF_SEL3)) - EM_select_face(efa, 0); - else if(efa->v4 && tface->flag & TF_SEL4) - EM_select_face(efa, 0); - tface->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4); - } else { - /* EM_deselect_flush will deselect the face */ - if(tface->flag & TF_SEL1) efa->v1->f &= ~SELECT; - if(tface->flag & TF_SEL2) efa->v2->f &= ~SELECT; - if(tface->flag & TF_SEL3) efa->v3->f &= ~SELECT; - if((efa->v4) && tface->flag & TF_SEL4) efa->v4->f &= ~SELECT; - tface->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4); - } - } - } - } - - - /*deselects too many but ok for now*/ - if(em->selectmode & (SCE_SELECT_EDGE|SCE_SELECT_VERTEX)) { - EM_deselect_flush(em); - } - - if (em->selectmode==SCE_SELECT_FACE) { - /* de-selected all edges from faces that were de-selected. - * now make sure all faces that are selected also have selected edges */ - for (efa= em->faces.first; efa; efa= efa->next) { - if (efa->f & SELECT) { - EM_select_face(efa, 1); - } - } - } - - EM_validate_selections(); - -// XXX object_tface_flags_changed(OBACT, 0); -#endif -} - -void reveal_tface_uv(EditMesh *em) -{ -#if 0 - /* function should move away? */ - EditFace *efa; - MTFace *tface; - - if( is_uv_tface_editing_allowed()==0 ) return; - - /* call the mesh function if we are in mesh sync sel */ - if (G.sima->flag & SI_SYNC_UVSEL) { - reveal_mesh(); - return; - } - - if (G.sima->flag & SI_SELACTFACE) { - if (em->selectmode == SCE_SELECT_FACE) { - for (efa= em->faces.first; efa; efa= efa->next) { - if (!(efa->h) && !(efa->f & SELECT)) { - tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - EM_select_face(efa, 1); - tface->flag |= TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4; - } - } - } else { - /* enable adjacent faces to have disconnected UV selections if sticky is disabled */ - if (G.sima->sticky == SI_STICKY_DISABLE) { - for (efa= em->faces.first; efa; efa= efa->next) { - if (!(efa->h) && !(efa->f & SELECT)) { - /* All verts must be unselected for the face to be selected in the UV view */ - if ((efa->v1->f&SELECT)==0 && (efa->v2->f&SELECT)==0 && (efa->v3->f&SELECT)==0 && (efa->v4==0 || (efa->v4->f&SELECT)==0)) { - tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - tface->flag |= TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4; - /* Cant use EM_select_face here because it unselects the verts - * and we cant tell if the face was totally unselected or not */ - /*EM_select_face(efa, 1); - * - * See Loop with EM_select_face() below... */ - efa->f |= SELECT; - } - } - } - } else { - for (efa= em->faces.first; efa; efa= efa->next) { - if (!(efa->h) && !(efa->f & SELECT)) { - tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - if ((efa->v1->f & SELECT)==0) {tface->flag |= TF_SEL1;} - if ((efa->v2->f & SELECT)==0) {tface->flag |= TF_SEL2;} - if ((efa->v3->f & SELECT)==0) {tface->flag |= TF_SEL3;} - if ((efa->v4 && (efa->v4->f & SELECT)==0)) {tface->flag |= TF_SEL4;} - efa->f |= SELECT; - } - } - } - - /* Select all edges and verts now */ - for (efa= em->faces.first; efa; efa= efa->next) { - /* we only selected the face flags, and didnt changes edges or verts, fix this now */ - if (!(efa->h) && (efa->f & SELECT)) { - EM_select_face(efa, 1); - } - } - EM_select_flush(em); - } - } else if (em->selectmode == SCE_SELECT_FACE) { - for (efa= em->faces.first; efa; efa= efa->next) { - if (!(efa->h) && !(efa->f & SELECT)) { - tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - efa->f |= SELECT; - tface->flag |= TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4; - } - } - - /* Select all edges and verts now */ - for (efa= em->faces.first; efa; efa= efa->next) { - /* we only selected the face flags, and didnt changes edges or verts, fix this now */ - if (!(efa->h) && (efa->f & SELECT)) { - EM_select_face(efa, 1); - } - } - - } else { - for (efa= em->faces.first; efa; efa= efa->next) { - if (!(efa->h) && !(efa->f & SELECT)) { - tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - if ((efa->v1->f & SELECT)==0) {tface->flag |= TF_SEL1;} - if ((efa->v2->f & SELECT)==0) {tface->flag |= TF_SEL2;} - if ((efa->v3->f & SELECT)==0) {tface->flag |= TF_SEL3;} - if ((efa->v4 && (efa->v4->f & SELECT)==0)) {tface->flag |= TF_SEL4;} - efa->f |= SELECT; - } - } - - /* Select all edges and verts now */ - for (efa= em->faces.first; efa; efa= efa->next) { - /* we only selected the face flags, and didnt changes edges or verts, fix this now */ - if (!(efa->h) && (efa->f & SELECT)) { - EM_select_face(efa, 1); - } - } - } - -// XXX object_tface_flags_changed(OBACT, 0); -#endif -} - void select_faces_by_numverts(EditMesh *em, int numverts) { EditFace *efa; diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h index 89dc8942a2a..0e54e10793c 100644 --- a/source/blender/editors/mesh/mesh_intern.h +++ b/source/blender/editors/mesh/mesh_intern.h @@ -43,30 +43,6 @@ int edgetag_context_check(Scene *scene, EditEdge *eed); void edgetag_context_set(Scene *scene, EditEdge *eed, int val); int edgetag_shortest_path(Scene *scene, EditMesh *em, EditEdge *source, EditEdge *target); -/* ******************* meshtools.c */ - - -/* XXX move to uv editor? */ -enum { - B_UVAUTO_REDRAW = 3301, - B_UVAUTO_SPHERE, - B_UVAUTO_CYLINDER, - B_UVAUTO_CYLRADIUS, - B_UVAUTO_WINDOW, - B_UVAUTO_CUBE, - B_UVAUTO_CUBESIZE, - B_UVAUTO_RESET, - B_UVAUTO_BOUNDS, - B_UVAUTO_TOP, - B_UVAUTO_FACE, - B_UVAUTO_OBJECT, - B_UVAUTO_ALIGNX, - B_UVAUTO_ALIGNY, - B_UVAUTO_UNWRAP, - B_UVAUTO_DRAWFACES -}; - - /* ******************* editmesh.c */ extern void free_editvert(EditMesh *em, EditVert *eve); diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index f119c347915..fe50c1ec27a 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -285,7 +285,7 @@ void ED_keymap_mesh(wmWindowManager *wm) WM_keymap_add_item(keymap, "MESH_OT_knife_cut", LEFTMOUSE, KM_PRESS, KM_ALT|KM_CTRL, 0); - - + /* UV's */ + WM_keymap_add_item(keymap, "UV_OT_mapping_menu", UKEY, KM_PRESS, 0, 0); } diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c index 70a05d52376..42c91d7ea1b 100644 --- a/source/blender/editors/space_image/image_draw.c +++ b/source/blender/editors/space_image/image_draw.c @@ -52,6 +52,7 @@ #include "BIF_gl.h" #include "BIF_glutil.h" +#include "ED_image.h" #include "ED_screen.h" #include "UI_resources.h" @@ -663,16 +664,16 @@ void draw_image_main(SpaceImage *sima, ARegion *ar, Scene *scene) } } /* and we check for spare */ - ibuf= get_space_image_buffer(sima); + ibuf= ED_space_image_buffer(sima); } #endif /* put scene context variable in iuser */ sima->iuser.scene= scene; /* retrieve the image and information about it */ - ima= get_space_image(sima); - ibuf= get_space_image_buffer(sima); - get_space_image_zoom(sima, ar, &zoomx, &zoomy); + ima= ED_space_image(sima); + ibuf= ED_space_image_buffer(sima); + ED_space_image_zoom(sima, ar, &zoomx, &zoomy); show_viewer= (ima && ima->source == IMA_SRC_VIEWER); show_render= (show_viewer && ima->type == IMA_TYPE_R_RESULT); diff --git a/source/blender/editors/space_image/image_header.c b/source/blender/editors/space_image/image_header.c index 7f9171e87b3..3a1b623c09e 100644 --- a/source/blender/editors/space_image/image_header.c +++ b/source/blender/editors/space_image/image_header.c @@ -51,6 +51,7 @@ #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" +#include "ED_image.h" #include "ED_mesh.h" #include "ED_screen.h" #include "ED_types.h" @@ -61,6 +62,7 @@ #include "BIF_gl.h" #include "BIF_glutil.h" +#include "BIF_transform.h" #include "UI_interface.h" #include "UI_resources.h" @@ -132,9 +134,9 @@ static void image_viewmenu(bContext *C, uiMenuItem *head, void *arg_unused) RNA_pointer_create(&sc->id, &RNA_SpaceImageEditor, sima, &spaceptr); RNA_pointer_create(&sc->id, &RNA_SpaceUVEditor, sima, &uvptr); - show_render= get_space_image_show_render(sima); - show_paint= get_space_image_show_paint(sima); - show_uvedit= get_space_image_show_uvedit(sima, CTX_data_edit_object(C)); + show_render= ED_space_image_show_render(sima); + show_paint= ED_space_image_show_paint(sima); + show_uvedit= ED_space_image_show_uvedit(sima, CTX_data_edit_object(C)); /* create menu */ uiMenuItemO(head, ICON_MENU_PANEL, "IMAGE_OT_toggle_view_properties_panel"); // View Properties... @@ -251,10 +253,10 @@ static void image_imagemenu(bContext *C, uiMenuItem *head, void *arg_unused) int show_render; /* retrieve state */ - ima= get_space_image(sima); - ibuf= get_space_image_buffer(sima); + ima= ED_space_image(sima); + ibuf= ED_space_image_buffer(sima); - show_render= get_space_image_show_render(sima); + show_render= ED_space_image_show_render(sima); RNA_pointer_create(&sc->id, &RNA_SpaceImageEditor, sima, &spaceptr); @@ -306,56 +308,18 @@ static void image_imagemenu(bContext *C, uiMenuItem *head, void *arg_unused) #endif } -#if 0 -static void do_image_uvs_showhidemenu(void *arg, int event) -{ - switch(event) { - case 4: /* show hidden faces */ - reveal_tface_uv(); - break; - case 5: /* hide selected faces */ - hide_tface_uv(0); - break; - case 6: /* hide deselected faces */ - hide_tface_uv(1); - break; - } - allqueue(REDRAWVIEW3D, 0); -} -#endif - static void image_uvs_showhidemenu(bContext *C, uiMenuItem *head, void *arg_unused) { - uiMenuItemO(head, 0, "UV_OT_show_hidden_faces"); // Show Hidden Faces|Alt H - uiMenuItemO(head, 0, "UV_OT_hide_selected_faces"); // Hide Selected Faces|H - uiMenuItemO(head, 0, "UV_OT_hide_deselected_faces"); // Hide Deselected Faces|Shift H + uiMenuItemO(head, 0, "UV_OT_show_hidden"); + uiMenuItemO(head, 0, "UV_OT_hide_selected"); + uiMenuItemO(head, 0, "UV_OT_hide_deselected"); } -#if 0 -static void do_image_uvs_transformmenu(void *arg, int event) -{ - switch(event) { - case 0: /* Grab */ - initTransform(TFM_TRANSLATION, CTX_NONE); - Transform(); - break; - case 1: /* Rotate */ - initTransform(TFM_ROTATION, CTX_NONE); - Transform(); - break; - case 2: /* Scale */ - initTransform(TFM_RESIZE, CTX_NONE); - Transform(); - break; - } -} -#endif - static void image_uvs_transformmenu(bContext *C, uiMenuItem *head, void *arg_unused) { - uiMenuItemO(head, 0, "UV_OT_grab"); // Grab/Move|G - uiMenuItemO(head, 0, "UV_OT_rotate"); // Rotate|R - uiMenuItemO(head, 0, "UV_OT_scale"); // Scale|S + uiMenuItemEnumO(head, 0, "TFM_OT_transform", "mode", TFM_TRANSLATION); + uiMenuItemEnumO(head, 0, "TFM_OT_transform", "mode", TFM_ROTATION); + uiMenuItemEnumO(head, 0, "TFM_OT_transform", "mode", TFM_RESIZE); } static void image_uvs_mirrormenu(bContext *C, uiMenuItem *head, void *arg_unused) @@ -435,8 +399,8 @@ static void image_uvsmenu(bContext *C, uiMenuItem *head, void *arg_unused) ImBuf *ibuf; /* retrieve state */ - ima= get_space_image(sima); - ibuf= get_space_image_buffer(sima); + ima= ED_space_image(sima); + ibuf= ED_space_image_buffer(sima); RNA_pointer_create(&sc->id, &RNA_SpaceUVEditor, sima, &uvptr); RNA_id_pointer_create(&scene->id, &sceneptr); @@ -806,11 +770,14 @@ static void sima_idpoin_handle(bContext *C, ID *id, int event) switch(event) { case UI_ID_BROWSE: case UI_ID_DELETE: - set_space_image(sima, scene, obedit, sima->image); + ED_space_image_set(sima, scene, obedit, sima->image); if(sima->image && sima->image->id.us==0) sima->image->id.us= 1; + if(obedit) + WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); + ED_area_tag_redraw(CTX_wm_area(C)); ED_undo_push(C, "Assign Image UV"); break; @@ -844,12 +811,12 @@ void image_header_buttons(const bContext *C, ARegion *ar) int xco, yco= 3, show_uvedit, show_render, show_paint; /* retrieve state */ - ima= get_space_image(sima); - ibuf= get_space_image_buffer(sima); + ima= ED_space_image(sima); + ibuf= ED_space_image_buffer(sima); - show_render= get_space_image_show_render(sima); - show_paint= get_space_image_show_paint(sima); - show_uvedit= get_space_image_show_uvedit(sima, CTX_data_edit_object(C)); + show_render= ED_space_image_show_render(sima); + show_paint= ED_space_image_show_paint(sima); + show_uvedit= ED_space_image_show_uvedit(sima, CTX_data_edit_object(C)); RNA_pointer_create(&sc->id, &RNA_SpaceImageEditor, sima, &spaceptr); RNA_pointer_create(&sc->id, &RNA_SpaceUVEditor, sima, &uvptr); @@ -1076,7 +1043,7 @@ static int toolbox_invoke(bContext *C, wmOperator *op, wmEvent *event) uiMenuItem *head; int show_uvedit; - show_uvedit= get_space_image_show_uvedit(sima, obedit); + show_uvedit= ED_space_image_show_uvedit(sima, obedit); head= uiPupMenuBegin("Toolbox", 0); @@ -1101,4 +1068,3 @@ void IMAGE_OT_toolbox(wmOperatorType *ot) ot->poll= space_image_main_area_poll; } - diff --git a/source/blender/editors/space_image/image_intern.h b/source/blender/editors/space_image/image_intern.h index 3f61ec6207a..bbf0ed792c0 100644 --- a/source/blender/editors/space_image/image_intern.h +++ b/source/blender/editors/space_image/image_intern.h @@ -39,21 +39,6 @@ struct ImBuf; struct wmOperatorType; struct Scene; -/* space_image.c */ -struct Image *get_space_image(struct SpaceImage *sima); -void set_space_image(struct SpaceImage *sima, struct Scene *scene, struct Object *obedit, struct Image *ima); - -struct ImBuf *get_space_image_buffer(struct SpaceImage *sima); -void get_space_image_size(struct SpaceImage *sima, int *width, int *height); -void get_space_image_aspect(struct SpaceImage *sima, float *aspx, float *aspy); -void get_space_image_zoom(struct SpaceImage *sima, struct ARegion *ar, float *zoomx, float *zoomy); -void get_space_image_uv_aspect(struct SpaceImage *sima, float *aspx, float *aspy); - -int get_space_image_show_render(struct SpaceImage *sima); -int get_space_image_show_paint(struct SpaceImage *sima); -int get_space_image_show_uvedit(struct SpaceImage *sima, struct Object *obedit); -int get_space_image_show_uvshadow(struct SpaceImage *sima, struct Object *obedit); - /* image_header.c */ void image_header_buttons(const struct bContext *C, struct ARegion *ar); diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index e8f5b6956fd..afda954b074 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -61,6 +61,7 @@ #include "RNA_define.h" #include "RNA_types.h" +#include "ED_image.h" #include "ED_screen.h" #include "ED_uvedit.h" @@ -126,7 +127,7 @@ static void sima_zoom_set(SpaceImage *sima, ARegion *ar, float zoom) return; /* check zoom limits */ - get_space_image_size(sima, &width, &height); + ED_space_image_size(sima, &width, &height); width *= sima->zoom; height *= sima->zoom; @@ -413,10 +414,10 @@ static int view_all_exec(bContext *C, wmOperator *op) scene= (Scene*)CTX_data_scene(C); obedit= CTX_data_edit_object(C); - ima= get_space_image(sima); - ibuf= get_space_image_buffer(sima); - get_space_image_size(sima, &width, &height); - get_space_image_aspect(sima, &aspx, &aspy); + ima= ED_space_image(sima); + ibuf= ED_space_image_buffer(sima); + ED_space_image_size(sima, &width, &height); + ED_space_image_aspect(sima, &aspx, &aspy); w= width*aspx; h= height*aspy; @@ -474,9 +475,9 @@ static int view_selected_exec(bContext *C, wmOperator *op) scene= (Scene*)CTX_data_scene(C); obedit= CTX_data_edit_object(C); - ima= get_space_image(sima); - ibuf= get_space_image_buffer(sima); - get_space_image_size(sima, &width, &height); + ima= ED_space_image(sima); + ibuf= ED_space_image_buffer(sima); + ED_space_image_size(sima, &width, &height); /* get bounds */ if(!ED_uvedit_minmax(scene, ima, obedit, min, max)) @@ -621,7 +622,7 @@ static void load_image_filesel(SpaceImage *sima, Scene *scene, Object *obedit, c ima= BKE_add_image_file(str, scene->r.cfra); if(ima) { BKE_image_signal(ima, &sima->iuser, IMA_SIGNAL_RELOAD); - set_space_image(sima, scene, obedit, ima); + ED_space_image_set(sima, scene, obedit, ima); } // XXX BIF_undo_push("Load image UV"); // XXX allqueue(REDRAWIMAGE, 0); @@ -642,8 +643,8 @@ static void replace_image_filesel(SpaceImage *sima, char *str) /* called from f static void save_image_doit(SpaceImage *sima, Scene *scene, char *name) { - Image *ima= get_space_image(sima); - ImBuf *ibuf= get_space_image_buffer(sima); + Image *ima= ED_space_image(sima); + ImBuf *ibuf= ED_space_image_buffer(sima); int len; char str[FILE_MAXDIR+FILE_MAXFILE]; @@ -775,7 +776,7 @@ static char *filesel_imagetype_string(Image *ima) void save_as_image_sima(SpaceImage *sima, Scene *scene) { Image *ima = sima->image; - ImBuf *ibuf= get_space_image_buffer(sima); + ImBuf *ibuf= ED_space_image_buffer(sima); char name[FILE_MAXDIR+FILE_MAXFILE]; if (ima) { @@ -801,8 +802,8 @@ void save_as_image_sima(SpaceImage *sima, Scene *scene) /* if exists, saves over without fileselect */ void save_image_sima(SpaceImage *sima, Scene *scene) { - Image *ima = get_space_image(sima); - ImBuf *ibuf= get_space_image_buffer(sima); + Image *ima = ED_space_image(sima); + ImBuf *ibuf= ED_space_image_buffer(sima); char name[FILE_MAXDIR+FILE_MAXFILE]; if (ima) { @@ -880,7 +881,7 @@ void reload_image_sima(SpaceImage *sima) { if (sima ) { BKE_image_signal(sima->image, &sima->iuser, IMA_SIGNAL_RELOAD); - /* set_space_image(sima, scene, obedit, NULL); - do we really need this? */ + /* ED_space_image_set(sima, scene, obedit, NULL); - do we really need this? */ } // XXX allqueue(REDRAWIMAGE, 0); @@ -912,7 +913,7 @@ void new_image_sima(SpaceImage *sima, Scene *scene, Object *obedit) #endif ima = BKE_add_image_size(width, height, name, floatbuf, uvtestgrid, color); - set_space_image(sima, scene, obedit, ima); + ED_space_image_set(sima, scene, obedit, ima); BKE_image_signal(sima->image, &sima->iuser, IMA_SIGNAL_USER_NEW_IMAGE); // XXX BIF_undo_push("Add image"); @@ -937,7 +938,7 @@ void pack_image_sima(SpaceImage *sima) } } else { - ImBuf *ibuf= get_space_image_buffer(sima); + ImBuf *ibuf= ED_space_image_buffer(sima); if (ibuf && (ibuf->userflags & IB_BITMAPDIRTY)) { if(1) // XXX okee("Can't pack painted image. Use Repack as PNG?")) BKE_image_memorypack(ima); @@ -1045,7 +1046,7 @@ void image_final_aspect(Image *image, float *x, float *y) void sima_sample_color(SpaceImage *sima) { - ImBuf *ibuf= get_space_image_buffer(sima); + ImBuf *ibuf= ED_space_image_buffer(sima); float fx, fy; short mval[2], mvalo[2], firsttime=1; @@ -1143,7 +1144,7 @@ void mouseco_to_curtile(SpaceImage *sima, struct Object *obedit) short mval[2]; int show_uvedit; - show_uvedit= get_space_image_show_uvedit(sima, obedit); + show_uvedit= ED_space_image_show_uvedit(sima, obedit); if(!show_uvedit) return; if(sima->image && sima->image->tpageflag & IMA_TILES) { diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index 19ba040ea8c..4f40dff378b 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -181,7 +181,7 @@ static void image_refresh(const bContext *C, ScrArea *sa) Object *obedit= CTX_data_edit_object(C); Image *ima; - ima= get_space_image(sima); + ima= ED_space_image(sima); /* check if we have to set the image from the editmesh */ if(ima && (ima->source==IMA_SRC_VIEWER || sima->pin)); @@ -235,11 +235,11 @@ static int image_context(const bContext *C, bContextDataMember member, bContextD SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C); if(member == CTX_DATA_EDIT_IMAGE) { - CTX_data_pointer_set(result, get_space_image(sima)); + CTX_data_pointer_set(result, ED_space_image(sima)); return 1; } else if(member == CTX_DATA_EDIT_IMAGE_BUFFER) { - CTX_data_pointer_set(result, get_space_image_buffer(sima)); + CTX_data_pointer_set(result, ED_space_image_buffer(sima)); return 1; } @@ -251,7 +251,7 @@ static int image_context(const bContext *C, bContextDataMember member, bContextD /* sets up the fields of the View2D from zoom and offset */ static void image_main_area_set_view2d(SpaceImage *sima, ARegion *ar) { - Image *ima= get_space_image(sima); + Image *ima= ED_space_image(sima); float x1, y1, w, h; int width, height, winx, winy; @@ -274,7 +274,7 @@ static void image_main_area_set_view2d(SpaceImage *sima, ARegion *ar) } #endif - get_space_image_size(sima, &width, &height); + ED_space_image_size(sima, &width, &height); w= width; h= height; @@ -354,6 +354,7 @@ static void image_main_area_draw(const bContext *C, ARegion *ar) /* and uvs in 0.0-1.0 space */ UI_view2d_view_ortho(C, v2d); draw_uvedit_main(sima, ar, scene, obedit); + ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST); UI_view2d_view_restore(C); /* scrollers? */ @@ -472,13 +473,13 @@ void ED_spacetype_image(void) /**************************** common state *****************************/ -Image *get_space_image(SpaceImage *sima) +Image *ED_space_image(SpaceImage *sima) { return sima->image; } /* called to assign images to UV faces */ -void set_space_image(SpaceImage *sima, Scene *scene, Object *obedit, Image *ima) +void ED_space_image_set(SpaceImage *sima, Scene *scene, Object *obedit, Image *ima) { ED_uvedit_assign_image(scene, obedit, ima, sima->image); @@ -493,7 +494,7 @@ void set_space_image(SpaceImage *sima, Scene *scene, Object *obedit, Image *ima) BKE_image_signal(sima->image, &sima->iuser, IMA_SIGNAL_USER_NEW_IMAGE); } -ImBuf *get_space_image_buffer(SpaceImage *sima) +ImBuf *ED_space_image_buffer(SpaceImage *sima) { ImBuf *ibuf; @@ -512,30 +513,42 @@ ImBuf *get_space_image_buffer(SpaceImage *sima) return NULL; } -void get_space_image_size(SpaceImage *sima, int *width, int *height) +void ED_image_size(Image *ima, int *width, int *height) { ImBuf *ibuf; - ibuf= get_space_image_buffer(sima); + ibuf= (ima)? BKE_image_get_ibuf(ima, NULL): NULL; if(ibuf && ibuf->x > 0 && ibuf->y > 0) { *width= ibuf->x; *height= ibuf->y; } - /* I know a bit weak... but preview uses not actual image size */ - // XXX else if(image_preview_active(sima, width, height)); else { *width= 256; *height= 256; } } -void get_space_image_aspect(SpaceImage *sima, float *aspx, float *aspy) +void ED_space_image_size(SpaceImage *sima, int *width, int *height) { - Image *ima; + ImBuf *ibuf; - ima= get_space_image(sima); + ibuf= ED_space_image_buffer(sima); + + if(ibuf && ibuf->x > 0 && ibuf->y > 0) { + *width= ibuf->x; + *height= ibuf->y; + } + /* I know a bit weak... but preview uses not actual image size */ + // XXX else if(image_preview_active(sima, width, height)); + else { + *width= 256; + *height= 256; + } +} +void ED_image_aspect(Image *ima, float *aspx, float *aspy) +{ *aspx= *aspy= 1.0; if((ima == NULL) || (ima->type == IMA_TYPE_R_RESULT) || (ima->type == IMA_TYPE_COMPOSITE) || @@ -546,45 +559,61 @@ void get_space_image_aspect(SpaceImage *sima, float *aspx, float *aspy) *aspy = ima->aspy/ima->aspx; } -void get_space_image_zoom(SpaceImage *sima, ARegion *ar, float *zoomx, float *zoomy) +void ED_space_image_aspect(SpaceImage *sima, float *aspx, float *aspy) +{ + ED_image_aspect(ED_space_image(sima), aspx, aspy); +} + +void ED_space_image_zoom(SpaceImage *sima, ARegion *ar, float *zoomx, float *zoomy) { int width, height; - get_space_image_size(sima, &width, &height); + ED_space_image_size(sima, &width, &height); *zoomx= (float)(ar->winrct.xmax - ar->winrct.xmin)/(float)((ar->v2d.cur.xmax - ar->v2d.cur.xmin)*width); *zoomy= (float)(ar->winrct.ymax - ar->winrct.ymin)/(float)((ar->v2d.cur.ymax - ar->v2d.cur.ymin)*height); } -void get_space_image_uv_aspect(SpaceImage *sima, float *aspx, float *aspy) +void ED_space_image_uv_aspect(SpaceImage *sima, float *aspx, float *aspy) { int w, h; - get_space_image_aspect(sima, aspx, aspy); - get_space_image_size(sima, &w, &h); + ED_space_image_aspect(sima, aspx, aspy); + ED_space_image_size(sima, &w, &h); + + *aspx *= (float)w/256.0f; + *aspy *= (float)h/256.0f; +} + +void ED_image_uv_aspect(Image *ima, float *aspx, float *aspy) +{ + int w, h; + + ED_image_aspect(ima, aspx, aspy); + ED_image_size(ima, &w, &h); *aspx *= (float)w; *aspy *= (float)h; } -int get_space_image_show_render(SpaceImage *sima) +int ED_space_image_show_render(SpaceImage *sima) { return (sima->image && ELEM(sima->image->type, IMA_TYPE_R_RESULT, IMA_TYPE_COMPOSITE)); } -int get_space_image_show_paint(SpaceImage *sima) +int ED_space_image_show_paint(SpaceImage *sima) { - if(get_space_image_show_render(sima)) + if(ED_space_image_show_render(sima)) return 0; return (sima->flag & SI_DRAWTOOL); } -int get_space_image_show_uvedit(SpaceImage *sima, Object *obedit) +int ED_space_image_show_uvedit(SpaceImage *sima, Object *obedit) { - if(get_space_image_show_render(sima)) + if(ED_space_image_show_render(sima)) return 0; - if(get_space_image_show_paint(sima)) + if(ED_space_image_show_paint(sima)) return 0; if(obedit && obedit->type == OB_MESH) @@ -593,33 +622,15 @@ int get_space_image_show_uvedit(SpaceImage *sima, Object *obedit) return 0; } -int get_space_image_show_uvshadow(SpaceImage *sima, Object *obedit) +int ED_space_image_show_uvshadow(SpaceImage *sima, Object *obedit) { - if(get_space_image_show_render(sima)) + if(ED_space_image_show_render(sima)) return 0; - if(get_space_image_show_paint(sima)) + if(ED_space_image_show_paint(sima)) if(obedit && obedit->type == OB_MESH) return EM_texFaceCheck(((Mesh*)obedit->data)->edit_mesh); return 0; } -/* Exported Functions */ - -Image *ED_space_image(SpaceImage *sima) -{ - return get_space_image(sima); -} - -void ED_space_image_size(SpaceImage *sima, int *width, int *height) -{ - get_space_image_size(sima, width, height); -} - -void ED_space_image_uv_aspect(SpaceImage *sima, float *aspx, float *aspy) -{ - get_space_image_uv_aspect(sima, aspx, aspy); -} - - diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 37781f68179..8c7bb0463c2 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -980,6 +980,10 @@ void initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) t->draw_handle = ED_region_draw_cb_activate(t->ar->type, drawTransform, t, REGION_DRAW_POST); } + else if(t->spacetype == SPACE_IMAGE) { + Mat3One(t->spacemtx); + t->draw_handle = ED_region_draw_cb_activate(t->ar->type, drawTransform, t, REGION_DRAW_POST); + } else Mat3One(t->spacemtx); diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c index 58bfdc99d34..26d240be3fc 100644 --- a/source/blender/editors/transform/transform_constraints.c +++ b/source/blender/editors/transform/transform_constraints.c @@ -72,6 +72,7 @@ #include "BKE_global.h" #include "BKE_utildefines.h" +#include "ED_image.h" #include "ED_view3d.h" #include "BLI_arithb.h" @@ -681,7 +682,7 @@ void drawConstraint(TransInfo *t) { TransCon *tc = &(t->con); - if (t->spacetype!=SPACE_VIEW3D) + if (!ELEM(t->spacetype, SPACE_VIEW3D, SPACE_IMAGE)) return; if (!(tc->mode & CON_APPLY)) return; @@ -743,7 +744,7 @@ void drawPropCircle(TransInfo *t) UI_ThemeColor(TH_GRID); - if (t->spacetype == SPACE_VIEW3D) + if(t->spacetype == SPACE_VIEW3D) { RegionView3D *rv3d = t->ar->regiondata; @@ -756,21 +757,25 @@ void drawPropCircle(TransInfo *t) Mat4One(imat); } - - if(t->obedit) + glPushMatrix(); + + if((t->spacetype == SPACE_VIEW3D) && t->obedit) { - glPushMatrix(); glMultMatrixf(t->obedit->obmat); /* because t->center is in local space */ } + else if(t->spacetype == SPACE_IMAGE) + { + float aspx, aspy; + + ED_space_image_uv_aspect(t->sa->spacedata.first, &aspx, &aspy); + glScalef(1.0f/aspx, 1.0f/aspy, 1.0); + } set_inverted_drawing(1); drawcircball(GL_LINE_LOOP, t->center, t->propsize, imat); set_inverted_drawing(0); - if(t->obedit) - { - glPopMatrix(); - } + glPopMatrix(); } } diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 1e7c67c7cd3..49f0020420a 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -341,10 +341,11 @@ void transform_keymap_for_space(struct wmWindowManager *wm, struct ListBase *key km = WM_keymap_add_item(keymap, "TFM_OT_transform", SKEY, KM_PRESS, 0, 0); RNA_int_set(km->ptr, "mode", TFM_RESIZE); - km = WM_keymap_add_item(keymap, "TFM_OT_transform", SKEY, KM_PRESS, KM_ALT|KM_CTRL|KM_SHIFT, 0); - RNA_int_set(km->ptr, "mode", TFM_SHEAR); + km = WM_keymap_add_item(keymap, "TFM_OT_transform", MKEY, KM_PRESS, 0, 0); + RNA_int_set(km->ptr, "mode", TFM_MIRROR); break; default: break; } } + diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c index 5bffe6b1124..9686d4d6094 100644 --- a/source/blender/editors/uvedit/uvedit_draw.c +++ b/source/blender/editors/uvedit/uvedit_draw.c @@ -38,7 +38,6 @@ #include "BKE_customdata.h" #include "BKE_DerivedMesh.h" -#include "BKE_global.h" // XXX make edge and face drawing flags local #include "BKE_object.h" #include "BKE_utildefines.h" @@ -48,54 +47,21 @@ #include "BIF_gl.h" #include "BIF_glutil.h" +#include "ED_image.h" #include "ED_mesh.h" #include "UI_resources.h" -#include "../space_image/image_intern.h" #include "uvedit_intern.h" -/* XXX make this draw extra for transform operator */ -#if 0 -static void draw_image_transform(ImBuf *ibuf, float xuser_asp, float yuser_asp) -{ -#if 0 - if(G.moving) { - float aspx, aspy, center[3]; - - BIF_drawConstraint(); - - if(ibuf==0 || ibuf->rect==0 || ibuf->x==0 || ibuf->y==0) { - aspx= aspy= 1.0; - } - else { - aspx= (256.0/ibuf->x) * xuser_asp; - aspy= (256.0/ibuf->y) * yuser_asp; - } - BIF_getPropCenter(center); - - /* scale and translate the circle into place and draw it */ - glPushMatrix(); - glScalef(aspx, aspy, 1.0); - glTranslatef((1/aspx)*center[0] - center[0], - (1/aspy)*center[1] - center[1], 0.0); - - BIF_drawPropCircle(); - - glPopMatrix(); - } -#endif -} -#endif - static void drawcursor_sima(SpaceImage *sima, ARegion *ar) { View2D *v2d= &ar->v2d; float zoomx, zoomy, w, h; int width, height; - get_space_image_size(sima, &width, &height); - get_space_image_zoom(sima, ar, &zoomx, &zoomy); + ED_space_image_size(sima, &width, &height); + ED_space_image_zoom(sima, ar, &zoomx, &zoomy); w= zoomx*width/256.0f; h= zoomy*height/256.0f; @@ -191,9 +157,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, EditMesh *em, MTFac Image *ima= sima->image; float aspx, aspy, col[4], tf_uv[4][2]; - aspx= 1.0f; - aspy= 1.0f; - //XXX transform_aspect_ratio_tf_uv(&aspx, &aspy); + ED_space_image_uv_aspect(sima, &aspx, &aspy); switch(sima->dt_uvstretch) { case SI_UVDT_STRETCH_AREA: @@ -823,8 +787,8 @@ void draw_uvedit_main(SpaceImage *sima, ARegion *ar, Scene *scene, Object *obedi { int show_uvedit, show_uvshadow; - show_uvedit= get_space_image_show_uvedit(sima, obedit); - show_uvshadow= get_space_image_show_uvshadow(sima, obedit); + show_uvedit= ED_space_image_show_uvedit(sima, obedit); + show_uvshadow= ED_space_image_show_uvshadow(sima, obedit); if(show_uvedit || show_uvshadow) { /* this is basically the same object_handle_update as in the 3d view, @@ -840,9 +804,6 @@ void draw_uvedit_main(SpaceImage *sima, ARegion *ar, Scene *scene, Object *obedi if(show_uvedit) drawcursor_sima(sima, ar); - - // XXX becomes operator draw extra: - // draw_image_transform(ibuf, xuser_asp, yuser_asp); } } diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h index a66c9ea2fb8..cca357c8685 100644 --- a/source/blender/editors/uvedit/uvedit_intern.h +++ b/source/blender/editors/uvedit/uvedit_intern.h @@ -66,10 +66,16 @@ float uv_area(float uv[][2], int quad); void uv_copy_aspect(float uv_orig[][2], float uv[][2], float aspx, float aspy); /* operators */ +void UV_OT_average_islands_scale(struct wmOperatorType *ot); +void UV_OT_cube_project(struct wmOperatorType *ot); +void UV_OT_cylinder_project(struct wmOperatorType *ot); +void UV_OT_from_view(struct wmOperatorType *ot); +void UV_OT_mapping_menu(struct wmOperatorType *ot); +void UV_OT_minimize_stretch(struct wmOperatorType *ot); void UV_OT_pack_islands(struct wmOperatorType *ot); +void UV_OT_reset(struct wmOperatorType *ot); +void UV_OT_sphere_project(struct wmOperatorType *ot); void UV_OT_unwrap(struct wmOperatorType *ot); -void UV_OT_minimize_stretch(struct wmOperatorType *ot); -void UV_OT_average_islands_scale(struct wmOperatorType *ot); #endif /* ED_UVEDIT_INTERN_H */ diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 86f5c782ca3..4c27151acef 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -56,6 +56,7 @@ #include "BIF_transform.h" +#include "ED_image.h" #include "ED_mesh.h" #include "ED_screen.h" @@ -69,7 +70,6 @@ #include "UI_view2d.h" #include "uvedit_intern.h" -#include "../space_image/image_intern.h" /************************* state testing ************************/ @@ -99,7 +99,7 @@ void ED_uvedit_assign_image(Scene *scene, Object *obedit, Image *ima, Image *pre return; em= ((Mesh*)obedit->data)->edit_mesh; - if(!em || !em->faces.first); + if(!em || !em->faces.first) return; /* ensure we have a uv layer */ @@ -133,15 +133,13 @@ void ED_uvedit_assign_image(Scene *scene, Object *obedit, Image *ima, Image *pre } /* and update depdency graph */ - if(update) { + if(update) DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - /* XXX ensure undo, notifiers? */ - } } /* dotile - 1, set the tile flag (from the space image) * 2, set the tile index for the faces. */ -void ED_uvedit_set_tile(Scene *scene, Object *obedit, Image *ima, int curtile, int dotile) +void ED_uvedit_set_tile(bContext *C, Scene *scene, Object *obedit, Image *ima, int curtile, int dotile) { EditMesh *em; EditFace *efa; @@ -174,7 +172,7 @@ void ED_uvedit_set_tile(Scene *scene, Object *obedit, Image *ima, int curtile, i } DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - // XXX WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); } /*********************** space conversion *********************/ @@ -183,7 +181,7 @@ static void uvedit_pixel_to_float(SpaceImage *sima, float *dist, float pixeldist { int width, height; - get_space_image_size(sima, &width, &height); + ED_space_image_size(sima, &width, &height); dist[0]= pixeldist/width; dist[1]= pixeldist/height; @@ -2183,8 +2181,8 @@ int circle_select_exec(bContext *C, wmOperator *op) /* compute ellipse size and location, not a circle since we deal * with non square image. ellipse is normalized, r = 1.0. */ - get_space_image_size(sima, &width, &height); - get_space_image_zoom(sima, ar, &zoomx, &zoomy); + ED_space_image_size(sima, &width, &height); + ED_space_image_zoom(sima, ar, &zoomx, &zoomy); ellipse[0]= width*zoomx/radius; ellipse[1]= height*zoomy/radius; @@ -2243,7 +2241,7 @@ static void snap_cursor_to_pixels(SpaceImage *sima, View2D *v2d) { int width= 0, height= 0; - get_space_image_size(sima, &width, &height); + ED_space_image_size(sima, &width, &height); snap_uv_to_pixel(v2d->cursor, width, height); } @@ -2460,7 +2458,7 @@ static int snap_uvs_to_pixels(SpaceImage *sima, Scene *scene, Object *obedit) float w, h; short change = 0; - get_space_image_size(sima, &width, &height); + ED_space_image_size(sima, &width, &height); w = (float)width; h = (float)height; @@ -2515,7 +2513,7 @@ void UV_OT_snap_selection(wmOperatorType *ot) static EnumPropertyItem target_items[] = { {0, "PIXELS", "Pixels", ""}, {1, "CURSOR", "Cursor", ""}, - {2, "ADJACENT_UNSELECTED", "Adjacent Unselected", ""}, + {2, "ADJACENT_DESELECTED", "Adjacent Deselected", ""}, {0, NULL, NULL, NULL}}; /* identifiers */ @@ -2584,7 +2582,7 @@ void UV_OT_pin(wmOperatorType *ot) RNA_def_boolean(ot->srna, "clear", 0, "Clear", "Clear pinning for the selection instead of setting it."); } -/* ******************** select pinned operator **************** */ +/******************* select pinned operator ***************/ static int select_pinned_exec(bContext *C, wmOperator *op) { @@ -2625,6 +2623,280 @@ void UV_OT_select_pinned(wmOperatorType *ot) ot->poll= ED_operator_uvedit; } +/********************** hide operator *********************/ + +static int hide_exec(bContext *C, wmOperator *op) +{ + SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C); + Scene *scene= CTX_data_scene(C); + Object *obedit= CTX_data_edit_object(C); + EditMesh *em= ((Mesh*)obedit->data)->edit_mesh; + EditFace *efa; + MTFace *tf; + int swap= (strcmp(op->idname, "UV_OT_hide_deselected") == 0); + + if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) { + EM_hide_mesh(em, swap); + WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + return OPERATOR_FINISHED; + } + + if(swap) { + for(efa= em->faces.first; efa; efa= efa->next) { + if(efa->f & SELECT) { + tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + if(sima->flag & SI_SELACTFACE) { + /* Pretend face mode */ + if(( (efa->v4==NULL && + ( tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3)) == (TF_SEL1|TF_SEL2|TF_SEL3) ) || + ( tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4)) == (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4) ) == 0) { + + if(em->selectmode == SCE_SELECT_FACE) { + efa->f &= ~SELECT; + /* must re-select after */ + efa->e1->f &= ~SELECT; + efa->e2->f &= ~SELECT; + efa->e3->f &= ~SELECT; + if(efa->e4) efa->e4->f &= ~SELECT; + } + else + EM_select_face(efa, 0); + } + tf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4); + } + else if(em->selectmode == SCE_SELECT_FACE) { + if((tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3))==0) { + if(!efa->v4) + EM_select_face(efa, 0); + else if(!(tf->flag & TF_SEL4)) + EM_select_face(efa, 0); + tf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4); + } + } + else { + /* EM_deselect_flush will deselect the face */ + if((tf->flag & TF_SEL1)==0) efa->v1->f &= ~SELECT; + if((tf->flag & TF_SEL2)==0) efa->v2->f &= ~SELECT; + if((tf->flag & TF_SEL3)==0) efa->v3->f &= ~SELECT; + if((efa->v4) && (tf->flag & TF_SEL4)==0) efa->v4->f &= ~SELECT; + + tf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4); + } + } + } + } + else { + for(efa= em->faces.first; efa; efa= efa->next) { + if(efa->f & SELECT) { + tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + + if(sima->flag & SI_SELACTFACE) { + if( (efa->v4==NULL && + ( tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3)) == (TF_SEL1|TF_SEL2|TF_SEL3) ) || + ( tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4)) == (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4) ) { + + if(em->selectmode == SCE_SELECT_FACE) { + efa->f &= ~SELECT; + /* must re-select after */ + efa->e1->f &= ~SELECT; + efa->e2->f &= ~SELECT; + efa->e3->f &= ~SELECT; + if(efa->e4) efa->e4->f &= ~SELECT; + } + else + EM_select_face(efa, 0); + } + + tf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4); + } + else if(em->selectmode == SCE_SELECT_FACE) { + if(tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3)) + EM_select_face(efa, 0); + else if(efa->v4 && tf->flag & TF_SEL4) + EM_select_face(efa, 0); + + tf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4); + } + else { + /* EM_deselect_flush will deselect the face */ + if(tf->flag & TF_SEL1) efa->v1->f &= ~SELECT; + if(tf->flag & TF_SEL2) efa->v2->f &= ~SELECT; + if(tf->flag & TF_SEL3) efa->v3->f &= ~SELECT; + if((efa->v4) && tf->flag & TF_SEL4) efa->v4->f &= ~SELECT; + + tf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4); + } + } + } + } + + /*deselects too many but ok for now*/ + if(em->selectmode & (SCE_SELECT_EDGE|SCE_SELECT_VERTEX)) + EM_deselect_flush(em); + + if(em->selectmode==SCE_SELECT_FACE) { + /* de-selected all edges from faces that were de-selected. + * now make sure all faces that are selected also have selected edges */ + for(efa= em->faces.first; efa; efa= efa->next) + if(efa->f & SELECT) + EM_select_face(efa, 1); + } + + EM_validate_selections(em); + WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + + return OPERATOR_FINISHED; +} + +void UV_OT_hide_selected(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Hide Selected"; + ot->idname= "UV_OT_hide_selected"; + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* api callbacks */ + ot->exec= hide_exec; + ot->poll= ED_operator_uvedit; +} + +void UV_OT_hide_deselected(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Hide Deselected"; + ot->idname= "UV_OT_hide_deselected"; + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* api callbacks */ + ot->exec= hide_exec; + ot->poll= ED_operator_uvedit; +} + +/****************** show hidden operator ******************/ + +static int show_hidden_exec(bContext *C, wmOperator *op) +{ + SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C); + Scene *scene= CTX_data_scene(C); + Object *obedit= CTX_data_edit_object(C); + EditMesh *em= ((Mesh*)obedit->data)->edit_mesh; + EditFace *efa; + MTFace *tf; + + /* call the mesh function if we are in mesh sync sel */ + if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) { + EM_reveal_mesh(em); + WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + return OPERATOR_FINISHED; + } + + if(sima->flag & SI_SELACTFACE) { + if(em->selectmode == SCE_SELECT_FACE) { + for(efa= em->faces.first; efa; efa= efa->next) { + if(!(efa->h) && !(efa->f & SELECT)) { + tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + EM_select_face(efa, 1); + tf->flag |= TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4; + } + } + } + else { + /* enable adjacent faces to have disconnected UV selections if sticky is disabled */ + if(sima->sticky == SI_STICKY_DISABLE) { + for(efa= em->faces.first; efa; efa= efa->next) { + if(!(efa->h) && !(efa->f & SELECT)) { + /* All verts must be unselected for the face to be selected in the UV view */ + if((efa->v1->f&SELECT)==0 && (efa->v2->f&SELECT)==0 && (efa->v3->f&SELECT)==0 && (efa->v4==0 || (efa->v4->f&SELECT)==0)) { + tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + + tf->flag |= TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4; + /* Cant use EM_select_face here because it unselects the verts + * and we cant tell if the face was totally unselected or not */ + /*EM_select_face(efa, 1); + * + * See Loop with EM_select_face() below... */ + efa->f |= SELECT; + } + } + } + } + else { + for(efa= em->faces.first; efa; efa= efa->next) { + if(!(efa->h) && !(efa->f & SELECT)) { + tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + + if((efa->v1->f & SELECT)==0) {tf->flag |= TF_SEL1;} + if((efa->v2->f & SELECT)==0) {tf->flag |= TF_SEL2;} + if((efa->v3->f & SELECT)==0) {tf->flag |= TF_SEL3;} + if((efa->v4 && (efa->v4->f & SELECT)==0)) {tf->flag |= TF_SEL4;} + + efa->f |= SELECT; + } + } + } + + /* Select all edges and verts now */ + for(efa= em->faces.first; efa; efa= efa->next) + /* we only selected the face flags, and didnt changes edges or verts, fix this now */ + if(!(efa->h) && (efa->f & SELECT)) + EM_select_face(efa, 1); + + EM_select_flush(em); + } + } + else if(em->selectmode == SCE_SELECT_FACE) { + for(efa= em->faces.first; efa; efa= efa->next) { + if(!(efa->h) && !(efa->f & SELECT)) { + tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + efa->f |= SELECT; + tf->flag |= TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4; + } + } + + /* Select all edges and verts now */ + for(efa= em->faces.first; efa; efa= efa->next) + /* we only selected the face flags, and didnt changes edges or verts, fix this now */ + if(!(efa->h) && (efa->f & SELECT)) + EM_select_face(efa, 1); + } + else { + for(efa= em->faces.first; efa; efa= efa->next) { + if(!(efa->h) && !(efa->f & SELECT)) { + tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + + if((efa->v1->f & SELECT)==0) {tf->flag |= TF_SEL1;} + if((efa->v2->f & SELECT)==0) {tf->flag |= TF_SEL2;} + if((efa->v3->f & SELECT)==0) {tf->flag |= TF_SEL3;} + if((efa->v4 && (efa->v4->f & SELECT)==0)) {tf->flag |= TF_SEL4;} + + efa->f |= SELECT; + } + } + + /* Select all edges and verts now */ + for(efa= em->faces.first; efa; efa= efa->next) + /* we only selected the face flags, and didnt changes edges or verts, fix this now */ + if(!(efa->h) && (efa->f & SELECT)) + EM_select_face(efa, 1); + } + + WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + + return OPERATOR_FINISHED; +} + +void UV_OT_show_hidden(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Show Hidden"; + ot->idname= "UV_OT_show_hidden"; + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* api callbacks */ + ot->exec= show_hidden_exec; + ot->poll= ED_operator_uvedit; +} + /* ************************** registration **********************************/ void ED_operatortypes_uvedit(void) @@ -2648,10 +2920,20 @@ void ED_operatortypes_uvedit(void) WM_operatortype_append(UV_OT_weld); WM_operatortype_append(UV_OT_pin); - WM_operatortype_append(UV_OT_unwrap); - WM_operatortype_append(UV_OT_minimize_stretch); WM_operatortype_append(UV_OT_average_islands_scale); + WM_operatortype_append(UV_OT_cube_project); + WM_operatortype_append(UV_OT_cylinder_project); + WM_operatortype_append(UV_OT_from_view); + WM_operatortype_append(UV_OT_mapping_menu); + WM_operatortype_append(UV_OT_minimize_stretch); WM_operatortype_append(UV_OT_pack_islands); + WM_operatortype_append(UV_OT_reset); + WM_operatortype_append(UV_OT_sphere_project); + WM_operatortype_append(UV_OT_unwrap); + + WM_operatortype_append(UV_OT_show_hidden); + WM_operatortype_append(UV_OT_hide_selected); + WM_operatortype_append(UV_OT_hide_deselected); } void ED_keymap_uvedit(wmWindowManager *wm) @@ -2662,8 +2944,7 @@ void ED_keymap_uvedit(wmWindowManager *wm) WM_keymap_add_item(keymap, "UV_OT_select", SELECTMOUSE, KM_PRESS, 0, 0); RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", 1); WM_keymap_add_item(keymap, "UV_OT_loop_select", SELECTMOUSE, KM_PRESS, KM_ALT, 0); - // XXX not working? - RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_loop_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, KM_ALT)->ptr, "extend", 1); + RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_loop_select", SELECTMOUSE, KM_PRESS, KM_SHIFT|KM_ALT, 0)->ptr, "extend", 1); /* border/circle selection */ WM_keymap_add_item(keymap, "UV_OT_border_select", BKEY, KM_PRESS, 0, 0); @@ -2688,6 +2969,11 @@ void ED_keymap_uvedit(wmWindowManager *wm) WM_keymap_add_item(keymap, "UV_OT_pack_islands", PKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "UV_OT_average_islands_scale", AKEY, KM_PRESS, KM_CTRL, 0); + /* hide */ + WM_keymap_add_item(keymap, "UV_OT_hide_selected", HKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "UV_OT_hide_deselected", HKEY, KM_PRESS, KM_SHIFT, 0); + WM_keymap_add_item(keymap, "UV_OT_show_hidden", HKEY, KM_PRESS, KM_ALT, 0); + transform_keymap_for_space(wm, keymap, SPACE_IMAGE); } diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c index 635a7903d6f..0fcd0062044 100644 --- a/source/blender/editors/uvedit/uvedit_parametrizer.c +++ b/source/blender/editors/uvedit/uvedit_parametrizer.c @@ -3828,7 +3828,7 @@ static void p_smooth(PChart *chart) if (hedges) MEM_freeN(hedges); if (vedges) MEM_freeN(vedges); - // XXX error("Not enough memory for area smoothing grid."); + // printf("Not enough memory for area smoothing grid."); return; } @@ -3978,7 +3978,7 @@ static void p_smooth(PChart *chart) if (triangles) MEM_freeN(triangles); if (tri) MEM_freeN(tri); - // XXX error("Not enough memory for area smoothing grid."); + // printf("Not enough memory for area smoothing grid."); return; } diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index c7e0dfd7bc7..ccad3acfd56 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -53,46 +53,54 @@ #include "PIL_time.h" +#include "ED_image.h" #include "ED_mesh.h" #include "ED_screen.h" #include "ED_uvedit.h" +#include "ED_view3d.h" #include "RNA_access.h" #include "RNA_define.h" +#include "UI_interface.h" + #include "WM_api.h" #include "WM_types.h" #include "uvedit_intern.h" #include "uvedit_parametrizer.h" -static void ED_uvedit_create_uvs(EditMesh *em) +static int ED_uvedit_ensure_uvs(bContext *C, Scene *scene, Object *obedit) { -#if 0 - if (em && em->faces.first) - EM_add_data_layer(&em->fdata, CD_MTFACE); + EditMesh *em= ((Mesh*)obedit->data)->edit_mesh; + EditFace *efa; + MTFace *tf; + + if(ED_uvedit_test(obedit)) + return 1; + + if(em && em->faces.first) + EM_add_data_layer(em, &em->fdata, CD_MTFACE); - if (!ED_uvedit_test(obedit)) - return; + if(!ED_uvedit_test(obedit)) + return 0; - 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); + // XXX this image is not in context in 3d view .. only + // way to get would be to find the first image window? + ED_uvedit_assign_image(scene, obedit, CTX_data_edit_image(C), NULL); /* select new UV's */ - if ((G.sima==0 || G.sima->flag & SI_SYNC_UVSEL)==0) { - EditFace *efa; - MTFace *tf; - for(efa=em->faces.first; efa; efa=efa->next) { - tf= (MTFace *)CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - simaFaceSel_Set(efa, tf); - } + for(efa=em->faces.first; efa; efa=efa->next) { + tf= (MTFace *)CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + uvedit_face_select(scene, efa, tf); } -#endif + + return 1; } /****************** Parametrizer Conversion ***************/ -ParamHandle *construct_param_handle(Scene *scene, EditMesh *em, short implicit, short fill, short sel) +ParamHandle *construct_param_handle(Scene *scene, EditMesh *em, short implicit, short fill, short sel, short correct_aspect) { ParamHandle *handle; EditFace *efa; @@ -103,37 +111,37 @@ ParamHandle *construct_param_handle(Scene *scene, EditMesh *em, short implicit, handle = param_construct_begin(); - if((scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT)==0) { + if(correct_aspect) { efa = EM_get_actFace(em, 1); - if (efa) { - float aspx = 1.0f, aspy= 1.0f; - // XXX MTFace *tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - // XXX image_final_aspect(tf->tpage, &aspx, &aspy); - // XXX get_space_image_aspect(sima, &aspx, &aspy); + if(efa) { + MTFace *tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + float aspx, aspy; + + ED_image_uv_aspect(tf->tpage, &aspx, &aspy); - if (aspx!=aspy) + if(aspx!=aspy) param_aspect_ratio(handle, aspx, aspy); } } /* we need the vert indicies */ - for (ev= em->verts.first, a=0; ev; ev= ev->next, a++) + for(ev= em->verts.first, a=0; ev; ev= ev->next, a++) ev->tmp.l = a; - for (efa= em->faces.first; efa; efa= efa->next) { + for(efa= em->faces.first; efa; efa= efa->next) { ParamKey key, vkeys[4]; ParamBool pin[4], select[4]; float *co[4]; float *uv[4]; int nverts; - if ((efa->h) || (sel && (efa->f & SELECT)==0)) + if((efa->h) || (sel && (efa->f & SELECT)==0)) continue; tf= (MTFace *)CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - if (implicit && + if(implicit && !( uvedit_uv_selected(scene, efa, tf, 0) || uvedit_uv_selected(scene, efa, tf, 1) || uvedit_uv_selected(scene, efa, tf, 2) || @@ -163,7 +171,7 @@ ParamHandle *construct_param_handle(Scene *scene, EditMesh *em, short implicit, select[1] = ((uvedit_uv_selected(scene, efa, tf, 1)) != 0); select[2] = ((uvedit_uv_selected(scene, efa, tf, 2)) != 0); - if (efa->v4) { + if(efa->v4) { vkeys[3] = (ParamKey)efa->v4->tmp.l; co[3] = efa->v4->co; uv[3] = tf->uv[3]; @@ -177,8 +185,8 @@ ParamHandle *construct_param_handle(Scene *scene, EditMesh *em, short implicit, param_face_add(handle, key, nverts, vkeys, co, uv, pin, select); } - if (!implicit) { - for (eed= em->edges.first; eed; eed= eed->next) { + if(!implicit) { + for(eed= em->edges.first; eed; eed= eed->next) { if(eed->seam) { ParamKey vkeys[2]; vkeys[0] = (ParamKey)eed->v1->tmp.l; @@ -193,61 +201,7 @@ ParamHandle *construct_param_handle(Scene *scene, EditMesh *em, short implicit, return handle; } -/* ******************** unwrap operator **************** */ - -static int unwrap_exec(bContext *C, wmOperator *op) -{ - Scene *scene= CTX_data_scene(C); - Object *obedit= CTX_data_edit_object(C); - EditMesh *em= ((Mesh*)obedit->data)->edit_mesh; - ParamHandle *handle; - int method = RNA_enum_get(op->ptr, "method"); - int fill_holes = RNA_boolean_get(op->ptr, "fill_holes"); - - /* add uvs if they don't exist yet */ - if(!ED_uvedit_test(obedit)) - ED_uvedit_create_uvs(em); - - handle= construct_param_handle(scene, em, 0, fill_holes, 0); - - param_lscm_begin(handle, PARAM_FALSE, method == 0); - param_lscm_solve(handle); - param_lscm_end(handle); - - param_pack(handle); - - param_flush(handle); - - param_delete(handle); - - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); - - return OPERATOR_FINISHED; -} - -void UV_OT_unwrap(wmOperatorType *ot) -{ - static EnumPropertyItem method_items[] = { - {0, "ANGLE_BASED", "Angle Based", ""}, - {1, "CONFORMAL", "Conformal", ""}, - {0, NULL, NULL, NULL}}; - - /* identifiers */ - ot->name= "Unwrap"; - ot->idname= "UV_OT_unwrap"; - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - /* api callbacks */ - ot->exec= unwrap_exec; - ot->poll= ED_operator_uvmap; - - /* properties */ - RNA_def_enum(ot->srna, "method", method_items, 0, "Method", "Unwrapping method. Angle Based usually gives better results than Conformal, while being somewhat slower."); - RNA_def_boolean(ot->srna, "fill_holes", 1, "Fill Holes", "Virtual fill holes in mesh before unwrapping, to better avoid overlaps and preserve symmetry."); -} - -/* ******************** minimize stretch operator **************** */ +/* ******************** Minimize Stretch operator **************** */ typedef struct MinStretch { Scene *scene; @@ -274,7 +228,7 @@ static void minimize_stretch_init(bContext *C, wmOperator *op) ms->em= em; ms->blend= RNA_float_get(op->ptr, "blend"); ms->iterations= RNA_int_get(op->ptr, "iterations"); - ms->handle= construct_param_handle(scene, em, 1, fill_holes, 1); + ms->handle= construct_param_handle(scene, em, 1, fill_holes, 1, 1); ms->lasttime= PIL_check_seconds_timer(); param_stretch_begin(ms->handle); @@ -440,7 +394,7 @@ void UV_OT_minimize_stretch(wmOperatorType *ot) RNA_def_int(ot->srna, "iterations", 0, 0, INT_MAX, "Iterations", "Number of iterations to run, 0 is unlimited when run interactively.", 0, 100); } -/* ******************** pack islands operator **************** */ +/* ******************** Pack Islands operator **************** */ static int pack_islands_exec(bContext *C, wmOperator *op) { @@ -449,7 +403,7 @@ static int pack_islands_exec(bContext *C, wmOperator *op) EditMesh *em= ((Mesh*)obedit->data)->edit_mesh; ParamHandle *handle; - handle = construct_param_handle(scene, em, 1, 0, 1); + handle = construct_param_handle(scene, em, 1, 0, 1, 1); param_pack(handle); param_flush(handle); param_delete(handle); @@ -472,7 +426,7 @@ void UV_OT_pack_islands(wmOperatorType *ot) ot->poll= ED_operator_uvedit; } -/* ******************** average islands scale operator **************** */ +/* ******************** Average Islands Scale operator **************** */ static int average_islands_scale_exec(bContext *C, wmOperator *op) { @@ -481,7 +435,7 @@ static int average_islands_scale_exec(bContext *C, wmOperator *op) EditMesh *em= ((Mesh*)obedit->data)->edit_mesh; ParamHandle *handle; - handle= construct_param_handle(scene, em, 1, 0, 1); + handle= construct_param_handle(scene, em, 1, 0, 1, 1); param_average(handle); param_flush(handle); param_delete(handle); @@ -516,14 +470,14 @@ void ED_uvedit_live_unwrap_begin(Scene *scene, Object *obedit) if(!ED_uvedit_test(obedit)) return; - liveHandle = construct_param_handle(scene, em, 0, fillholes, 1); + liveHandle = construct_param_handle(scene, em, 0, fillholes, 1, 1); param_lscm_begin(liveHandle, PARAM_TRUE, abf); } void ED_uvedit_live_unwrap_re_solve(void) { - if (liveHandle) { + if(liveHandle) { param_lscm_solve(liveHandle); param_flush(liveHandle); } @@ -531,12 +485,831 @@ void ED_uvedit_live_unwrap_re_solve(void) void ED_uvedit_live_unwrap_end(short cancel) { - if (liveHandle) { + if(liveHandle) { param_lscm_end(liveHandle); - if (cancel) + if(cancel) param_flush_restore(liveHandle); param_delete(liveHandle); liveHandle = NULL; } } +/*************** UV Map Common Transforms *****************/ + +#define VIEW_ON_EQUATOR 0 +#define VIEW_ON_POLES 1 +#define ALIGN_TO_OBJECT 2 + +#define POLAR_ZX 0 +#define POLAR_ZY 1 + +static void uv_map_transform_center(Scene *scene, View3D *v3d, float *result, Object *ob, EditMesh *em) +{ + EditFace *efa; + float min[3], max[3], *cursx; + int around= (v3d)? v3d->around: V3D_CENTER; + + /* only operates on the edit object - this is all that's needed now */ + + switch(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_map_rotation_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.0f, upangle= 0.0f; + int k; + + /* get rotation of the current view matrix */ + if(rv3d) + Mat4CpyMat4(viewmatrix, rv3d->viewmat); + else + Mat4One(viewmatrix); + + /* but shifting */ + for(k=0; k<4; k++) + viewmatrix[3][k] =0.0f; + + /* get rotation of the current object matrix */ + Mat4CpyMat4(rotobj,ob->obmat); + + /* but shifting */ + for(k=0; k<4; k++) + rotobj[3][k] =0.0f; + + 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= (float)M_PI*(sideangledeg + 180.0f)/180.0f; + 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= (float)M_PI*upangledeg/180.0f; + 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.0f/radius; + + /* calculate transforms*/ + Mat4MulSerie(result, rotup, rotside, viewmatrix, rotobj, NULL, NULL, NULL, NULL); +} + +static void uv_map_transform(bContext *C, wmOperator *op, float center[3], float rotmat[4][4]) +{ + /* context checks are messy here, making it work in both 3d view and uv editor */ + Scene *scene= CTX_data_scene(C); + Object *obedit= CTX_data_edit_object(C); + EditMesh *em= ((Mesh*)obedit->data)->edit_mesh; + SpaceLink *sl= CTX_wm_space_data(C); + View3D *v3d= (sl->spacetype == SPACE_VIEW3D)? (View3D*)sl: NULL; + ARegion *ar= CTX_wm_region(C); + RegionView3D *rv3d= (v3d && ar->regiontype == RGN_TYPE_WINDOW)? ar->regiondata: NULL; + /* common operator properties */ + int align= RNA_enum_get(op->ptr, "align"); + int direction= RNA_enum_get(op->ptr, "direction"); + float radius= RNA_struct_find_property(op->ptr, "radius")? RNA_float_get(op->ptr, "radius"): 1.0f; + float upangledeg, sideangledeg; + + uv_map_transform_center(scene, v3d, center, obedit, em); + + if(direction == VIEW_ON_EQUATOR) { + upangledeg= 90.0f; + sideangledeg= 0.0f; + } + else { + upangledeg= 0.0f; + if(align == POLAR_ZY) sideangledeg= 0.0f; + else sideangledeg= 90.0f; + } + + /* be compatible to the "old" sphere/cylinder mode */ + if(direction == ALIGN_TO_OBJECT) + Mat4One(rotmat); + else + uv_map_rotation_matrix(rotmat, rv3d, obedit, upangledeg, sideangledeg, radius); +} + +static void uv_transform_properties(wmOperatorType *ot, int radius) +{ + static EnumPropertyItem direction_items[]= { + {VIEW_ON_EQUATOR, "VIEW_ON_EQUATOR", "View on Equator", "3D view is on the equator."}, + {VIEW_ON_POLES, "VIEW_ON_POLES", "View on Poles", "3D view is on the poles."}, + {ALIGN_TO_OBJECT, "ALIGN_TO_OBJECT", "Align to Object", "Align according to object transform."}, + {0, NULL, NULL, NULL} + }; + static EnumPropertyItem align_items[]= { + {POLAR_ZX, "POLAR_ZX", "Polar ZX", "Polar 0 is X."}, + {POLAR_ZY, "POLAR_ZY", "Polar ZY", "Polar 0 is Y."}, + {0, NULL, NULL, NULL} + }; + + RNA_def_enum(ot->srna, "direction", direction_items, VIEW_ON_EQUATOR, "Direction", "Direction of the sphere or cylinder."); + RNA_def_enum(ot->srna, "align", align_items, VIEW_ON_EQUATOR, "Align", "How to determine rotation around the pole."); + if(radius) + RNA_def_float(ot->srna, "radius", 1.0f, 0.0f, FLT_MAX, "Radius", "Radius of the sphere or cylinder.", 0.0001f, 100.0f); +} + +static void correct_uv_aspect(EditMesh *em) +{ + EditFace *efa= EM_get_actFace(em, 1); + MTFace *tf; + float scale, aspx= 1.0f, aspy=1.0f; + + if(efa) { + tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + ED_image_uv_aspect(tf->tpage, &aspx, &aspy); + } + + if(aspx == aspy) + return; + + if(aspx > aspy) { + scale= aspy/aspx; + + for(efa= em->faces.first; efa; efa= efa->next) { + if(efa->f & SELECT) { + tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + + tf->uv[0][0]= ((tf->uv[0][0]-0.5)*scale)+0.5; + tf->uv[1][0]= ((tf->uv[1][0]-0.5)*scale)+0.5; + tf->uv[2][0]= ((tf->uv[2][0]-0.5)*scale)+0.5; + if(efa->v4) + tf->uv[3][0]= ((tf->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) { + tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + + tf->uv[0][1]= ((tf->uv[0][1]-0.5)*scale)+0.5; + tf->uv[1][1]= ((tf->uv[1][1]-0.5)*scale)+0.5; + tf->uv[2][1]= ((tf->uv[2][1]-0.5)*scale)+0.5; + if(efa->v4) + tf->uv[3][1]= ((tf->uv[3][1]-0.5)*scale)+0.5; + } + } + } +} + +/******************** Map Clip & Correct ******************/ + +static void uv_map_clip_correct_properties(wmOperatorType *ot) +{ + RNA_def_boolean(ot->srna, "correct_aspect", 1, "Correct Aspect", "Map UV's taking image aspect ratio into account."); + RNA_def_boolean(ot->srna, "clip_to_bounds", 0, "Clip to Bounds", "Clip UV coordinates to bounds after unwrapping."); + RNA_def_boolean(ot->srna, "scale_to_bounds", 0, "Scale to Bounds", "Scale UV coordinates to bounds after unwrapping."); +} + +static void uv_map_clip_correct(EditMesh *em, wmOperator *op) +{ + EditFace *efa; + MTFace *tf; + float dx, dy, min[2], max[2]; + int b, nverts; + int correct_aspect= RNA_boolean_get(op->ptr, "correct_aspect"); + int clip_to_bounds= RNA_boolean_get(op->ptr, "clip_to_bounds"); + int scale_to_bounds= RNA_boolean_get(op->ptr, "scale_to_bounds"); + + /* correct for image aspect ratio */ + if(correct_aspect) + correct_uv_aspect(em); + + if(scale_to_bounds) { + INIT_MINMAX2(min, max); + + for(efa= em->faces.first; efa; efa= efa->next) { + if(efa->f & SELECT) { + tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + + DO_MINMAX2(tf->uv[0], min, max); + DO_MINMAX2(tf->uv[1], min, max); + DO_MINMAX2(tf->uv[2], min, max); + + if(efa->v4) + DO_MINMAX2(tf->uv[3], min, max); + } + } + + /* rescale UV to be in 1/1 */ + dx= (max[0]-min[0]); + dy= (max[1]-min[1]); + + if(dx > 0.0f) + dx= 1.0f/dx; + if(dy > 0.0f) + dy= 1.0f/dy; + + for(efa= em->faces.first; efa; efa= efa->next) { + if(efa->f & SELECT) { + tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + + nverts= (efa->v4)? 4: 3; + + for(b=0; b<nverts; b++) { + tf->uv[b][0]= (tf->uv[b][0]-min[0])*dx; + tf->uv[b][1]= (tf->uv[b][1]-min[1])*dy; + } + } + } + } + else if(clip_to_bounds) { + /* clipping and wrapping */ + for(efa= em->faces.first; efa; efa= efa->next) { + if(efa->f & SELECT) { + tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + + nverts= (efa->v4)? 4: 3; + + for(b=0; b<nverts; b++) { + CLAMP(tf->uv[b][0], 0.0, 1.0); + CLAMP(tf->uv[b][1], 0.0, 1.0); + } + } + } + } +} + +/* ******************** Unwrap operator **************** */ + +static int unwrap_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + Object *obedit= CTX_data_edit_object(C); + EditMesh *em= ((Mesh*)obedit->data)->edit_mesh; + ParamHandle *handle; + int method = RNA_enum_get(op->ptr, "method"); + int fill_holes = RNA_boolean_get(op->ptr, "fill_holes"); + int correct_aspect = RNA_boolean_get(op->ptr, "correct_aspect"); + + /* add uvs if they don't exist yet */ + if(!ED_uvedit_ensure_uvs(C, scene, obedit)) + return OPERATOR_CANCELLED; + + handle= construct_param_handle(scene, em, 0, fill_holes, 0, correct_aspect); + + param_lscm_begin(handle, PARAM_FALSE, method == 0); + param_lscm_solve(handle); + param_lscm_end(handle); + + param_pack(handle); + + param_flush(handle); + + param_delete(handle); + + DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); + + return OPERATOR_FINISHED; +} + +void UV_OT_unwrap(wmOperatorType *ot) +{ + static EnumPropertyItem method_items[] = { + {0, "ANGLE_BASED", "Angle Based", ""}, + {1, "CONFORMAL", "Conformal", ""}, + {0, NULL, NULL, NULL}}; + + /* identifiers */ + ot->name= "Unwrap"; + ot->idname= "UV_OT_unwrap"; + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* api callbacks */ + ot->exec= unwrap_exec; + ot->poll= ED_operator_uvmap; + + /* properties */ + RNA_def_enum(ot->srna, "method", method_items, 0, "Method", "Unwrapping method. Angle Based usually gives better results than Conformal, while being somewhat slower."); + RNA_def_boolean(ot->srna, "fill_holes", 1, "Fill Holes", "Virtual fill holes in mesh before unwrapping, to better avoid overlaps and preserve symmetry."); + RNA_def_boolean(ot->srna, "correct_aspect", 1, "Correct Aspect", "Map UV's taking image aspect ratio into account."); +} + +/**************** Project From View operator **************/ + +static void uv_from_view_bounds(float target[2], float source[3], float rotmat[4][4]) +{ + float pv[3]; + + Mat4MulVecfl(rotmat, pv); + + /* ortho projection */ + target[0] = -pv[0]; + target[1] = pv[2]; +} + +static void uv_from_view(ARegion *ar, float target[2], float source[3], float rotmat[4][4]) +{ + RegionView3D *rv3d= ar->regiondata; + float pv[3], pv4[4], dx, dy, x= 0.0, y= 0.0; + + Mat4MulVecfl(rotmat, pv); + + 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; +} + +static int from_view_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + Object *obedit= CTX_data_edit_object(C); + EditMesh *em= ((Mesh*)obedit->data)->edit_mesh; + ARegion *ar= CTX_wm_region(C); + EditFace *efa; + MTFace *tf; + float rotmat[4][4]; + + /* add uvs if they don't exist yet */ + if(!ED_uvedit_ensure_uvs(C, scene, obedit)) + return OPERATOR_CANCELLED; + + if(RNA_boolean_get(op->ptr, "orthographic")) { + uv_map_rotation_matrix(rotmat, ar->regiondata, obedit, 90.0f, 0.0f, 1.0f); + + for(efa= em->faces.first; efa; efa= efa->next) { + if(efa->f & SELECT) { + tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + + uv_from_view_bounds(tf->uv[0], efa->v1->co, rotmat); + uv_from_view_bounds(tf->uv[1], efa->v2->co, rotmat); + uv_from_view_bounds(tf->uv[2], efa->v3->co, rotmat); + if(efa->v4) + uv_from_view_bounds(tf->uv[3], efa->v4->co, rotmat); + } + } + } + else { + Mat4CpyMat4(rotmat, obedit->obmat); + + for(efa= em->faces.first; efa; efa= efa->next) { + if(efa->f & SELECT) { + tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + + uv_from_view(ar, tf->uv[0], efa->v1->co, rotmat); + uv_from_view(ar, tf->uv[1], efa->v2->co, rotmat); + uv_from_view(ar, tf->uv[2], efa->v3->co, rotmat); + if(efa->v4) + uv_from_view(ar, tf->uv[3], efa->v4->co, rotmat); + } + } + } + + uv_map_clip_correct(em, op); + + DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); + + return OPERATOR_FINISHED; +} + +static int from_view_poll(bContext *C) +{ + SpaceLink *sl= CTX_wm_space_data(C); + ARegion *ar= CTX_wm_region(C); + + if(!ED_operator_uvmap(C)) + return 0; + + return (sl->spacetype == SPACE_VIEW3D && ar->regiontype == RGN_TYPE_WINDOW); +} + +void UV_OT_from_view(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Project From View"; + ot->idname= "UV_OT_project_from_view"; + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* api callbacks */ + ot->exec= from_view_exec; + ot->poll= from_view_poll; + + /* properties */ + RNA_def_boolean(ot->srna, "orthographic", 0, "Orthographic", "Use orthographic projection."); + uv_map_clip_correct_properties(ot); +} + +/********************** Reset operator ********************/ + +static int reset_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + Object *obedit= CTX_data_edit_object(C); + EditMesh *em= ((Mesh*)obedit->data)->edit_mesh; + EditFace *efa; + MTFace *tf; + + /* add uvs if they don't exist yet */ + if(!ED_uvedit_ensure_uvs(C, scene, obedit)) + return OPERATOR_CANCELLED; + + for(efa= em->faces.first; efa; efa= efa->next) { + if(efa->f & SELECT) { + tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + + tf->uv[0][0]= 0.0f; + tf->uv[0][1]= 0.0f; + + tf->uv[1][0]= 1.0f; + tf->uv[1][1]= 0.0f; + + tf->uv[2][0]= 1.0f; + tf->uv[2][1]= 1.0f; + + tf->uv[3][0]= 0.0f; + tf->uv[3][1]= 1.0f; + } + } + + DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); + + return OPERATOR_FINISHED; +} + +void UV_OT_reset(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Reset"; + ot->idname= "UV_OT_reset"; + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* api callbacks */ + ot->exec= reset_exec; + ot->poll= ED_operator_uvmap; +} + +/****************** Sphere Project operator ***************/ + +static void uv_sphere_project(float target[2], float source[3], float center[3], float rotmat[4][4]) +{ + float pv[3]; + + VecSubf(pv, source, center); + Mat4MulVecfl(rotmat, pv); + + 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; +} + +static void uv_map_mirror(EditFace *efa, MTFace *tf) +{ + float dx; + int nverts, i, mi; + + nverts= (efa->v4)? 4: 3; + + mi = 0; + for(i=1; i<nverts; i++) + if(tf->uv[i][0] > tf->uv[mi][0]) + mi = i; + + for(i=0; i<nverts; i++) { + if(i != mi) { + dx = tf->uv[mi][0] - tf->uv[i][0]; + if(dx > 0.5) tf->uv[i][0] += 1.0; + } + } +} + +static int sphere_project_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + Object *obedit= CTX_data_edit_object(C); + EditMesh *em= ((Mesh*)obedit->data)->edit_mesh; + EditFace *efa; + MTFace *tf; + float center[3], rotmat[4][4]; + + /* add uvs if they don't exist yet */ + if(!ED_uvedit_ensure_uvs(C, scene, obedit)) + return OPERATOR_CANCELLED; + + uv_map_transform(C, op, center, rotmat); + + for(efa= em->faces.first; efa; efa= efa->next) { + if(efa->f & SELECT) { + tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + + uv_sphere_project(tf->uv[0], efa->v1->co, center, rotmat); + uv_sphere_project(tf->uv[1], efa->v2->co, center, rotmat); + uv_sphere_project(tf->uv[2], efa->v3->co, center, rotmat); + if(efa->v4) + uv_sphere_project(tf->uv[3], efa->v4->co, center, rotmat); + + uv_map_mirror(efa, tf); + } + } + + uv_map_clip_correct(em, op); + + DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); + + return OPERATOR_FINISHED; +} + +void UV_OT_sphere_project(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Sphere Projection"; + ot->idname= "UV_OT_sphere_project"; + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* api callbacks */ + ot->exec= sphere_project_exec; + ot->poll= ED_operator_uvmap; + + /* properties */ + uv_transform_properties(ot, 0); + uv_map_clip_correct_properties(ot); +} + +/***************** Cylinder Project operator **************/ + +static void uv_cylinder_project(float target[2], float source[3], float center[3], float rotmat[4][4]) +{ + float pv[3]; + + VecSubf(pv, source, center); + Mat4MulVecfl(rotmat, pv); + + 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; +} + +static int cylinder_project_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + Object *obedit= CTX_data_edit_object(C); + EditMesh *em= ((Mesh*)obedit->data)->edit_mesh; + EditFace *efa; + MTFace *tf; + float center[3], rotmat[4][4]; + + /* add uvs if they don't exist yet */ + if(!ED_uvedit_ensure_uvs(C, scene, obedit)) + return OPERATOR_CANCELLED; + + uv_map_transform(C, op, center, rotmat); + + for(efa= em->faces.first; efa; efa= efa->next) { + if(efa->f & SELECT) { + tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + + uv_cylinder_project(tf->uv[0], efa->v1->co, center, rotmat); + uv_cylinder_project(tf->uv[1], efa->v2->co, center, rotmat); + uv_cylinder_project(tf->uv[2], efa->v3->co, center, rotmat); + if(efa->v4) + uv_cylinder_project(tf->uv[3], efa->v4->co, center, rotmat); + + uv_map_mirror(efa, tf); + } + } + + uv_map_clip_correct(em, op); + + DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); + + return OPERATOR_FINISHED; +} + +void UV_OT_cylinder_project(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Cylinder Projection"; + ot->idname= "UV_OT_cylinder_project"; + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* api callbacks */ + ot->exec= cylinder_project_exec; + ot->poll= ED_operator_uvmap; + + /* properties */ + uv_transform_properties(ot, 1); + uv_map_clip_correct_properties(ot); +} + +/******************* Cube Project operator ****************/ + +static int cube_project_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + Object *obedit= CTX_data_edit_object(C); + EditMesh *em= ((Mesh*)obedit->data)->edit_mesh; + EditFace *efa; + MTFace *tf; + float no[3], cube_size, *loc, dx, dy; + int cox, coy; + + /* add uvs if they don't exist yet */ + if(!ED_uvedit_ensure_uvs(C, scene, obedit)) + return OPERATOR_CANCELLED; + + loc= obedit->obmat[3]; + cube_size= RNA_float_get(op->ptr, "cube_size"); + + /* choose x,y,z axis for projection depending on the largest normal + * component, but clusters all together around the center of map. */ + + for(efa= em->faces.first; efa; efa= efa->next) { + if(efa->f & SELECT) { + tf= 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; } + + tf->uv[0][0]= 0.5+0.5*cube_size*(loc[cox] + efa->v1->co[cox]); + tf->uv[0][1]= 0.5+0.5*cube_size*(loc[coy] + efa->v1->co[coy]); + dx = floor(tf->uv[0][0]); + dy = floor(tf->uv[0][1]); + tf->uv[0][0] -= dx; + tf->uv[0][1] -= dy; + tf->uv[1][0]= 0.5+0.5*cube_size*(loc[cox] + efa->v2->co[cox]); + tf->uv[1][1]= 0.5+0.5*cube_size*(loc[coy] + efa->v2->co[coy]); + tf->uv[1][0] -= dx; + tf->uv[1][1] -= dy; + tf->uv[2][0]= 0.5+0.5*cube_size*(loc[cox] + efa->v3->co[cox]); + tf->uv[2][1]= 0.5+0.5*cube_size*(loc[coy] + efa->v3->co[coy]); + tf->uv[2][0] -= dx; + tf->uv[2][1] -= dy; + + if(efa->v4) { + tf->uv[3][0]= 0.5+0.5*cube_size*(loc[cox] + efa->v4->co[cox]); + tf->uv[3][1]= 0.5+0.5*cube_size*(loc[coy] + efa->v4->co[coy]); + tf->uv[3][0] -= dx; + tf->uv[3][1] -= dy; + } + } + } + + uv_map_clip_correct(em, op); + + DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit); + + return OPERATOR_FINISHED; +} + +void UV_OT_cube_project(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Cube Projection"; + ot->idname= "UV_OT_cube_project"; + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* api callbacks */ + ot->exec= cube_project_exec; + ot->poll= ED_operator_uvmap; + + /* properties */ + RNA_def_float(ot->srna, "cube_size", 1.0f, 0.0f, FLT_MAX, "Cube Size", "Size of the cube to project on.", 0.001f, 100.0f); + uv_map_clip_correct_properties(ot); +} + +/******************* Mapping Menu operator ****************/ + +static int mapping_menu_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + uiMenuItem *head; + + head= uiPupMenuBegin("UV Mapping", 0); + uiMenuItemO(head, 0, "UV_OT_unwrap"); + uiMenuSeparator(head); + uiMenuItemO(head, 0, "UV_OT_cube_project"); + uiMenuItemO(head, 0, "UV_OT_cylinder_project"); + uiMenuItemO(head, 0, "UV_OT_sphere_project"); + uiMenuItemO(head, 0, "UV_OT_project_from_view"); + uiMenuSeparator(head); + uiMenuItemO(head, 0, "UV_OT_reset"); + uiPupMenuEnd(C, head); + + /* XXX python */ +#ifndef DISABLE_PYTHON +#if 0 + /* 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 + +#ifndef DISABLE_PYTHON +#if 0 + mode= pupmenu(uvmenu); + if(mode >= 10) { + BPY_menu_do_python(PYMENU_UVCALCULATION, mode - 10); + return; + } +#endif +#endif + + return OPERATOR_CANCELLED; +} + +void UV_OT_mapping_menu(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Mapping Menu"; + ot->idname= "UV_OT_mapping_menu"; + + /* api callbacks */ + ot->invoke= mapping_menu_invoke; + ot->poll= ED_operator_uvmap; +} + |