Index: source/blender/bmesh/intern/bmesh_opdefines.c =================================================================== --- source/blender/bmesh/intern/bmesh_opdefines.c (revision 23029) +++ source/blender/bmesh/intern/bmesh_opdefines.c (working copy) @@ -703,6 +703,18 @@ 0 }; +/* +** uv reverse +** reverse the uvs +*/ +BMOpDefine def_meshreverseuvs = { + "meshreverseuvs", + {{BMOP_OPSLOT_ELEMENT_BUF, "faces"}, /* input faces */ + {0} /*null-terminating sentinel*/}, + bmesh_reverseuvs_exec, + 0 +}; + BMOpDefine *opdefines[] = { &def_splitop, &def_dupeop, @@ -749,6 +761,7 @@ &def_pointmerge_facedata, &def_vert_average_facedata, &def_meshrotateuvs, + &def_meshreverseuvs }; int bmesh_total_ops = (sizeof(opdefines) / sizeof(void*)); Index: source/blender/bmesh/intern/bmesh_operators_private.h =================================================================== --- source/blender/bmesh/intern/bmesh_operators_private.h (revision 23029) +++ source/blender/bmesh/intern/bmesh_operators_private.h (working copy) @@ -52,5 +52,5 @@ void bmesh_pointmerge_facedata_exec(BMesh *bm, BMOperator *op); void bmesh_vert_average_facedata_exec(BMesh *bm, BMOperator *op); void bmesh_rotateuvs_exec(BMesh *bm, BMOperator *op); - +void bmesh_reverseuvs_exec(BMesh *bm, BMOperator *op); #endif Index: source/blender/bmesh/operators/utils.c =================================================================== --- source/blender/bmesh/operators/utils.c (revision 23029) +++ source/blender/bmesh/operators/utils.c (working copy) @@ -1024,3 +1024,55 @@ } } + +/****************************************************************************** +** Reverse UVs for a face +******************************************************************************/ + +#define MAX_N(a, b) ((a < b) ? b : a) + +void bmesh_reverseuvs_exec(BMesh *bm, BMOperator *op) +{ + BMOIter fs_iter; /* selected faces iterator */ + BMFace *fs; /* current face */ + BMIter l_iter; /* iteration loop */ + + float *uvs = NULL; + + int max_vert_count = 0; + + /* first thing we are going to do is to count the maximum number of vertices a face can have */ + BMO_ITER(fs, &fs_iter, bm, op, "faces", BM_FACE) { + max_vert_count = MAX_N(fs->len, max_vert_count); + } + + uvs = MEM_mallocN(sizeof(float) * 2 * max_vert_count, "face uvs"); + + BMO_ITER(fs, &fs_iter, bm, op, "faces", BM_FACE) { + if( CustomData_has_layer(&(bm->ldata), CD_MLOOPUV) ) { + BMLoop *lf; /* current face loops */ + MLoopUV *f_luv; /* first face loop uv */ + int num_verts = fs->len; + int i = 0; + BM_ITER(lf, &l_iter, bm, BM_LOOPS_OF_FACE, fs) { + /* current loop uv is the previous loop uv */ + MLoopUV *luv = CustomData_bmesh_get(&bm->ldata, lf->head.data, CD_MLOOPUV); + uvs[i * 2] = luv->uv[0]; + uvs[i * 2 + 1] = luv->uv[1]; + i++; + } + + /* now that we have the uvs in the array, reverse! */ + i = 0; + BM_ITER(lf, &l_iter, bm, BM_LOOPS_OF_FACE, fs) { + /* current loop uv is the previous loop uv */ + MLoopUV *luv = CustomData_bmesh_get(&bm->ldata, lf->head.data, CD_MLOOPUV); + luv->uv[0] = uvs[(fs->len - i - 1) * 2]; + luv->uv[1] = uvs[(fs->len - i - 1) * 2 + 1]; + i++; + } + } + } + + MEM_freeN(uvs); +} Index: source/blender/editors/mesh/mesh_ops.c =================================================================== --- source/blender/editors/mesh/mesh_ops.c (revision 23029) +++ source/blender/editors/mesh/mesh_ops.c (working copy) @@ -168,7 +168,8 @@ // uiItemS(layout); uiItemMenuEnumO(layout, NULL, 0, "MESH_OT_uvs_rotate", "direction"); - uiItemMenuEnumO(layout, NULL, 0, "MESH_OT_uvs_mirror", "axis"); + //uiItemMenuEnumO(layout, NULL, 0, "MESH_OT_uvs_mirror", "axis"); + uiItemO(layout, NULL, 0, "MESH_OT_uvs_reverse"); uiItemMenuEnumO(layout, NULL, 0, "MESH_OT_colors_rotate", "direction"); uiItemMenuEnumO(layout, NULL, 0, "MESH_OT_colors_mirror", "axis"); @@ -283,7 +284,8 @@ WM_operatortype_append(MESH_OT_region_to_loop); WM_operatortype_append(MESH_OT_uvs_rotate); - WM_operatortype_append(MESH_OT_uvs_mirror); + //WM_operatortype_append(MESH_OT_uvs_mirror); + WM_operatortype_append(MESH_OT_uvs_reverse); WM_operatortype_append(MESH_OT_colors_rotate); WM_operatortype_append(MESH_OT_colors_mirror); @@ -426,7 +428,8 @@ WM_keymap_add_item(keymap, "MESH_OT_region_to_loop",SIXKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "MESH_OT_uvs_rotate",SEVENKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_add_item(keymap, "MESH_OT_uvs_mirror",SEVENKEY, KM_PRESS, KM_ALT, 0); + //WM_keymap_add_item(keymap, "MESH_OT_uvs_mirror",SEVENKEY, KM_PRESS, KM_ALT, 0); + WM_keymap_add_item(keymap, "MESH_OT_uvs_reverse",SEVENKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "MESH_OT_colors_rotate",EIGHTKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "MESH_OT_colors_mirror",EIGHTKEY, KM_PRESS, KM_ALT, 0); Index: source/blender/editors/mesh/bmesh_tools.c =================================================================== --- source/blender/editors/mesh/bmesh_tools.c (revision 23029) +++ source/blender/editors/mesh/bmesh_tools.c (working copy) @@ -2095,82 +2095,31 @@ /* we succeeded */ return OPERATOR_FINISHED; -#if 0 - Scene *scene= CTX_data_scene(C); - Object *obedit= CTX_data_edit_object(C); - EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data); +} - EditFace *efa; - short change = 0; - MTFace *tf; - float u1, v1; - int dir= RNA_enum_get(op->ptr, "direction"); +static int mesh_reverse_uvs(bContext *C, wmOperator *op) +{ + Scene *scene = CTX_data_scene(C); + Object *ob = CTX_data_edit_object(C); + BMEditMesh *em = ((Mesh*)ob->data)->edit_btmesh; + BMOperator bmop; - if (!EM_texFaceCheck(em)) { - BKE_report(op->reports, RPT_ERROR, "Mesh has no uv/image layers."); - BKE_mesh_end_editmesh(obedit->data, em); - return OPERATOR_CANCELLED; - } + /* initialize the bmop using EDBM api, which does various ui error reporting and other stuff */ + EDBM_InitOpf(em, &bmop, op, "meshreverseuvs faces=%hf", BM_SELECT); - for(efa=em->faces.first; efa; efa=efa->next) { - if (efa->f & SELECT) { - tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); - u1= tf->uv[0][0]; - v1= tf->uv[0][1]; + /* execute the operator */ + BMO_Exec_Op(em->bm, &bmop); - if (dir == DIRECTION_CCW) { - if(efa->v4) { - tf->uv[0][0]= tf->uv[3][0]; - tf->uv[0][1]= tf->uv[3][1]; - - tf->uv[3][0]= tf->uv[2][0]; - tf->uv[3][1]= tf->uv[2][1]; - } else { - tf->uv[0][0]= tf->uv[2][0]; - tf->uv[0][1]= tf->uv[2][1]; - } - - tf->uv[2][0]= tf->uv[1][0]; - tf->uv[2][1]= tf->uv[1][1]; - - tf->uv[1][0]= u1; - tf->uv[1][1]= v1; - } else { - tf->uv[0][0]= tf->uv[1][0]; - tf->uv[0][1]= tf->uv[1][1]; - - tf->uv[1][0]= tf->uv[2][0]; - tf->uv[1][1]= tf->uv[2][1]; - - if(efa->v4) { - tf->uv[2][0]= tf->uv[3][0]; - tf->uv[2][1]= tf->uv[3][1]; - - tf->uv[3][0]= u1; - tf->uv[3][1]= v1; - } - else { - tf->uv[2][0]= u1; - tf->uv[2][1]= v1; - } - } - change = 1; - } - } - - BKE_mesh_end_editmesh(obedit->data, em); - - if(!change) + /* finish the operator */ + if( !EDBM_FinishOp(em, &bmop, op, 1) ) return OPERATOR_CANCELLED; - DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); -#endif - return OPERATOR_FINISHED; -} + /* dependencies graph and notification stuff */ + DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT | ND_GEOM_SELECT, ob); -static int mesh_mirror_uvs(bContext *C, wmOperator *op) -{ + /* we succeeded */ + return OPERATOR_FINISHED; #if 0 Scene *scene= CTX_data_scene(C); Object *obedit= CTX_data_edit_object(C); @@ -2258,7 +2207,6 @@ WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); #endif - return OPERATOR_FINISHED; } static int mesh_rotate_colors(bContext *C, wmOperator *op) @@ -2396,21 +2344,22 @@ RNA_def_enum(ot->srna, "direction", direction_items, DIRECTION_CW, "Direction", "Direction to rotate UVs around."); } -void MESH_OT_uvs_mirror(wmOperatorType *ot) +//void MESH_OT_uvs_mirror(wmOperatorType *ot) +void MESH_OT_uvs_reverse(wmOperatorType *ot) { /* identifiers */ - ot->name= "Mirror UVs"; - ot->idname= "MESH_OT_uvs_mirror"; + ot->name= "Reverse UVs"; + ot->idname= "MESH_OT_uvs_reverse"; /* api callbacks */ - ot->exec= mesh_mirror_uvs; + ot->exec= mesh_reverse_uvs; ot->poll= ED_operator_editmesh; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* props */ - RNA_def_enum(ot->srna, "axis", axis_items, DIRECTION_CW, "Axis", "Axis to mirror UVs around."); + //RNA_def_enum(ot->srna, "axis", axis_items, DIRECTION_CW, "Axis", "Axis to mirror UVs around."); } void MESH_OT_colors_rotate(wmOperatorType *ot) Index: source/blender/editors/mesh/mesh_intern.h =================================================================== --- source/blender/editors/mesh/mesh_intern.h (revision 23029) +++ source/blender/editors/mesh/mesh_intern.h (working copy) @@ -276,7 +276,8 @@ void MESH_OT_region_to_loop(struct wmOperatorType *ot); void MESH_OT_uvs_rotate(struct wmOperatorType *ot); -void MESH_OT_uvs_mirror(struct wmOperatorType *ot); +//void MESH_OT_uvs_mirror(struct wmOperatorType *ot); +void MESH_OT_uvs_reverse(struct wmOperatorType *ot); void MESH_OT_colors_rotate(struct wmOperatorType *ot); void MESH_OT_colors_mirror(struct wmOperatorType *ot);