merge with trunk at r31523
[blender.git] / source / blender / editors / uvedit / uvedit_ops.c
index c2918f0faaea24f3389de3513df7d65592303717..946428d9baf5bcdd8e9fbf7b49abaf9d151c0df0 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 #include <math.h>
+#include <string.h>
 
 #include "MEM_guardedalloc.h"
 
 #include "DNA_object_types.h"
 #include "DNA_meshdata_types.h"
+#include "DNA_image_types.h"
+#include "DNA_space_types.h"
 #include "DNA_scene_types.h"
 
 #include "BLI_math.h"
 #include "BLI_blenlib.h"
 #include "BLI_editVert.h"
+#include "BLI_array.h"
 
 #include "BKE_context.h"
 #include "BKE_customdata.h"
@@ -48,6 +52,7 @@
 #include "BKE_library.h"
 #include "BKE_mesh.h"
 #include "BKE_report.h"
+#include "BKE_tessmesh.h"
 
 #include "ED_image.h"
 #include "ED_mesh.h"
 
 #include "uvedit_intern.h"
 
+#define EFA_F1_FLAG    2
+
 /************************* state testing ************************/
 
 int ED_uvedit_test(Object *obedit)
 {
-       EditMesh *em;
+       BMEditMesh *em;
        int ret;
 
-       if(!obedit || obedit->type != OB_MESH)
+       if(obedit->type != OB_MESH)
                return 0;
 
-       em = BKE_mesh_get_editmesh(obedit->data);
-       ret = EM_texFaceCheck(em);
-       BKE_mesh_end_editmesh(obedit->data, em);
+       em = ((Mesh*)obedit->data)->edit_btmesh;
+       ret = EDBM_texFaceCheck(em);
        
        return ret;
 }
@@ -86,9 +92,10 @@ int ED_uvedit_test(Object *obedit)
 
 void ED_uvedit_assign_image(Scene *scene, Object *obedit, Image *ima, Image *previma)
 {
-       EditMesh *em;
-       EditFace *efa;
-       MTFace *tf;
+       BMEditMesh *em;
+       BMFace *efa;
+       BMIter iter;
+       MTexPoly *tf;
        int update= 0;
        
        /* skip assigning these procedural images... */
@@ -99,21 +106,21 @@ void ED_uvedit_assign_image(Scene *scene, Object *obedit, Image *ima, Image *pre
        if(!obedit || (obedit->type != OB_MESH))
                return;
 
-       em= BKE_mesh_get_editmesh(((Mesh*)obedit->data));
-       if(!em || !em->faces.first) {
-               BKE_mesh_end_editmesh(obedit->data, em);
+       em= ((Mesh*)obedit->data)->edit_btmesh;
+       if(!em || !em->bm->totface) {
                return;
        }
        
        /* ensure we have a uv layer */
-       if(!CustomData_has_layer(&em->fdata, CD_MTFACE)) {
-               EM_add_data_layer(em, &em->fdata, CD_MTFACE);
+       if(!CustomData_has_layer(&em->bm->pdata, CD_MTEXPOLY)) {
+               BM_add_data_layer(em->bm, &em->bm->pdata, CD_MTEXPOLY);
+               BM_add_data_layer(em->bm, &em->bm->ldata, CD_MLOOPUV);
                update= 1;
        }
 
        /* now assign to all visible faces */
-       for(efa= em->faces.first; efa; efa= efa->next) {
-               tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+       BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+               tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
 
                if(uvedit_face_visible(scene, previma, efa, tf)) {
                        if(ima) {
@@ -135,17 +142,16 @@ void ED_uvedit_assign_image(Scene *scene, Object *obedit, Image *ima, Image *pre
        /* and update depdency graph */
        if(update)
                DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
-
-       BKE_mesh_end_editmesh(obedit->data, em);
 }
 
 /* dotile -    1, set the tile flag (from the space image)
  *                     2, set the tile index for the faces. */
 void ED_uvedit_set_tile(bContext *C, Scene *scene, Object *obedit, Image *ima, int curtile)
 {
-       EditMesh *em;
-       EditFace *efa;
-       MTFace *tf;
+       BMEditMesh *em;
+       BMFace *efa;
+       BMIter iter;
+       MTexPoly *tf;
        
        /* verify if we have something to do */
        if(!ima || !ED_uvedit_test(obedit))
@@ -155,18 +161,17 @@ void ED_uvedit_set_tile(bContext *C, Scene *scene, Object *obedit, Image *ima, i
        if(ima->type==IMA_TYPE_R_RESULT || ima->type==IMA_TYPE_COMPOSITE)
                return;
        
-       em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
+       em= ((Mesh*)obedit->data)->edit_btmesh;
 
-       for(efa= em->faces.first; efa; efa= efa->next) {
-               tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+       BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+               tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
 
-               if(efa->h==0 && efa->f & SELECT)
+               if(!BM_TestHFlag(efa, BM_HIDDEN) && BM_TestHFlag(efa, BM_SELECT))
                        tf->tile= curtile; /* set tile index */
        }
 
        DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
-       BKE_mesh_end_editmesh(obedit->data, em);
 }
 
 /*********************** space conversion *********************/
@@ -175,13 +180,7 @@ static void uvedit_pixel_to_float(SpaceImage *sima, float *dist, float pixeldist
 {
        int width, height;
 
-       if(sima) {
-               ED_space_image_size(sima, &width, &height);
-       }
-       else {
-               width= 256;
-               height= 256;
-       }
+       ED_space_image_size(sima, &width, &height);
 
        dist[0]= pixeldist/width;
        dist[1]= pixeldist/height;
@@ -189,18 +188,17 @@ static void uvedit_pixel_to_float(SpaceImage *sima, float *dist, float pixeldist
 
 /*************** visibility and selection utilities **************/
 
-int uvedit_face_visible_nolocal(Scene *scene, EditFace *efa)
+int uvedit_face_visible_nolocal(Scene *scene, BMFace *efa)
 {
        ToolSettings *ts= scene->toolsettings;
 
        if(ts->uv_flag & UV_SYNC_SELECTION)
-               return (efa->h==0);
+               return (BM_TestHFlag(efa, BM_HIDDEN)==0);
        else
-               return (efa->h==0 && (efa->f & SELECT));
+               return (BM_TestHFlag(efa, BM_HIDDEN)==0 && BM_TestHFlag(efa, BM_SELECT));
 }
 
-int uvedit_face_visible(Scene *scene, Image *ima, EditFace *efa, MTFace *tf)
-{
+int uvedit_face_visible(Scene *scene, Image *ima, BMFace *efa, MTexPoly *tf) {
        ToolSettings *ts= scene->toolsettings;
 
        if(ts->uv_flag & UV_SHOW_SAME_IMAGE)
@@ -209,134 +207,216 @@ int uvedit_face_visible(Scene *scene, Image *ima, EditFace *efa, MTFace *tf)
                return uvedit_face_visible_nolocal(scene, efa);
 }
 
-int uvedit_face_selected(Scene *scene, EditFace *efa, MTFace *tf)
+int uvedit_face_selected(Scene *scene, BMEditMesh *em, BMFace *efa)
 {
        ToolSettings *ts= scene->toolsettings;
 
        if(ts->uv_flag & UV_SYNC_SELECTION)
-               return (efa->f & SELECT);
-       else
-               return (!(~tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3)) &&(!efa->v4 || tf->flag & TF_SEL4));
+               return (BM_TestHFlag(efa, BM_SELECT));
+       else {
+               BMLoop *l;
+               MLoopUV *luv;
+               BMIter liter;
+
+               BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                       luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+                       if (!(luv->flag & MLOOPUV_VERTSEL))
+                               return 0;
+               }
+
+               return 1;
+       }
 }
 
-void uvedit_face_select(Scene *scene, EditFace *efa, MTFace *tf)
+int uvedit_face_select(Scene *scene, BMEditMesh *em, BMFace *efa)
 {
        ToolSettings *ts= scene->toolsettings;
 
        if(ts->uv_flag & UV_SYNC_SELECTION)
-               EM_select_face(efa, 1);
-       else
-               tf->flag |= (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
+               BM_Select(em->bm, efa, 1);
+       else {
+               BMLoop *l;
+               MLoopUV *luv;
+               BMIter liter;
+
+               BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                       luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+                       luv->flag |= MLOOPUV_VERTSEL;
+               }
+
+               return 1;
+       }
+
+       return 0;
 }
 
-void uvedit_face_deselect(Scene *scene, EditFace *efa, MTFace *tf)
+int uvedit_face_deselect(Scene *scene, BMEditMesh *em, BMFace *efa)
 {
        ToolSettings *ts= scene->toolsettings;
 
        if(ts->uv_flag & UV_SYNC_SELECTION)
-               EM_select_face(efa, 0);
-       else
-               tf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
+               BM_Select(em->bm, efa, 0);
+       else {
+               BMLoop *l;
+               MLoopUV *luv;
+               BMIter liter;
+
+               BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                       luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+                       luv->flag &= ~MLOOPUV_VERTSEL;
+               }
+
+               return 1;
+       }
+
+       return 0;
 }
 
-int uvedit_edge_selected(Scene *scene, EditFace *efa, MTFace *tf, int i)
+int uvedit_edge_selected(BMEditMesh *em, Scene *scene, BMLoop *l)
 {
        ToolSettings *ts= scene->toolsettings;
-       int nvert= (efa->v4)? 4: 3;
 
        if(ts->uv_flag & UV_SYNC_SELECTION) {
                if(ts->selectmode == SCE_SELECT_FACE)
-                       return (efa->f & SELECT);
-               else if(ts->selectmode == SCE_SELECT_EDGE)
-                       return (*(&efa->e1 + i))->f & SELECT;
-               else
-                       return (((efa->v1 + i)->f & SELECT) && ((efa->v1 + (i+1)%nvert)->f & SELECT));
+                       return BM_TestHFlag(l->f, BM_SELECT);
+               else if(ts->selectmode == SCE_SELECT_EDGE) {
+                       return BM_TestHFlag(l->e, BM_SELECT);
+               } else
+                       return BM_TestHFlag(l->v, BM_SELECT) && 
+                              BM_TestHFlag(((BMLoop*)l->next)->v, BM_SELECT);
+       }
+       else {
+               MLoopUV *luv1, *luv2;
+
+               luv1 = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+               luv2 = CustomData_bmesh_get(&em->bm->ldata, l->next->head.data, CD_MLOOPUV);
+
+               return (luv1->flag & MLOOPUV_VERTSEL) && (luv2->flag & MLOOPUV_VERTSEL);
        }
-       else
-               return (tf->flag & TF_SEL_MASK(i)) && (tf->flag & TF_SEL_MASK((i+1)%nvert));
 }
 
-void uvedit_edge_select(Scene *scene, EditFace *efa, MTFace *tf, int i)
+void uvedit_edge_select(BMEditMesh *em, Scene *scene, BMLoop *l)
+
 {
        ToolSettings *ts= scene->toolsettings;
-       int nvert= (efa->v4)? 4: 3;
 
        if(ts->uv_flag & UV_SYNC_SELECTION) {
                if(ts->selectmode == SCE_SELECT_FACE)
-                       EM_select_face(efa, 1);
+                       BM_Select(em->bm, l->f, 1);
                else if(ts->selectmode == SCE_SELECT_EDGE)
-                       EM_select_edge((*(&efa->e1 + i)), 1);
+                       BM_Select(em->bm, l->e, 1);
                else {
-                       (efa->v1 + i)->f |= SELECT;
-                       (efa->v1 + (i+1)%nvert)->f |= SELECT;
+                       BM_Select(em->bm, l->e->v1, 1);
+                       BM_Select(em->bm, l->e->v2, 1);
                }
        }
-       else
-               tf->flag |= TF_SEL_MASK(i)|TF_SEL_MASK((i+1)%nvert);
+       else {
+               MLoopUV *luv1, *luv2;
+
+               luv1 = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+               luv2 = CustomData_bmesh_get(&em->bm->ldata, l->next->head.data, CD_MLOOPUV);
+               
+               luv1->flag |= MLOOPUV_VERTSEL;
+               luv2->flag |= MLOOPUV_VERTSEL;
+       }
 }
 
-void uvedit_edge_deselect(Scene *scene, EditFace *efa, MTFace *tf, int i)
+void uvedit_edge_deselect(BMEditMesh *em, Scene *scene, BMLoop *l)
+
 {
        ToolSettings *ts= scene->toolsettings;
-       int nvert= (efa->v4)? 4: 3;
 
        if(ts->uv_flag & UV_SYNC_SELECTION) {
                if(ts->selectmode == SCE_SELECT_FACE)
-                       EM_select_face(efa, 0);
+                       BM_Select(em->bm, l->f, 0);
                else if(ts->selectmode == SCE_SELECT_EDGE)
-                       EM_select_edge((*(&efa->e1 + i)), 0);
+                       BM_Select(em->bm, l->e, 0);
                else {
-                       (efa->v1 + i)->f &= ~SELECT;
-                       (efa->v1 + (i+1)%nvert)->f &= ~SELECT;
+                       BM_Select(em->bm, l->e->v1, 0);
+                       BM_Select(em->bm, l->e->v2, 0);
                }
        }
-       else
-               tf->flag &= ~(TF_SEL_MASK(i)|TF_SEL_MASK((i+1)%nvert));
+       else {
+               MLoopUV *luv1, *luv2;
+
+               luv1 = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+               luv2 = CustomData_bmesh_get(&em->bm->ldata, l->next->head.data, CD_MLOOPUV);
+               
+               luv1->flag &= ~MLOOPUV_VERTSEL;
+               luv2->flag &= ~MLOOPUV_VERTSEL;
+       }
 }
 
-int uvedit_uv_selected(Scene *scene, EditFace *efa, MTFace *tf, int i)
+int uvedit_uv_selected(BMEditMesh *em, Scene *scene, BMLoop *l)
 {
        ToolSettings *ts= scene->toolsettings;
 
        if(ts->uv_flag & UV_SYNC_SELECTION) {
                if(ts->selectmode == SCE_SELECT_FACE)
-                       return (efa->f & SELECT);
+                       return BM_TestHFlag(l->f, BM_SELECT);
                else
-                       return (*(&efa->v1 + i))->f & SELECT;
+                       return BM_TestHFlag(l, BM_SELECT);
+       }
+       else {
+               MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+
+               return luv->flag & MLOOPUV_VERTSEL;
        }
-       else
-               return tf->flag & TF_SEL_MASK(i);
 }
 
-void uvedit_uv_select(Scene *scene, EditFace *efa, MTFace *tf, int i)
+void uvedit_uv_select(BMEditMesh *em, Scene *scene, BMLoop *l)
 {
        ToolSettings *ts= scene->toolsettings;
 
        if(ts->uv_flag & UV_SYNC_SELECTION) {
                if(ts->selectmode == SCE_SELECT_FACE)
-                       EM_select_face(efa, 1);
+                       BM_Select(em->bm, l->f, 1);
                else
-                       (*(&efa->v1 + i))->f |= SELECT;
+                       BM_Select(em->bm, l->v, 1);
+       }
+       else {
+               MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+               
+               luv->flag |= MLOOPUV_VERTSEL;
        }
-       else
-               tf->flag |= TF_SEL_MASK(i);
 }
 
-void uvedit_uv_deselect(Scene *scene, EditFace *efa, MTFace *tf, int i)
+void uvedit_uv_deselect(BMEditMesh *em, Scene *scene, BMLoop *l)
 {
        ToolSettings *ts= scene->toolsettings;
 
        if(ts->uv_flag & UV_SYNC_SELECTION) {
                if(ts->selectmode == SCE_SELECT_FACE)
-                       EM_select_face(efa, 0);
+                       BM_Select(em->bm, l->f, 0);
                else
-                       (*(&efa->v1 + i))->f &= ~SELECT;
+                       BM_Select(em->bm, l->v, 0);
+       }
+       else {
+               MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+               
+               luv->flag &= ~MLOOPUV_VERTSEL;
        }
-       else
-               tf->flag &= ~TF_SEL_MASK(i);
 }
 
 /*********************** geometric utilities ***********************/
+void poly_uv_center(BMEditMesh *em, BMFace *f, float cent[2])
+{
+       BMLoop *l;
+       MLoopUV *luv;
+       BMIter liter;
+
+       cent[0] = cent[1] = 0.0f;
+
+       BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, f) {
+               luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+               cent[0] += luv->uv[0];
+               cent[1] += luv->uv[1];
+       }
+
+       cent[0] /= (float) f->len;
+       cent[1] /= (float) f->len;
+}
+
 
 void uv_center(float uv[][2], float cent[2], int quad)
 {
@@ -358,6 +438,28 @@ float uv_area(float uv[][2], int quad)
                return area_tri_v2(uv[0], uv[1], uv[2]); 
 }
 
+float poly_uv_area(float uv[][2], int len)
+{
+       //BMESH_TODO: make this not suck
+       //maybe use scanfill? I dunno.
+
+       if(len >= 4)
+               return area_tri_v2(uv[0], uv[1], uv[2]) + area_tri_v2(uv[0], uv[2], uv[3]); 
+       else
+               return area_tri_v2(uv[0], uv[1], uv[2]); 
+
+       return 1.0;
+}
+
+void poly_copy_aspect(float uv_orig[][2], float uv[][2], float aspx, float aspy, int len)
+{
+       int i;
+       for (i=0; i<len; i++) {
+               uv[i][0] = uv_orig[i][0]*aspx;
+               uv[i][1] = uv_orig[i][1]*aspy;
+       }
+}
+
 void uv_copy_aspect(float uv_orig[][2], float uv[][2], float aspx, float aspy)
 {
        uv[0][0] = uv_orig[0][0]*aspx;
@@ -375,33 +477,42 @@ void uv_copy_aspect(float uv_orig[][2], float uv[][2], float aspx, float aspy)
 
 int ED_uvedit_minmax(Scene *scene, Image *ima, Object *obedit, float *min, float *max)
 {
-       EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
-       EditFace *efa;
-       MTFace *tf;
+       BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh;
+       BMFace *efa;
+       BMLoop *l;
+       BMIter iter, liter;
+       MTexPoly *tf;
+       MLoopUV *luv;
        int sel;
 
        INIT_MINMAX2(min, max);
 
        sel= 0;
-       for(efa= em->faces.first; efa; efa= efa->next) {
-               tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-               if(uvedit_face_visible(scene, ima, efa, tf)) {
-                       if(uvedit_uv_selected(scene, efa, tf, 0))                               { DO_MINMAX2(tf->uv[0], min, max); sel = 1; }
-                       if(uvedit_uv_selected(scene, efa, tf, 1))                               { DO_MINMAX2(tf->uv[1], min, max); sel = 1; }
-                       if(uvedit_uv_selected(scene, efa, tf, 2))                               { DO_MINMAX2(tf->uv[2], min, max); sel = 1; }
-                       if(efa->v4 && (uvedit_uv_selected(scene, efa, tf, 3)))  { DO_MINMAX2(tf->uv[3], min, max); sel = 1; }
-               }
+       BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+               tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+               if(!uvedit_face_visible(scene, ima, efa, tf))
+                       continue;
+               
+               BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                       if (uvedit_uv_selected(em, scene, l)) 
+                               luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+                               DO_MINMAX2(luv->uv, min, max); 
+                               sel = 1;
+                       }
        }
-       
-       BKE_mesh_end_editmesh(obedit->data, em);
+
        return sel;
 }
 
-int uvedit_center(Scene *scene, Image *ima, Object *obedit, float *cent, int mode)
+int uvedit_center(Scene *scene, Image *ima, Object *obedit, 
+                 float *cent, int mode)
 {
-       EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
-       EditFace *efa;
-       MTFace *tf;
+       BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh;
+       BMFace *efa;
+       BMLoop *l;
+       BMIter iter, liter;
+       MTexPoly *tf;
+       MLoopUV *luv;
        float min[2], max[2];
        int change= 0;
        
@@ -412,14 +523,18 @@ int uvedit_center(Scene *scene, Image *ima, Object *obedit, float *cent, int mod
        else if(mode==1) {
                INIT_MINMAX2(min, max);
                
-               for(efa= em->faces.first; efa; efa= efa->next) {
-                       tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-
-                       if(uvedit_face_visible(scene, ima, efa, tf)) {
-                               if(uvedit_uv_selected(scene, efa, tf, 0))                               { DO_MINMAX2(tf->uv[0], min, max);      change= 1;}
-                               if(uvedit_uv_selected(scene, efa, tf, 1))                               { DO_MINMAX2(tf->uv[1], min, max);      change= 1;}
-                               if(uvedit_uv_selected(scene, efa, tf, 2))                               { DO_MINMAX2(tf->uv[2], min, max);      change= 1;}
-                               if(efa->v4 && (uvedit_uv_selected(scene, efa, tf, 3)))  { DO_MINMAX2(tf->uv[3], min, max);      change= 1;}
+               BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+                       tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+                       if(!uvedit_face_visible(scene, ima, efa, tf))
+                               continue;
+                       
+                       BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                               if (uvedit_uv_selected(em, scene, l)) {
+                                       luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+       
+                                       DO_MINMAX2(luv->uv, min, max); 
+                                       change= 1;
+                               }
                        }
                }
        }
@@ -428,108 +543,147 @@ int uvedit_center(Scene *scene, Image *ima, Object *obedit, float *cent, int mod
                cent[0]= (min[0]+max[0])/2.0;
                cent[1]= (min[1]+max[1])/2.0;
                
-               BKE_mesh_end_editmesh(obedit->data, em);
                return 1;
        }
 
-       BKE_mesh_end_editmesh(obedit->data, em);
        return 0;
 }
 
 /************************** find nearest ****************************/
 
 typedef struct NearestHit {
-       EditFace *efa;
-       MTFace *tf;
-
-       int vert, uv;
-       int edge, vert2;
+       BMFace *efa;
+       MTexPoly *tf;
+       BMLoop *l, *nextl;
+       MLoopUV *luv, *nextluv;
+       int lindex; //index of loop within face
+       int vert1, vert2; //index in mesh of edge vertices
 } NearestHit;
 
-static void find_nearest_uv_edge(Scene *scene, Image *ima, EditMesh *em, float co[2], NearestHit *hit)
+static void find_nearest_uv_edge(Scene *scene, Image *ima, BMEditMesh *em, float co[2], NearestHit *hit)
 {
-       MTFace *tf;
-       EditFace *efa;
-       EditVert *eve;
+       MTexPoly *tf;
+       BMFace *efa;
+       BMLoop *l;
+       BMVert *eve;
+       BMIter iter, liter;
+       MLoopUV *luv, *nextluv;
        float mindist, dist;
-       int i, nverts;
+       int i;
 
        mindist= 1e10f;
        memset(hit, 0, sizeof(*hit));
 
-       for(i=0, eve=em->verts.first; eve; eve=eve->next, i++)
-               eve->tmp.l = i;
+       eve = BMIter_New(&iter, em->bm, BM_VERTS_OF_MESH, NULL);
+       for (i=0; eve; eve=BMIter_Step(&iter), i++) {
+               BMINDEX_SET(eve, i);
+       }
        
-       for(efa= em->faces.first; efa; efa= efa->next) {
-               tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-
-               if(uvedit_face_visible(scene, ima, efa, tf)) {
-                       nverts= efa->v4? 4: 3;
+       BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+               tf= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+               if(!uvedit_face_visible(scene, ima, efa, tf))
+                       continue;
+               
+               i = 0;
+               BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                       luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+                       nextluv = CustomData_bmesh_get(&em->bm->ldata, l->next->head.data, CD_MLOOPUV);
 
-                       for(i=0; i<nverts; i++) {
-                               dist= dist_to_line_segment_v2(co, tf->uv[i], tf->uv[(i+1)%nverts]);
+                       dist= dist_to_line_segment_v2(co, luv->uv, nextluv->uv);
 
-                               if(dist < mindist) {
-                                       hit->tf= tf;
-                                       hit->efa= efa;
-                                       hit->edge= i;
-                                       mindist= dist;
+                       if(dist < mindist) {
+                               hit->tf= tf;
+                               hit->efa= efa;
+                               
+                               hit->l = l;
+                               hit->nextl = (BMLoop*)l->next;
+                               hit->luv = luv;
+                               hit->nextluv = nextluv;
+                               hit->lindex = i;
+                               hit->vert1 = BMINDEX_GET(hit->l->v);
+                               hit->vert2 = BMINDEX_GET(((BMLoop*)hit->l->next)->v);
 
-                                       hit->vert= (*(&efa->v1 + i))->tmp.l;
-                                       hit->vert2= (*(&efa->v1 + ((i+1)%nverts)))->tmp.l;
-                               }
+                               mindist = dist;
                        }
+
+                       i++;
                }
        }
 }
 
-static void find_nearest_uv_face(Scene *scene, Image *ima, EditMesh *em, float co[2], NearestHit *hit)
+static void find_nearest_uv_face(Scene *scene, Image *ima, BMEditMesh *em, float co[2], NearestHit *hit)
 {
-       MTFace *tf;
-       EditFace *efa;
+       MTexPoly *tf;
+       BMFace *efa;
+       BMLoop *l;
+       BMIter iter, liter;
+       MLoopUV *luv;
        float mindist, dist, cent[2];
-       int i, nverts;
 
        mindist= 1e10f;
        memset(hit, 0, sizeof(*hit));
-       
-       for(efa= em->faces.first; efa; efa= efa->next) {
-               tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
 
-               if(uvedit_face_visible(scene, ima, efa, tf)) {
-                       nverts= efa->v4? 4: 3;
-                       cent[0]= cent[1]= 0.0f;
+       /*this will fill in hit.vert1 and hit.vert2*/
+       find_nearest_uv_edge(scene, ima, em, co, hit);
+       hit->l = hit->nextl = NULL;
+       hit->luv = hit->nextluv = NULL;
 
-                       for(i=0; i<nverts; i++) {
-                               cent[0] += tf->uv[i][0];
-                               cent[1] += tf->uv[i][1];
-                       }
+       BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+               tf= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+               if(!uvedit_face_visible(scene, ima, efa, tf))
+                       continue;
+               
+               cent[0]= cent[1]= 0.0f;
+               BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                       luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
 
-                       cent[0] /= nverts;
-                       cent[1] /= nverts;
-                       dist= fabs(co[0]- cent[0]) + fabs(co[1]- cent[1]);
+                       cent[0] += luv->uv[0];
+                       cent[1] += luv->uv[1];
+               }
 
-                       if(dist < mindist) {
-                               hit->tf= tf;
-                               hit->efa= efa;
-                               mindist= dist;
-                       }
+               cent[0] /= efa->len;
+               cent[1] /= efa->len;
+               dist= fabs(co[0]- cent[0]) + fabs(co[1]- cent[1]);
+
+               if(dist < mindist) {
+                       hit->tf= tf;
+                       hit->efa= efa;
+                       mindist= dist;
                }
        }
 }
 
-static int nearest_uv_between(MTFace *tf, int nverts, int id, float co[2], float uv[2])
+static int nearest_uv_between(BMEditMesh *em, BMFace *efa, int nverts, int id, 
+                             float co[2], float uv[2])
 {
-       float m[3], v1[3], v2[3], c1, c2;
-       int id1, id2;
+       BMLoop *l;
+       MLoopUV *luv;
+       BMIter iter;
+       float m[3], v1[3], v2[3], c1, c2, *uv1, *uv2, *uv3;
+       int id1, id2, i;
 
-       id1= (id+nverts-1)%nverts;
-       id2= (id+nverts+1)%nverts;
+       id1= (id+efa->len-1)%efa->len;
+       id2= (id+efa->len+1)%efa->len;
 
        m[0]= co[0]-uv[0];
        m[1]= co[1]-uv[1];
-       sub_v2_v2v2(v1, tf->uv[id1], tf->uv[id]);
-       sub_v2_v2v2(v2, tf->uv[id2], tf->uv[id]);
+
+       i = 0;
+       BM_ITER(l, &iter, em->bm, BM_LOOPS_OF_FACE, efa) {
+               luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+               
+               if (i == id1)
+                       uv1 = luv->uv;
+               else if (i == id)
+                       uv2 = luv->uv;
+               else if (i == id2)
+                       uv3 = luv->uv;
+
+               i++;
+       }
+
+       sub_v3_v3v3(v1, uv1, uv);
+       sub_v3_v3v3(v2, uv3, uv);
 
        /* m and v2 on same side of v-v1? */
        c1= v1[0]*m[1] - v1[1]*m[0];
@@ -545,83 +699,103 @@ static int nearest_uv_between(MTFace *tf, int nverts, int id, float co[2], float
        return (c1*c2 >= 0.0f);
 }
 
-static void find_nearest_uv_vert(Scene *scene, Image *ima, EditMesh *em, float co[2], float penalty[2], NearestHit *hit)
+static void find_nearest_uv_vert(Scene *scene, Image *ima, BMEditMesh *em, 
+                                float co[2], float penalty[2], NearestHit *hit)
 {
-       EditFace *efa;
-       EditVert *eve;
-       MTFace *tf;
+       BMFace *efa;
+       BMVert *eve;
+       BMLoop *l;
+       BMIter iter, liter;
+       MTexPoly *tf;
+       MLoopUV *luv;
        float mindist, dist;
        int i, nverts;
 
+       /*this will fill in hit.vert1 and hit.vert2*/
+       find_nearest_uv_edge(scene, ima, em, co, hit);
+       hit->l = hit->nextl = NULL;
+       hit->luv = hit->nextluv = NULL;
+
        mindist= 1e10f;
        memset(hit, 0, sizeof(*hit));
        
-       for(i=0, eve=em->verts.first; eve; eve=eve->next, i++)
-               eve->tmp.l = i;
-       
-       for(efa= em->faces.first; efa; efa= efa->next) {
-               tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-
-               if(uvedit_face_visible(scene, ima, efa, tf)) {
-                       nverts= efa->v4? 4: 3;
+       eve = BMIter_New(&iter, em->bm, BM_VERTS_OF_MESH, NULL);
+       for (i=0; eve; eve=BMIter_Step(&iter), i++) {
+               BMINDEX_SET(eve, i);
+       }
 
-                       for(i=0; i<nverts; i++) {
-                               if(penalty && uvedit_uv_selected(scene, efa, tf, i))
-                                       dist= fabs(co[0]-tf->uv[i][0])+penalty[0] + fabs(co[1]-tf->uv[i][1])+penalty[1];
-                               else
-                                       dist= fabs(co[0]-tf->uv[i][0]) + fabs(co[1]-tf->uv[i][1]);
+       BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+               tf= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+               if(!uvedit_face_visible(scene, ima, efa, tf))
+                       continue;
+               
+               i = 0;
+               BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                       luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
 
-                               if(dist<=mindist) {
-                                       if(dist==mindist)
-                                               if(!nearest_uv_between(tf, nverts, i, co, tf->uv[i]))
-                                                       continue;
+                       if(penalty && uvedit_uv_selected(em, scene, l))
+                               dist= fabs(co[0]-luv->uv[0])+penalty[0] + fabs(co[1]-luv->uv[1])+penalty[1];
+                       else
+                               dist= fabs(co[0]-luv->uv[0]) + fabs(co[1]-luv->uv[1]);
 
-                                       mindist= dist;
+                       if(dist<=mindist) {
+                               if(dist==mindist)
+                                       if(!nearest_uv_between(em, efa, efa->len, i, co, luv->uv)) {
+                                               i++;
+                                               continue;
+                                       }
 
-                                       hit->uv= i;
-                                       hit->tf= tf;
-                                       hit->efa= efa;
+                               mindist= dist;
 
-                                       hit->vert= (*(&efa->v1 + i))->tmp.l;
-                               }
+                               hit->l = l;
+                               hit->nextl = (BMLoop*)l->next;
+                               hit->luv = luv;
+                               hit->nextluv = CustomData_bmesh_get(&em->bm->ldata, l->next->head.data, CD_MLOOPUV);
+                               hit->tf= tf;
+                               hit->efa= efa;
+                               hit->lindex = i;
+                               hit->vert1 = BMINDEX_GET(hit->l->v);
                        }
+
+                       i++;
                }
        }
 }
 
 int ED_uvedit_nearest_uv(Scene *scene, Object *obedit, Image *ima, float co[2], float uv[2])
 {
-       EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
-       EditFace *efa;
-       MTFace *tf;
+       BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh;
+       BMFace *efa;
+       BMLoop *l;
+       BMIter iter, liter;
+       MTexPoly *tf;
+       MLoopUV *luv;
        float mindist, dist;
-       int i, nverts, found= 0;
+       int found= 0;
 
        mindist= 1e10f;
        uv[0]= co[0];
        uv[1]= co[1];
        
-       for(efa= em->faces.first; efa; efa= efa->next) {
-               tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-
-               if(uvedit_face_visible(scene, ima, efa, tf)) {
-                       nverts= efa->v4? 4: 3;
-
-                       for(i=0; i<nverts; i++) {
-                               dist= fabs(co[0]-tf->uv[i][0]) + fabs(co[1]-tf->uv[i][1]);
+       BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+               tf= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+               if(!uvedit_face_visible(scene, ima, efa, tf))
+                       continue;
+               
+               BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                       luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+                       dist= fabs(co[0]-luv->uv[0]) + fabs(co[1]-luv->uv[1]);
 
-                               if(dist<=mindist) {
-                                       mindist= dist;
+                       if(dist<=mindist) {
+                               mindist= dist;
 
-                                       uv[0]= tf->uv[i][0];
-                                       uv[1]= tf->uv[i][1];
-                                       found= 1;
-                               }
+                               uv[0]= luv->uv[0];
+                               uv[1]= luv->uv[1];
+                               found= 1;
                        }
                }
        }
 
-       BKE_mesh_end_editmesh(obedit->data, em);
        return found;
 }
 
@@ -643,26 +817,28 @@ static void uv_vertex_loop_flag(UvMapVert *first)
                first->flag= 1;
 }
 
-static UvMapVert *uv_vertex_map_get(UvVertMap *vmap, EditFace *efa, int a)
+static UvMapVert *uv_vertex_map_get(UvVertMap *vmap, BMFace *efa, int a)
 {
        UvMapVert *iterv, *first;
-       
-       first= EM_get_uv_map_vert(vmap, (*(&efa->v1 + a))->tmp.l);
+       BMLoop *l;
+
+       l = BMIter_AtIndex(NULL, BM_LOOPS_OF_FACE, efa, a);
+       first= EDBM_get_uv_map_vert(vmap,  BMINDEX_GET(l->v));
 
        for(iterv=first; iterv; iterv=iterv->next) {
                if(iterv->separate)
                        first= iterv;
-               if(iterv->f == efa->tmp.l)
+               if(iterv->f == BMINDEX_GET(efa))
                        return first;
        }
        
        return NULL;
 }
 
-static int uv_edge_tag_faces(UvMapVert *first1, UvMapVert *first2, int *totface)
+static int uv_edge_tag_faces(BMEditMesh *em, UvMapVert *first1, UvMapVert *first2, int *totface)
 {
        UvMapVert *iterv1, *iterv2;
-       EditFace *efa;
+       BMFace *efa;
        int tot = 0;
 
        /* count number of faces this edge has */
@@ -676,8 +852,8 @@ static int uv_edge_tag_faces(UvMapVert *first1, UvMapVert *first2, int *totface)
 
                        if(iterv1->f == iterv2->f) {
                                /* if face already tagged, don't do this edge */
-                               efa= EM_get_face_for_index(iterv1->f);
-                               if(efa->f1)
+                               efa= EDBM_get_face_for_index(em, iterv1->f);
+                               if(BMO_TestFlag(em->bm, efa, EFA_F1_FLAG))
                                        return 0;
 
                                tot++;
@@ -701,8 +877,8 @@ static int uv_edge_tag_faces(UvMapVert *first1, UvMapVert *first2, int *totface)
                                break;
 
                        if(iterv1->f == iterv2->f) {
-                               efa= EM_get_face_for_index(iterv1->f);
-                               efa->f1= 1;
+                               efa= EDBM_get_face_for_index(em, iterv1->f);
+                               BMO_SetFlag(em->bm, efa, EFA_F1_FLAG);
                                break;
                        }
                }
@@ -711,41 +887,47 @@ static int uv_edge_tag_faces(UvMapVert *first1, UvMapVert *first2, int *totface)
        return 1;
 }
 
-static int select_edgeloop(Scene *scene, Image *ima, EditMesh *em, NearestHit *hit, float limit[2], int extend)
+static int select_edgeloop(Scene *scene, Image *ima, BMEditMesh *em, NearestHit *hit, float limit[2], int extend)
 {
-       EditVert *eve;
-       EditFace *efa;
-       MTFace *tf;
+       BMVert *eve;
+       BMFace *efa;
+       BMIter iter, liter;
+       BMLoop *l;
+       MTexPoly *tf;
        UvVertMap *vmap;
        UvMapVert *iterv1, *iterv2;
        int a, count, looking, nverts, starttotf, select;
 
        /* setup */
-       EM_init_index_arrays(em, 0, 0, 1);
-       vmap= EM_make_uv_vert_map(em, 0, 0, limit);
+       EDBM_init_index_arrays(em, 0, 0, 1);
+       vmap= EDBM_make_uv_vert_map(em, 0, 0, limit);
 
-       for(count=0, eve=em->verts.first; eve; count++, eve= eve->next)
-               eve->tmp.l = count;
+       count = 0;
+       BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
+               BMINDEX_SET(eve, count);
+               count++;
+       }
 
-       for(count=0, efa= em->faces.first; efa; count++, efa= efa->next) {
+       count = 0;
+       BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
                if(!extend) {
-                       tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-                       uvedit_face_deselect(scene, efa, tf);
+                       uvedit_face_deselect(scene, em, efa);
                }
-
-               efa->tmp.l= count;
-               efa->f1= 0;
+               
+               BMO_ClearFlag(em->bm, efa, EFA_F1_FLAG);
+               BMINDEX_SET(efa, count);
+               count++;
        }
-       
+
        /* set flags for first face and verts */
-       nverts= (hit->efa->v4)? 4: 3;
-       iterv1= uv_vertex_map_get(vmap, hit->efa, hit->edge);
-       iterv2= uv_vertex_map_get(vmap, hit->efa, (hit->edge+1)%nverts);
+       nverts= hit->efa->len;
+       iterv1= uv_vertex_map_get(vmap, hit->efa, hit->lindex);
+       iterv2= uv_vertex_map_get(vmap, hit->efa, (hit->lindex+1)%nverts);
        uv_vertex_loop_flag(iterv1);
        uv_vertex_loop_flag(iterv2);
 
        starttotf= 0;
-       uv_edge_tag_faces(iterv1, iterv2, &starttotf);
+       uv_edge_tag_faces(em, iterv1, iterv2, &starttotf);
 
        /* sorry, first edge isnt even ok */
        if(iterv1->flag==0 && iterv2->flag==0) looking= 0;
@@ -756,21 +938,25 @@ static int select_edgeloop(Scene *scene, Image *ima, EditMesh *em, NearestHit *h
                looking= 0;
 
                /* find correct valence edges which are not tagged yet, but connect to tagged one */
-               for(efa= em->faces.first; efa; efa=efa->next) {
-                       tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
 
-                       if(!efa->f1 && uvedit_face_visible(scene, ima, efa, tf)) {
-                               nverts= (efa->v4)? 4: 3;
+               BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+                       tf= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+
+                       if(!BMO_TestFlag(em->bm, efa, EFA_F1_FLAG) && uvedit_face_visible(scene, ima, efa, tf)) {
+                               nverts= efa->len;
                                for(a=0; a<nverts; a++) {
                                        /* check face not hidden and not tagged */
                                        iterv1= uv_vertex_map_get(vmap, efa, a);
                                        iterv2= uv_vertex_map_get(vmap, efa, (a+1)%nverts);
+                                       
+                                       if (!iterv1 || !iterv2)
+                                               continue;
 
                                        /* check if vertex is tagged and has right valence */
                                        if(iterv1->flag || iterv2->flag) {
-                                               if(uv_edge_tag_faces(iterv1, iterv2, &starttotf)) {
+                                               if(uv_edge_tag_faces(em, iterv1, iterv2, &starttotf)) {
                                                        looking= 1;
-                                                       efa->f1= 1;
+                                                       BMO_SetFlag(em->bm, efa, EFA_F1_FLAG);
 
                                                        uv_vertex_loop_flag(iterv1);
                                                        uv_vertex_loop_flag(iterv2);
@@ -783,16 +969,14 @@ static int select_edgeloop(Scene *scene, Image *ima, EditMesh *em, NearestHit *h
        }
 
        /* do the actual select/deselect */
-       nverts= (hit->efa->v4)? 4: 3;
-       iterv1= uv_vertex_map_get(vmap, hit->efa, hit->edge);
-       iterv2= uv_vertex_map_get(vmap, hit->efa, (hit->edge+1)%nverts);
+       nverts= hit->efa->len;
+       iterv1= uv_vertex_map_get(vmap, hit->efa, hit->lindex);
+       iterv2= uv_vertex_map_get(vmap, hit->efa, (hit->lindex+1)%nverts);
        iterv1->flag= 1;
        iterv2->flag= 1;
 
        if(extend) {
-               tf= CustomData_em_get(&em->fdata, hit->efa->data, CD_MTFACE);
-
-               if(uvedit_uv_selected(scene, hit->efa, tf, hit->edge) && uvedit_uv_selected(scene, hit->efa, tf, hit->edge))
+               if(uvedit_uv_selected(em, scene, hit->l) && uvedit_uv_selected(em, scene, hit->l))
                        select= 0;
                else
                        select= 1;
@@ -800,81 +984,108 @@ static int select_edgeloop(Scene *scene, Image *ima, EditMesh *em, NearestHit *h
        else
                select= 1;
        
-       for(efa= em->faces.first; efa; efa=efa->next) {
-               tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+       BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+               tf= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
 
-               nverts= (efa->v4)? 4: 3;
-               for(a=0; a<nverts; a++) {
+               a = 0;
+               BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
                        iterv1= uv_vertex_map_get(vmap, efa, a);
 
                        if(iterv1->flag) {
-                               if(select) uvedit_uv_select(scene, efa, tf, a);
-                               else uvedit_uv_deselect(scene, efa, tf, a);
+                               if(select) uvedit_uv_select(em, scene, l);
+                               else uvedit_uv_deselect(em, scene, l);
                        }
+
+                       a++;
                }
        }
 
        /* cleanup */
-       EM_free_uv_vert_map(vmap);
-       EM_free_index_arrays();
+       EDBM_free_uv_vert_map(vmap);
+       EDBM_free_index_arrays(em);
 
        return (select)? 1: -1;
 }
 
 /*********************** linked select ***********************/
 
-static void select_linked(Scene *scene, Image *ima, EditMesh *em, float limit[2], NearestHit *hit, int extend)
+static void select_linked(Scene *scene, Image *ima, BMEditMesh *em, float limit[2], NearestHit *hit, int extend)
 {
-       EditFace *efa;
-       MTFace *tf;
+       BMFace *efa;
+       BMLoop *l;
+       BMIter iter, liter;
+       MTexPoly *tf;
+       MLoopUV *luv;
        UvVertMap *vmap;
        UvMapVert *vlist, *iterv, *startv;
        int a, i, nverts, stacksize= 0, *stack;
        char *flag;
 
-       EM_init_index_arrays(em, 0, 0, 1); /* we can use this too */
-       vmap= EM_make_uv_vert_map(em, 1, 0, limit);
+       EDBM_init_index_arrays(em, 0, 0, 1); /* we can use this too */
+       vmap= EDBM_make_uv_vert_map(em, 1, 1, limit);
+
        if(vmap == NULL)
                return;
 
-       stack= MEM_mallocN(sizeof(*stack) * em->totface, "UvLinkStack");
-       flag= MEM_callocN(sizeof(*flag) * em->totface, "UvLinkFlag");
+       stack= MEM_mallocN(sizeof(*stack)*em->bm->totface, "UvLinkStack");
+       flag= MEM_callocN(sizeof(*flag)*em->bm->totface, "UvLinkFlag");
 
        if(!hit) {
-               for(a=0, efa= em->faces.first; efa; efa= efa->next, a++) {
-                       tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+               a = 0;
+               BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+                       tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
 
-                       if(uvedit_face_visible(scene, ima, efa, tf)) {
-                               if(tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4)) {
-                                       stack[stacksize]= a;
-                                       stacksize++;
-                                       flag[a]= 1;
+                       if(uvedit_face_visible(scene, ima, efa, tf)) { 
+                               BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                                       luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+
+                                       if (luv->flag & MLOOPUV_VERTSEL) {
+                                               stack[stacksize]= a;
+                                               stacksize++;
+                                               flag[a]= 1;
+
+                                               break;
+                                       }
                                }
                        }
                }
+               a++;
        }
        else {
-               for(a=0, efa= em->faces.first; efa; efa= efa->next, a++) {
+               a = 0;
+               BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
                        if(efa == hit->efa) {
                                stack[stacksize]= a;
                                stacksize++;
                                flag[a]= 1;
                                break;
                        }
+
+                       a++;
                }
        }
 
        while(stacksize > 0) {
+               int j;
+
                stacksize--;
                a= stack[stacksize];
+               
+               j = 0;
+               BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+                       if(j==a)
+                               break;
 
-               efa = EM_get_face_for_index(a);
+                       j++;
+               }
 
-               nverts= efa->v4? 4: 3;
+               nverts= efa->len;
+
+               i = 0;
+               BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
 
-               for(i=0; i<nverts; i++) {
                        /* make_uv_vert_map_EM sets verts tmp.l to the indicies */
-                       vlist= EM_get_uv_map_vert(vmap, (*(&efa->v1 + i))->tmp.l);
+                       vlist= EDBM_get_uv_map_vert(vmap, BMINDEX_GET(l->v));
                        
                        startv= vlist;
 
@@ -894,53 +1105,71 @@ static void select_linked(Scene *scene, Image *ima, EditMesh *em, float limit[2]
                                        stacksize++;
                                }
                        }
+
+                       i++;
                }
        }
 
-       if(!extend) {
-               for(a=0, efa= em->faces.first; efa; efa= efa->next, a++) {
-                       tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-                       if(flag[a])
-                               tf->flag |= (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
-                       else
-                               tf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
+       if(!extend || hit) {            
+               a = 0;
+               BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+                       BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                               luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+                               
+                               if (flag[a])
+                                       luv->flag |= MLOOPUV_VERTSEL;
+                               else
+                                       luv->flag &= ~MLOOPUV_VERTSEL;
+                       }
                }
        }
        else {
-               for(a=0, efa= em->faces.first; efa; efa= efa->next, a++) {
-                       if(flag[a]) {
-                               tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-                               if(efa->v4) {
-                                       if((tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4)))
-                                               break;
-                               }
-                               else if(tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3))
+               a = 0;
+               BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+                       BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                               luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+                                               
+                               if (luv->flag & MLOOPUV_VERTSEL)
                                        break;
                        }
+
+                       a++;
                }
 
                if(efa) {
-                       for(a=0, efa= em->faces.first; efa; efa= efa->next, a++) {
-                               if(flag[a]) {
-                                       tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-                                       tf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
+                       a = 0;
+                       BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+                               if (!flag[a]) continue;
+
+                               BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                                       luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+                                       
+                                       luv->flag &= ~MLOOPUV_VERTSEL;
                                }
+
+                               a++;
                        }
                }
                else {
-                       for(a=0, efa= em->faces.first; efa; efa= efa->next, a++) {
-                               if(flag[a]) {
-                                       tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-                                       tf->flag |= (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
+                       a = 0;
+                       BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+                               if (!flag[a]) continue;
+
+                               BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                                       luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+                                       
+                                       luv->flag |= MLOOPUV_VERTSEL;
                                }
+
+                               a++;
                        }
                }
        }
        
        MEM_freeN(stack);
        MEM_freeN(flag);
-       EM_free_uv_vert_map(vmap);
-       EM_free_index_arrays();
+       EDBM_free_uv_vert_map(vmap);
+       EDBM_free_index_arrays(em);
 }
 
 /* ******************** align operator **************** */
@@ -950,31 +1179,33 @@ static void weld_align_uv(bContext *C, int tool)
        Scene *scene;
        Object *obedit;
        Image *ima;
-       EditMesh *em;
-       EditFace *efa;
-       MTFace *tf;
+       BMEditMesh *em;
+       BMFace *efa;
+       BMLoop *l;
+       BMIter iter, liter;
+       MTexPoly *tf;
+       MLoopUV *luv;
        float cent[2], min[2], max[2];
        
        scene= CTX_data_scene(C);
        obedit= CTX_data_edit_object(C);
-       em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
+       em= ((Mesh*)obedit->data)->edit_btmesh;
        ima= CTX_data_edit_image(C);
 
        INIT_MINMAX2(min, max);
 
        if(tool == 'a') {
-               for(efa= em->faces.first; efa; efa= efa->next) {
-                       tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+               BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+                       tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
 
-                       if(uvedit_face_visible(scene, ima, efa, tf)) {
-                               if(uvedit_uv_selected(scene, efa, tf, 0))
-                                       DO_MINMAX2(tf->uv[0], min, max)
-                               if(uvedit_uv_selected(scene, efa, tf, 1))
-                                       DO_MINMAX2(tf->uv[1], min, max)
-                               if(uvedit_uv_selected(scene, efa, tf, 2))
-                                       DO_MINMAX2(tf->uv[2], min, max)
-                               if(efa->v4 && uvedit_uv_selected(scene, efa, tf, 3))
-                                       DO_MINMAX2(tf->uv[3], min, max)
+                       if(!uvedit_face_visible(scene, ima, efa, tf))
+                               continue;
+
+                       BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                               if (uvedit_uv_selected(em, scene, l)) {
+                                       luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+                                       DO_MINMAX2(luv->uv, min, max)
+                               }
                        }
                }
 
@@ -984,41 +1215,39 @@ static void weld_align_uv(bContext *C, int tool)
        uvedit_center(scene, ima, obedit, cent, 0);
 
        if(tool == 'x' || tool == 'w') {
-               for(efa= em->faces.first; efa; efa= efa->next) {
-                       tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-                       if(uvedit_face_visible(scene, ima, efa, tf)) {
-                               if(uvedit_uv_selected(scene, efa, tf, 0))
-                                       tf->uv[0][0]= cent[0];
-                               if(uvedit_uv_selected(scene, efa, tf, 1))
-                                       tf->uv[1][0]= cent[0];
-                               if(uvedit_uv_selected(scene, efa, tf, 2))
-                                       tf->uv[2][0]= cent[0];
-                               if(efa->v4 && uvedit_uv_selected(scene, efa, tf, 3))
-                                       tf->uv[3][0]= cent[0];
+               BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+                       tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+                       if(!uvedit_face_visible(scene, ima, efa, tf))
+                               continue;
+
+                       BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                               if (uvedit_uv_selected(em, scene, l)) {
+                                       luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+                                       luv->uv[0] = cent[0];
+                               }
+
                        }
                }
        }
 
        if(tool == 'y' || tool == 'w') {
-               for(efa= em->faces.first; efa; efa= efa->next) {
-                       tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-                       if(uvedit_face_visible(scene, ima, efa, tf)) {
-                               if(uvedit_uv_selected(scene, efa, tf, 0))
-                                       tf->uv[0][1]= cent[1];
-                               if(uvedit_uv_selected(scene, efa, tf, 1))
-                                       tf->uv[1][1]= cent[1];
-                               if(uvedit_uv_selected(scene, efa, tf, 2))
-                                       tf->uv[2][1]= cent[1];
-                               if(efa->v4 && uvedit_uv_selected(scene, efa, tf, 3))
-                                       tf->uv[3][1]= cent[1];
+               BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+                       tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+                       if(!uvedit_face_visible(scene, ima, efa, tf))
+                               continue;
+
+                       BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                               if (uvedit_uv_selected(em, scene, l)) {
+                                       luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+                                       luv->uv[1] = cent[1];
+                               }
+
                        }
                }
        }
 
        DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
-
-       BKE_mesh_end_editmesh(obedit->data, em);
 }
 
 static int align_exec(bContext *C, wmOperator *op)
@@ -1085,37 +1314,40 @@ static int stitch_exec(bContext *C, wmOperator *op)
        SpaceImage *sima;
        Scene *scene;
        Object *obedit;
-       EditMesh *em;
-       EditFace *efa;
-       EditVert *eve;
+       BMEditMesh *em;
+       BMFace *efa;
+       BMLoop *l;
+       BMIter iter, liter;
+       BMVert *eve;
        Image *ima;
-       MTFace *tf;
+       MTexPoly *tf;
+       MLoopUV *luv;
        
        sima= CTX_wm_space_image(C);
        scene= CTX_data_scene(C);
        obedit= CTX_data_edit_object(C);
-       em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
+       em= ((Mesh*)obedit->data)->edit_btmesh;
        ima= CTX_data_edit_image(C);
        
        if(RNA_boolean_get(op->ptr, "use_limit")) {
                UvVertMap *vmap;
                UvMapVert *vlist, *iterv;
-               float newuv[2], limit[2];
+               float newuv[2], limit[2], pixels;
                int a, vtot;
 
-               limit[0]= RNA_float_get(op->ptr, "limit");
-               limit[1]= limit[0];
+               pixels= RNA_float_get(op->ptr, "limit");
+               uvedit_pixel_to_float(sima, limit, pixels);
 
-               EM_init_index_arrays(em, 0, 0, 1);
-               vmap= EM_make_uv_vert_map(em, 1, 0, limit);
+               EDBM_init_index_arrays(em, 0, 0, 1);
+               vmap= EDBM_make_uv_vert_map(em, 1, 0, limit);
 
                if(vmap == NULL) {
-                       BKE_mesh_end_editmesh(obedit->data, em);
                        return OPERATOR_CANCELLED;
                }
-
-               for(a=0, eve= em->verts.first; eve; a++, eve= eve->next) {
-                       vlist= EM_get_uv_map_vert(vmap, a);
+               
+               a = 0;
+               BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
+                       vlist= EDBM_get_uv_map_vert(vmap, a);
 
                        while(vlist) {
                                newuv[0]= 0; newuv[1]= 0;
@@ -1125,12 +1357,15 @@ static int stitch_exec(bContext *C, wmOperator *op)
                                        if((iterv != vlist) && iterv->separate)
                                                break;
 
-                                       efa = EM_get_face_for_index(iterv->f);
-                                       tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+                                       efa = EDBM_get_face_for_index(em, iterv->f);
+                                       tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
                                        
-                                       if(uvedit_uv_selected(scene, efa, tf, iterv->tfindex)) {
-                                               newuv[0] += tf->uv[iterv->tfindex][0];
-                                               newuv[1] += tf->uv[iterv->tfindex][1];
+                                       l = BMIter_AtIndex(em->bm, BM_LOOPS_OF_FACE, efa, iterv->tfindex);
+                                       if (uvedit_uv_selected(em, scene, l)) {
+                                               luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+
+                                               newuv[0] += luv->uv[0];
+                                               newuv[1] += luv->uv[1];
                                                vtot++;
                                        }
                                }
@@ -1142,95 +1377,72 @@ static int stitch_exec(bContext *C, wmOperator *op)
                                                if((iterv != vlist) && iterv->separate)
                                                        break;
 
-                                               efa = EM_get_face_for_index(iterv->f);
-                                               tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+                                               efa = EDBM_get_face_for_index(em, iterv->f);
+                                               tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+                                               
+                                               l = BMIter_AtIndex(em->bm, BM_LOOPS_OF_FACE, efa, iterv->tfindex);
+                                               if (uvedit_uv_selected(em, scene, l)) {
+                                                       luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
 
-                                               if(uvedit_uv_selected(scene, efa, tf, iterv->tfindex)) {
-                                                       tf->uv[iterv->tfindex][0]= newuv[0];
-                                                       tf->uv[iterv->tfindex][1]= newuv[1];
+                                                       luv->uv[0] = newuv[0];
+                                                       luv->uv[1] = newuv[1];
+                                                       vtot++;
                                                }
                                        }
                                }
 
                                vlist= iterv;
                        }
+
+                       a++;
                }
 
-               EM_free_uv_vert_map(vmap);
-               EM_free_index_arrays();
+               EDBM_free_uv_vert_map(vmap);
+               EDBM_free_index_arrays(em);
        }
        else {
                UVVertAverage *uv_average, *uvav;
                int count;
 
                // index and count verts
-               for(count=0, eve=em->verts.first; eve; count++, eve= eve->next)
-                       eve->tmp.l = count;
+               count=0;
+               BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
+                       BMINDEX_SET(eve, count);
+                       count++;
+               }
                
                uv_average= MEM_callocN(sizeof(UVVertAverage)*count, "Stitch");
                
                // gather uv averages per vert
-               for(efa= em->faces.first; efa; efa= efa->next) {
-                       tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-
-                       if(uvedit_face_visible(scene, ima, efa, tf)) {
-                               if(uvedit_uv_selected(scene, efa, tf, 0)) {
-                                       uvav = uv_average + efa->v1->tmp.l;
-                                       uvav->count++;
-                                       uvav->uv[0] += tf->uv[0][0];
-                                       uvav->uv[1] += tf->uv[0][1];
-                               }
-
-                               if(uvedit_uv_selected(scene, efa, tf, 1)) {
-                                       uvav = uv_average + efa->v2->tmp.l;
-                                       uvav->count++;
-                                       uvav->uv[0] += tf->uv[1][0];
-                                       uvav->uv[1] += tf->uv[1][1];
-                               }
-
-                               if(uvedit_uv_selected(scene, efa, tf, 2)) {
-                                       uvav = uv_average + efa->v3->tmp.l;
-                                       uvav->count++;
-                                       uvav->uv[0] += tf->uv[2][0];
-                                       uvav->uv[1] += tf->uv[2][1];
-                               }
+               BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+                       tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+                       if(!uvedit_face_visible(scene, ima, efa, tf))
+                               continue;
+                       
+                       BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                               if(uvedit_uv_selected(em, scene, l)) {
+                                       luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+                                       uvav = uv_average + BMINDEX_GET(l->v);
 
-                               if(efa->v4 && uvedit_uv_selected(scene, efa, tf, 3)) {
-                                       uvav = uv_average + efa->v4->tmp.l;
                                        uvav->count++;
-                                       uvav->uv[0] += tf->uv[3][0];
-                                       uvav->uv[1] += tf->uv[3][1];
+                                       uvav->uv[0] += luv->uv[0];
+                                       uvav->uv[1] += luv->uv[1];
                                }
                        }
                }
                
                // apply uv welding
-               for(efa= em->faces.first; efa; efa= efa->next) {
-                       tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-
-                       if(uvedit_face_visible(scene, ima, efa, tf)) {
-                               if(uvedit_uv_selected(scene, efa, tf, 0)) {
-                                       uvav = uv_average + efa->v1->tmp.l;
-                                       tf->uv[0][0] = uvav->uv[0]/uvav->count;
-                                       tf->uv[0][1] = uvav->uv[1]/uvav->count;
-                               }
-
-                               if(uvedit_uv_selected(scene, efa, tf, 1)) {
-                                       uvav = uv_average + efa->v2->tmp.l;
-                                       tf->uv[1][0] = uvav->uv[0]/uvav->count;
-                                       tf->uv[1][1] = uvav->uv[1]/uvav->count;
-                               }
-
-                               if(uvedit_uv_selected(scene, efa, tf, 2)) {
-                                       uvav = uv_average + efa->v3->tmp.l;
-                                       tf->uv[2][0] = uvav->uv[0]/uvav->count;
-                                       tf->uv[2][1] = uvav->uv[1]/uvav->count;
-                               }
-
-                               if(efa->v4 && uvedit_uv_selected(scene, efa, tf, 3)) {
-                                       uvav = uv_average + efa->v4->tmp.l;
-                                       tf->uv[3][0] = uvav->uv[0]/uvav->count;
-                                       tf->uv[3][1] = uvav->uv[1]/uvav->count;
+               BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+                       tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+                       if(!uvedit_face_visible(scene, ima, efa, tf))
+                               continue;
+                       
+                       BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                               if(uvedit_uv_selected(em, scene, l)) {
+                                       luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+                                       uvav = uv_average + BMINDEX_GET(l->v);
+                                       luv->uv[0] = uvav->uv[0]/uvav->count;
+                                       luv->uv[1] = uvav->uv[1]/uvav->count;
                                }
                        }
                }
@@ -1241,7 +1453,6 @@ static int stitch_exec(bContext *C, wmOperator *op)
        DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
 
-       BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;
 }
 
@@ -1259,7 +1470,7 @@ void UV_OT_stitch(wmOperatorType *ot)
 
        /* properties */
        RNA_def_boolean(ot->srna, "use_limit", 1, "Use Limit", "Stitch UVs within a specified limit distance.");
-       RNA_def_float(ot->srna, "limit", 0.01f, 0.0f, FLT_MAX, "Limit", "Limit distance in normalized coordinates.", -FLT_MAX, FLT_MAX);
+       RNA_def_float(ot->srna, "limit", 20.0, 0.0f, FLT_MAX, "Limit", "Limit distance in image pixels.", -FLT_MAX, FLT_MAX);
 }
 
 /* ******************** (de)select all operator **************** */
@@ -1269,36 +1480,39 @@ static int select_inverse_exec(bContext *C, wmOperator *op)
        Scene *scene;
        ToolSettings *ts;
        Object *obedit;
-       EditMesh *em;
-       EditFace *efa;
+       BMEditMesh *em;
+       BMFace *efa;
+       BMLoop *l;
+       BMIter iter, liter;
        Image *ima;
-       MTFace *tf;
+       MTexPoly *tf;
+       MLoopUV *luv;
        
        scene= CTX_data_scene(C);
        ts= CTX_data_tool_settings(C);
        obedit= CTX_data_edit_object(C);
-       em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
+       em= ((Mesh*)obedit->data)->edit_btmesh;
        ima= CTX_data_edit_image(C);
 
        if(ts->uv_flag & UV_SYNC_SELECTION) {
-               EM_select_swap(em);
+               EDBM_select_swap(em);
        }
        else {
-               for(efa= em->faces.first; efa; efa= efa->next) {
-                       tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+               BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+                       tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
 
-                       if(uvedit_face_visible(scene, ima, efa, tf)) {
-                               tf->flag ^= TF_SEL1;
-                               tf->flag ^= TF_SEL2;
-                               tf->flag ^= TF_SEL3;
-                               if(efa->v4) tf->flag ^= TF_SEL4;
+                       if(!uvedit_face_visible(scene, ima, efa, tf))
+                               continue;
+
+                       BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                               luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+                               luv->flag = luv->flag ^ MLOOPUV_VERTSEL;
                        }
                }
        }
 
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
 
-       BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;
 }
 
@@ -1322,43 +1536,52 @@ static int select_all_exec(bContext *C, wmOperator *op)
        Scene *scene;
        ToolSettings *ts;
        Object *obedit;
-       EditMesh *em;
-       EditFace *efa;
+       BMEditMesh *em;
+       BMFace *efa;
+       BMLoop *l;
+       BMIter iter, liter;
        Image *ima;
-       MTFace *tf;
+       MTexPoly *tf;
+       MLoopUV *luv;
        int action = RNA_enum_get(op->ptr, "action");
+       int sel = 1;
        
        scene= CTX_data_scene(C);
        ts= CTX_data_tool_settings(C);
        obedit= CTX_data_edit_object(C);
-       em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
+       em= ((Mesh*)obedit->data)->edit_btmesh;
        ima= CTX_data_edit_image(C);
        
        if(ts->uv_flag & UV_SYNC_SELECTION) {
+
                switch (action) {
                case SEL_TOGGLE:
-                       EM_toggle_select_all(em);
+                       EDBM_toggle_select_all(((Mesh*)obedit->data)->edit_btmesh);
                        break;
                case SEL_SELECT:
-                       EM_select_all(em);
+                       EDBM_set_flag_all(em, BM_SELECT);
                        break;
                case SEL_DESELECT:
-                       EM_deselect_all(em);
+                       EDBM_clear_flag_all(em, BM_SELECT);
                        break;
                case SEL_INVERT:
-                       EM_select_swap(em);
+                       EDBM_select_swap(em);
                        break;
                }
        }
        else {
-
                if (action == SEL_TOGGLE) {
                        action = SEL_SELECT;
-                       for(efa= em->faces.first; efa; efa= efa->next) {
-                               tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+                       BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+                               tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+       
+                               if(!uvedit_face_visible(scene, ima, efa, tf))
+                                       continue;
 
-                               if(uvedit_face_visible(scene, ima, efa, tf)) {
-                                       if(tf->flag & (TF_SEL1+TF_SEL2+TF_SEL3+TF_SEL4)) {
+                               BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                                       luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+
+                                       if (luv->flag & MLOOPUV_VERTSEL) {
                                                action = SEL_DESELECT;
                                                break;
                                        }
@@ -1366,30 +1589,29 @@ static int select_all_exec(bContext *C, wmOperator *op)
                        }
                }
        
-               for(efa= em->faces.first; efa; efa= efa->next) {
-                       tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+               
+               BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+                       tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
 
-                       if(uvedit_face_visible(scene, ima, efa, tf)) {
+                       if(!uvedit_face_visible(scene, ima, efa, tf))
+                               continue;
+
+                       BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
                                char select_flag;
 
-                               if(efa->v4)
-                                       select_flag = (TF_SEL1+TF_SEL2+TF_SEL3+TF_SEL4);
-                               else
-                                       select_flag = (TF_SEL1+TF_SEL2+TF_SEL3);
+                               luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+
+                               select_flag = luv->flag & MLOOPUV_VERTSEL;
 
                                switch (action) {
                                case SEL_SELECT:
-                                       tf->flag |= select_flag;
+                                       luv->flag |= MLOOPUV_VERTSEL;
                                        break;
                                case SEL_DESELECT:
-                                       tf->flag &= ~select_flag;
+                                       luv->flag &= MLOOPUV_VERTSEL;
                                        break;
                                case SEL_INVERT:
-                                       if ((tf->flag & select_flag) == select_flag) {
-                                               tf->flag &= ~select_flag;
-                                       } else {
-                                               tf->flag &= ~select_flag;
-                                       }
+                                       luv->flag ^= MLOOPUV_VERTSEL;
                                        break;
                                }
                        }
@@ -1398,7 +1620,6 @@ static int select_all_exec(bContext *C, wmOperator *op)
 
        WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
 
-       BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;
 }
 
@@ -1419,7 +1640,7 @@ void UV_OT_select_all(wmOperatorType *ot)
 
 /* ******************** mouse select operator **************** */
 
-static int sticky_select(float *limit, int hitv[4], int v, float *hituv[4], float *uv, int sticky)
+static int sticky_select(float *limit, int hitv[4], int v, float *hituv[4], float *uv, int sticky, int hitlen)
 {
        int i;
 
@@ -1428,7 +1649,7 @@ static int sticky_select(float *limit, int hitv[4], int v, float *hituv[4], floa
        if(sticky == SI_STICKY_DISABLE)
                return 0;
 
-       for(i=0; i<4; i++) {
+       for(i=0; i<hitlen; i++) {
                if(hitv[i] == v) {
                        if(sticky == SI_STICKY_LOC) {
                                if(fabs(hituv[i][0]-uv[0]) < limit[0] && fabs(hituv[i][1]-uv[1]) < limit[1])
@@ -1449,14 +1670,20 @@ static int mouse_select(bContext *C, float co[2], int extend, int loop)
        ToolSettings *ts= CTX_data_tool_settings(C);
        Object *obedit= CTX_data_edit_object(C);
        Image *ima= CTX_data_edit_image(C);
-       EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
-       EditFace *efa;
-       MTFace *tf;
+       BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh;
+       BMFace *efa;
+       BMLoop *l;
+       BMIter iter, liter;
+       MTexPoly *tf;
+       MLoopUV *luv;
        NearestHit hit;
-       int a, i, select = 1, selectmode, sticky, sync, hitv[4], nvert;
-       int flush = 0; /* 0 == dont flush, 1 == sel, -1 == desel;  only use when selection sync is enabled */
-       float limit[2], *hituv[4], penalty[2];
-       
+       int a, i, select = 1, selectmode, sticky, sync, *hitv=NULL, nvert;
+       BLI_array_declare(hitv);
+       int flush = 0, hitlen=0; /* 0 == dont flush, 1 == sel, -1 == desel;  only use when selection sync is enabled */
+       float limit[2], **hituv = NULL;
+       BLI_array_declare(hituv);
+       float penalty[2];
+
        uvedit_pixel_to_float(sima, limit, 0.05f);
        uvedit_pixel_to_float(sima, penalty, 5.0f);
 
@@ -1476,7 +1703,7 @@ static int mouse_select(bContext *C, float co[2], int extend, int loop)
        else {
                sync= 0;
                selectmode= ts->uv_selectmode;
-               sticky= (sima)? sima->sticky: 1;
+               sticky= sima->sticky;
        }
 
        /* find nearest element */
@@ -1484,76 +1711,88 @@ static int mouse_select(bContext *C, float co[2], int extend, int loop)
                /* find edge */
                find_nearest_uv_edge(scene, ima, em, co, &hit);
                if(hit.efa == NULL) {
-                       BKE_mesh_end_editmesh(obedit->data, em);
                        return OPERATOR_CANCELLED;
                }
+
+               hitlen = 0;
        }
        else if(selectmode == UV_SELECT_VERTEX) {
                /* find vertex */
                find_nearest_uv_vert(scene, ima, em, co, penalty, &hit);
                if(hit.efa == NULL) {
-                       BKE_mesh_end_editmesh(obedit->data, em);
                        return OPERATOR_CANCELLED;
                }
 
                /* mark 1 vertex as being hit */
-               for(i=0; i<4; i++)
+               for(i=0; i<hit.efa->len; i++) {
+                       BLI_array_growone(hitv);
+                       BLI_array_growone(hituv);
                        hitv[i]= 0xFFFFFFFF;
+               }
 
-               hitv[hit.uv]= hit.vert;
-               hituv[hit.uv]= hit.tf->uv[hit.uv];
+               hitv[hit.lindex]= hit.vert1;
+               hituv[hit.lindex]= hit.luv->uv;
+
+               hitlen = hit.efa->len;
        }
        else if(selectmode == UV_SELECT_EDGE) {
                /* find edge */
                find_nearest_uv_edge(scene, ima, em, co, &hit);
                if(hit.efa == NULL) {
-                       BKE_mesh_end_editmesh(obedit->data, em);
                        return OPERATOR_CANCELLED;
                }
 
                /* mark 2 edge vertices as being hit */
-               for(i=0; i<4; i++)
+               for(i=0; i<hit.efa->len; i++) {
+                       BLI_array_growone(hitv);
+                       BLI_array_growone(hituv);
                        hitv[i]= 0xFFFFFFFF;
+               }
+
+               nvert= hit.efa->len;
 
-               nvert= (hit.efa->v4)? 4: 3;
+               hitv[hit.lindex]= hit.vert1;
+               hitv[(hit.lindex+1)%nvert]= hit.vert2;
+               hituv[hit.lindex]= hit.luv->uv;
+               hituv[(hit.lindex+1)%nvert]= hit.nextluv->uv;
 
-               hitv[hit.edge]= hit.vert;
-               hitv[(hit.edge+1)%nvert]= hit.vert2;
-               hituv[hit.edge]= hit.tf->uv[hit.edge];
-               hituv[(hit.edge+1)%nvert]= hit.tf->uv[(hit.edge+1)%nvert];
+               hitlen = hit.efa->len;
        }
        else if(selectmode == UV_SELECT_FACE) {
                /* find face */
                find_nearest_uv_face(scene, ima, em, co, &hit);
                if(hit.efa == NULL) {
-                       BKE_mesh_end_editmesh(obedit->data, em);
                        return OPERATOR_CANCELLED;
                }
                
                /* make active */
-               EM_set_actFace(em, hit.efa);
+               EDBM_set_actFace(em, hit.efa);
 
                /* mark all face vertices as being hit */
-               for(i=0; i<4; i++)
-                       hituv[i]= hit.tf->uv[i];
+               i = 0;
+               BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, hit.efa) {
+                       luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
 
-               hitv[0]= hit.efa->v1->tmp.l;
-               hitv[1]= hit.efa->v2->tmp.l;
-               hitv[2]= hit.efa->v3->tmp.l;
+                       BLI_array_growone(hitv);
+                       BLI_array_growone(hituv);
+                       hituv[i]= luv->uv;
+                       hitv[i] = BMINDEX_GET(l->v);
+                       i++;
+               }
                
-               if(hit.efa->v4) hitv[3]= hit.efa->v4->tmp.l;
-               else hitv[3]= 0xFFFFFFFF;
+               hitlen = hit.efa->len;
        }
        else if(selectmode == UV_SELECT_ISLAND) {
                find_nearest_uv_vert(scene, ima, em, co, NULL, &hit);
 
                if(hit.efa==NULL) {
-                       BKE_mesh_end_editmesh(obedit->data, em);
                        return OPERATOR_CANCELLED;
                }
+
+               hitlen = 0;
        }
        else {
-               BKE_mesh_end_editmesh(obedit->data, em);
+               hitlen = 0;
                return OPERATOR_CANCELLED;
        }
 
@@ -1567,36 +1806,36 @@ static int mouse_select(bContext *C, float co[2], int extend, int loop)
        else if(extend) {
                if(selectmode == UV_SELECT_VERTEX) {
                        /* (de)select uv vertex */
-                       if(uvedit_uv_selected(scene, hit.efa, hit.tf, hit.uv)) {
-                               uvedit_uv_deselect(scene, hit.efa, hit.tf, hit.uv);
+                       if(uvedit_uv_selected(em, scene, hit.l)) {
+                               uvedit_uv_deselect(em, scene, hit.l);
                                select= 0;
                        }
                        else {
-                               uvedit_uv_select(scene, hit.efa, hit.tf, hit.uv);
+                               uvedit_uv_select(em, scene, hit.l);
                                select= 1;
                        }
                        flush = 1;
                }
                else if(selectmode == UV_SELECT_EDGE) {
                        /* (de)select edge */
-                       if(uvedit_edge_selected(scene, hit.efa, hit.tf, hit.edge)) {
-                               uvedit_edge_deselect(scene, hit.efa, hit.tf, hit.edge);
+                       if(uvedit_edge_selected(em, scene, hit.l)) {
+                               uvedit_edge_deselect(em, scene, hit.l);
                                select= 0;
                        }
                        else {
-                               uvedit_edge_select(scene, hit.efa, hit.tf, hit.edge);
+                               uvedit_edge_select(em, scene, hit.l);
                                select= 1;
                        }
                        flush = 1;
                }
                else if(selectmode == UV_SELECT_FACE) {
                        /* (de)select face */
-                       if(uvedit_face_selected(scene, hit.efa, hit.tf)) {
-                               uvedit_face_deselect(scene, hit.efa, hit.tf);
+                       if(uvedit_face_selected(scene, em, hit.efa)) {
+                               uvedit_face_deselect(scene, em, hit.efa);
                                select= 0;
                        }
                        else {
-                               uvedit_face_select(scene, hit.efa, hit.tf);
+                               uvedit_face_select(scene, em, hit.efa);
                                select= 1;
                        }
                        flush = -1;
@@ -1604,97 +1843,89 @@ static int mouse_select(bContext *C, float co[2], int extend, int loop)
 
                /* (de)select sticky uv nodes */
                if(sticky != SI_STICKY_DISABLE) {
-                       EditVert *ev;
-                       
-                       for(a=0, ev=em->verts.first; ev; ev = ev->next, a++)
-                               ev->tmp.l = a;
+                       BMVert *ev;
                        
+                       a = 0;
+                       BM_ITER(ev, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
+                               BMINDEX_SET(ev, a);
+                               a++;
+                       }
+
                        /* deselect */
                        if(select==0) {
-                               for(efa= em->faces.first; efa; efa= efa->next) {
-                                       tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-
-                                       if(uvedit_face_visible(scene, ima, efa, tf)) {
-                                               if(sticky_select(limit, hitv, efa->v1->tmp.l, hituv, tf->uv[0], sticky))
-                                                       uvedit_uv_deselect(scene, efa, tf, 0);
-                                               if(sticky_select(limit, hitv, efa->v2->tmp.l, hituv, tf->uv[1], sticky))
-                                                       uvedit_uv_deselect(scene, efa, tf, 1);
-                                               if(sticky_select(limit, hitv, efa->v3->tmp.l, hituv, tf->uv[2], sticky))
-                                                       uvedit_uv_deselect(scene, efa, tf, 2);
-                                               if(efa->v4)
-                                                       if(sticky_select(limit, hitv, efa->v4->tmp.l, hituv, tf->uv[3], sticky))
-                                                               uvedit_uv_deselect(scene, efa, tf, 3);
+                               BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+                                       tf= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+                                       if(!uvedit_face_visible(scene, ima, efa, tf))
+                                               continue;
+
+                                       BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                                               luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+                                               if(sticky_select(limit, hitv, BMINDEX_GET(l->v), hituv, luv->uv, sticky, hitlen))
+                                                       uvedit_uv_deselect(em, scene, l);
                                        }
                                }
                                flush = -1;
                        }
                        /* select */
                        else {
-                               for(efa= em->faces.first; efa; efa= efa->next) {
-                                       tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-
-                                       if(uvedit_face_visible(scene, ima, efa, tf)) {
-                                               if(sticky_select(limit, hitv, efa->v1->tmp.l, hituv, tf->uv[0], sticky))
-                                                       uvedit_uv_select(scene, efa, tf, 0);
-                                               if(sticky_select(limit, hitv, efa->v2->tmp.l, hituv, tf->uv[1], sticky))
-                                                       uvedit_uv_select(scene, efa, tf, 1);
-                                               if(sticky_select(limit, hitv, efa->v3->tmp.l, hituv, tf->uv[2], sticky))
-                                                       uvedit_uv_select(scene, efa, tf, 2);
-                                               if(efa->v4)
-                                                       if(sticky_select(limit, hitv, efa->v4->tmp.l, hituv, tf->uv[3], sticky))
-                                                               uvedit_uv_select(scene, efa, tf, 3);
+                               BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+                                       tf= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+                                       if(!uvedit_face_visible(scene, ima, efa, tf))
+                                               continue;
+
+                                       BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                                               luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+                                               if(sticky_select(limit, hitv, BMINDEX_GET(l->v), hituv, luv->uv, sticky, hitlen))
+                                                       uvedit_uv_select(em, scene, l);
                                        }
                                }
-                               
+
                                flush = 1;
                        }                       
                }
        }
        else {
                /* deselect all */
-               for(efa= em->faces.first; efa; efa= efa->next) {
-                       tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-                       uvedit_face_deselect(scene, efa, tf);
+               BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+                       uvedit_face_deselect(scene, em, efa);
                }
 
                if(selectmode == UV_SELECT_VERTEX) {
                        /* select vertex */
-                       uvedit_uv_select(scene, hit.efa, hit.tf, hit.uv);
+                       uvedit_uv_select(em, scene, hit.l);
                        flush= 1;
                }
                else if(selectmode == UV_SELECT_EDGE) {
                        /* select edge */
-                       uvedit_edge_select(scene, hit.efa, hit.tf, hit.edge);
+                       uvedit_edge_select(em, scene, hit.l);
                        flush= 1;
                }
                else if(selectmode == UV_SELECT_FACE) {
                        /* select face */
-                       uvedit_face_select(scene, hit.efa, hit.tf);
+                       uvedit_face_select(scene, em, hit.efa);
                }
 
                /* select sticky uvs */
                if(sticky != SI_STICKY_DISABLE) {
-                       for(efa= em->faces.first; efa; efa= efa->next) {
-                               tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-                               if(uvedit_face_visible(scene, ima, efa, tf)) {
+                       BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+                               tf= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+                               if(!uvedit_face_visible(scene, ima, efa, tf))
+                                       continue;
+                               
+                               BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
                                        if(sticky == SI_STICKY_DISABLE) continue;
+                                       luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
 
-                                       if(sticky_select(limit, hitv, efa->v1->tmp.l, hituv, tf->uv[0], sticky))
-                                               uvedit_uv_select(scene, efa, tf, 0);
-                                       if(sticky_select(limit, hitv, efa->v2->tmp.l, hituv, tf->uv[1], sticky))
-                                               uvedit_uv_select(scene, efa, tf, 1);
-                                       if(sticky_select(limit, hitv, efa->v3->tmp.l, hituv, tf->uv[2], sticky))
-                                               uvedit_uv_select(scene, efa, tf, 2);
-                                       if(efa->v4)
-                                               if(sticky_select(limit, hitv, efa->v4->tmp.l, hituv, tf->uv[3], sticky))
-                                                       uvedit_uv_select(scene, efa, tf, 3);
+                                       if(sticky_select(limit, hitv, BMINDEX_GET(l->v), hituv, luv->uv, sticky, hitlen))
+                                               uvedit_uv_select(em, scene, l);
 
                                        flush= 1;
                                }
                        }
                }
        }
-       
+#if 0 //bmesh does flushing through the BM_Select functions, so not sure
+      //what to do about this bit.
        if(sync) {
                /* flush for mesh selection */
                if(ts->selectmode != SCE_SELECT_FACE) {
@@ -1702,11 +1933,10 @@ static int mouse_select(bContext *C, float co[2], int extend, int loop)
                        else if(flush==-1)      EM_deselect_flush(em);
                }
        }
-       
+#endif 
        DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
        WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
        
-       BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_PASS_THROUGH|OPERATOR_FINISHED;
 }
 
@@ -1815,7 +2045,7 @@ static int select_linked_internal(bContext *C, wmOperator *op, wmEvent *event, i
        ToolSettings *ts= CTX_data_tool_settings(C);
        Object *obedit= CTX_data_edit_object(C);
        Image *ima= CTX_data_edit_image(C);
-       EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
+       BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh;
        float limit[2];
        int extend;
 
@@ -1823,7 +2053,6 @@ static int select_linked_internal(bContext *C, wmOperator *op, wmEvent *event, i
 
        if(ts->uv_flag & UV_SYNC_SELECTION) {
                BKE_report(op->reports, RPT_ERROR, "Can't select linked when sync selection is enabled.");
-               BKE_mesh_end_editmesh(obedit->data, em);
                return OPERATOR_CANCELLED;
        }
 
@@ -1858,7 +2087,6 @@ static int select_linked_internal(bContext *C, wmOperator *op, wmEvent *event, i
        DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
        WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
 
-       BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;
 }
 
@@ -1923,27 +2151,38 @@ static int unlink_selection_exec(bContext *C, wmOperator *op)
        ToolSettings *ts= CTX_data_tool_settings(C);
        Object *obedit= CTX_data_edit_object(C);
        Image *ima= CTX_data_edit_image(C);
-       EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
-       EditFace *efa;
-       MTFace *tf;
+       BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh;
+       BMFace *efa;
+       BMLoop *l;
+       BMIter iter, liter;
+       MTexPoly *tf;
+       MLoopUV *luv;
 
        if(ts->uv_flag & UV_SYNC_SELECTION) {
                BKE_report(op->reports, RPT_ERROR, "Can't unlink selection when sync selection is enabled.");
-               BKE_mesh_end_editmesh(obedit->data, em);
                return OPERATOR_CANCELLED;
        }
        
-       for(efa= em->faces.first; efa; efa= efa->next) {
-               tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+       BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+               int desel = 0;
+
+               tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+               if(!uvedit_face_visible(scene, ima, efa, tf))
+                       continue;
 
-               if(uvedit_face_visible(scene, ima, efa, tf)) {
-                       if(efa->v4) {
-                               if(~tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4))
-                                       tf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4);
+               BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                       luv = CustomData_bmesh_get(&em->bm->pdata, l->head.data, CD_MLOOPUV);
+                       
+                       if (!(luv->flag & MLOOPUV_VERTSEL)) {
+                               desel = 1;
+                               break;
                        }
-                       else {
-                               if(~tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3))
-                                       tf->flag &= ~(TF_SEL1|TF_SEL2|TF_SEL3);
+               }
+
+               if (desel) {
+                       BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                               luv = CustomData_bmesh_get(&em->bm->pdata, l->head.data, CD_MLOOPUV);
+                               luv->flag &= ~MLOOPUV_VERTSEL;
                        }
                }
        }
@@ -1951,7 +2190,6 @@ static int unlink_selection_exec(bContext *C, wmOperator *op)
        DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
        WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
 
-       BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;
 }
 
@@ -1986,78 +2224,77 @@ static void uv_faces_do_sticky(bContext *C, SpaceImage *sima, Scene *scene, Obje
         * selection (so for sticky modes, vertex or location based). */
        
        ToolSettings *ts= CTX_data_tool_settings(C);
-       EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
-       EditFace *efa;
-       MTFace *tf;
-       int nverts, i;
+       BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh;
+       BMFace *efa;
+       BMLoop *l;
+       BMIter iter, liter;
+       MTexPoly *tf;
        
        if((ts->uv_flag & UV_SYNC_SELECTION)==0 && sima->sticky == SI_STICKY_VERTEX) {
                /* Tag all verts as untouched, then touch the ones that have a face center
-                * in the loop and select all MTFace UV's that use a touched vert. */
-               EditVert *eve;
+                * in the loop and select all MLoopUV's that use a touched vert. */
+               BMVert *eve;
                
-               for(eve= em->verts.first; eve; eve= eve->next)
-                       eve->tmp.l = 0;
+               BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL)
+                       BMINDEX_SET(eve, 0);
                
-               for(efa= em->faces.first; efa; efa= efa->next) {
-                       if(efa->tmp.l) {
-                               if(efa->v4)
-                                       efa->v1->tmp.l= efa->v2->tmp.l= efa->v3->tmp.l= efa->v4->tmp.l=1;
-                               else
-                                       efa->v1->tmp.l= efa->v2->tmp.l= efa->v3->tmp.l= 1;
+               BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+                       if(BMINDEX_GET(efa)) {
+                               BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                                       BMINDEX_SET(l->v, 1);
+                               }
                        }
                }
 
                /* now select tagged verts */
-               for(efa= em->faces.first; efa; efa= efa->next) {
-                       tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);               
-                       nverts= efa->v4? 4: 3;
-                       for(i=0; i<nverts; i++) {
-                               if((*(&efa->v1 + i))->tmp.l) {
-                                       if(select)
-                                               uvedit_uv_select(scene, efa, tf, i);
+               BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+                       tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+
+                       BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                               if (BMINDEX_GET(l->v)) {
+                                       if (select)
+                                               uvedit_uv_select(em, scene, l);
                                        else
-                                               uvedit_uv_deselect(scene, efa, tf, i);
+                                               uvedit_uv_deselect(em, scene, l);
                                }
                        }
                }
        }
        else if((ts->uv_flag & UV_SYNC_SELECTION)==0 && sima->sticky == SI_STICKY_LOC) {
-               EditFace *efa_vlist;
-               MTFace *tf_vlist;
+               BMFace *efa_vlist;
+               MTexPoly *tf_vlist;
                UvMapVert *start_vlist=NULL, *vlist_iter;
                struct UvVertMap *vmap;
                float limit[2];
                int efa_index;
-               //EditVert *eve; /* removed vert counting for now */ 
+               //BMVert *eve; /* removed vert counting for now */ 
                //int a;
                
                uvedit_pixel_to_float(sima, limit, 0.05);
                
-               EM_init_index_arrays(em, 0, 0, 1);
-               vmap= EM_make_uv_vert_map(em, 0, 0, limit);
+               EDBM_init_index_arrays(em, 0, 0, 1);
+               vmap= EDBM_make_uv_vert_map(em, 0, 0, limit);
                
                /* verts are numbered above in make_uv_vert_map_EM, make sure this stays true! */
                /*for(a=0, eve= em->verts.first; eve; a++, eve= eve->next)
                        eve->tmp.l = a; */
                
                if(vmap == NULL) {
-                       BKE_mesh_end_editmesh(obedit->data, em);
                        return;
                }
                
-               for(efa_index=0, efa= em->faces.first; efa; efa_index++, efa= efa->next) {
-                       if(efa->tmp.l) {
-                               tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-                               nverts= efa->v4? 4: 3;
-
-                               for(i=0; i<nverts; i++) {
+               efa = BMIter_New(&iter, em->bm, BM_FACES_OF_MESH, NULL);
+               for (efa_index=0; efa; efa=BMIter_Step(&iter), efa_index++) {
+                       if(BMINDEX_GET(efa)) {
+                               tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+                               
+                               BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
                                        if(select)
-                                               uvedit_uv_select(scene, efa, tf, i);
+                                               uvedit_uv_select(em, scene, l);
                                        else
-                                               uvedit_uv_deselect(scene, efa, tf, i);
+                                               uvedit_uv_deselect(em, scene, l);
                                        
-                                       vlist_iter= EM_get_uv_map_vert(vmap, (*(&efa->v1 + i))->tmp.l);
+                                       vlist_iter= EDBM_get_uv_map_vert(vmap, BMINDEX_GET(l->v));
                                        
                                        while (vlist_iter) {
                                                if(vlist_iter->separate)
@@ -2076,35 +2313,33 @@ static void uv_faces_do_sticky(bContext *C, SpaceImage *sima, Scene *scene, Obje
                                                        break;
                                                
                                                if(efa_index != vlist_iter->f) {
-                                                       efa_vlist = EM_get_face_for_index(vlist_iter->f);
-                                                       tf_vlist = CustomData_em_get(&em->fdata, efa_vlist->data, CD_MTFACE);
+                                                       efa_vlist = EDBM_get_face_for_index(em, vlist_iter->f);
+                                                       tf_vlist = CustomData_bmesh_get(&em->bm->pdata, efa_vlist->head.data, CD_MTEXPOLY);
                                                        
                                                        if(select)
-                                                               uvedit_uv_select(scene, efa_vlist, tf_vlist, vlist_iter->tfindex);
+                                                               uvedit_uv_select(em, scene, BMIter_AtIndex(em->bm, BM_LOOPS_OF_FACE, efa_vlist, vlist_iter->tfindex));
                                                        else
-                                                               uvedit_uv_deselect(scene, efa_vlist, tf_vlist, vlist_iter->tfindex);
+                                                               uvedit_uv_deselect(em, scene, BMIter_AtIndex(em->bm, BM_LOOPS_OF_FACE, efa_vlist, vlist_iter->tfindex));
                                                }
                                                vlist_iter = vlist_iter->next;
                                        }
                                }
                        }
                }
-               EM_free_index_arrays();
-               EM_free_uv_vert_map(vmap);
+               EDBM_free_index_arrays(em);
+               EDBM_free_uv_vert_map(vmap);
                
        }
        else { /* SI_STICKY_DISABLE or ts->uv_flag & UV_SYNC_SELECTION */
-               for(efa= em->faces.first; efa; efa= efa->next) {
-                       if(efa->tmp.l) {
-                               tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+               BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+                       if(BMINDEX_GET(efa)) {
                                if(select)
-                                       uvedit_face_select(scene, efa, tf);
+                                       uvedit_face_select(scene, em, efa);
                                else
-                                       uvedit_face_deselect(scene, efa, tf);
+                                       uvedit_face_deselect(scene, em, efa);
                        }
                }
        }
-       BKE_mesh_end_editmesh(obedit->data, em);
 }
 
 static int border_select_exec(bContext *C, wmOperator *op)
@@ -2115,9 +2350,12 @@ static int border_select_exec(bContext *C, wmOperator *op)
        Object *obedit= CTX_data_edit_object(C);
        Image *ima= CTX_data_edit_image(C);
        ARegion *ar= CTX_wm_region(C);
-       EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
-       EditFace *efa;
-       MTFace *tface;
+       BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh;
+       BMFace *efa;
+       BMLoop *l;
+       BMIter iter, liter;
+       MTexPoly *tf;
+       MLoopUV *luv;
        rcti rect;
        rctf rectf;
        int change, pinned, select, faces;
@@ -2147,14 +2385,16 @@ static int border_select_exec(bContext *C, wmOperator *op)
 
                change= 0;
 
-               for(efa= em->faces.first; efa; efa= efa->next) {
+               BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
                        /* assume not touched */
-                       efa->tmp.l = 0;
-                       tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-                       if(uvedit_face_visible(scene, ima, efa, tface)) {
-                               uv_center(tface->uv, cent, efa->v4 != NULL);
+                       BMINDEX_SET(efa, 0);
+
+                       tf= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+                       if(uvedit_face_visible(scene, ima, efa, tf)) {
+                               poly_uv_center(em, efa, cent);
                                if(BLI_in_rctf(&rectf, cent[0], cent[1])) {
-                                       efa->tmp.l = change = 1;
+                                       BMINDEX_SET(efa, 1);
+                                       change = 1;
                                }
                        }
                }
@@ -2166,51 +2406,26 @@ static int border_select_exec(bContext *C, wmOperator *op)
        else {
                /* other selection modes */
                change= 1;
+               
+               BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+                       tf= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+                       if(!uvedit_face_visible(scene, ima, efa, tf))
+                               continue;
+                       BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                               luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
 
-               for(efa= em->faces.first; efa; efa= efa->next) {
-                       tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-                       if(uvedit_face_visible(scene, ima, efa, tface)) {
                                if(!pinned || (ts->uv_flag & UV_SYNC_SELECTION) ) {
+
                                        /* UV_SYNC_SELECTION - can't do pinned selection */
-                                       if(BLI_in_rctf(&rectf, tface->uv[0][0], tface->uv[0][1])) {
-                                               if(select)      uvedit_uv_select(scene, efa, tface, 0);
-                                               else            uvedit_uv_deselect(scene, efa, tface, 0);
-                                       }
-                                       if(BLI_in_rctf(&rectf, tface->uv[1][0], tface->uv[1][1])) {
-                                               if(select)      uvedit_uv_select(scene, efa, tface, 1);
-                                               else            uvedit_uv_deselect(scene, efa, tface, 1);
+                                       if(BLI_in_rctf(&rectf, luv->uv[0], luv->uv[1])) {
+                                               if(select)      uvedit_uv_select(em, scene, l);
+                                               else            uvedit_uv_deselect(em, scene, l);
                                        }
-                                       if(BLI_in_rctf(&rectf, tface->uv[2][0], tface->uv[2][1])) {
-                                               if(select)      uvedit_uv_select(scene, efa, tface, 2);
-                                               else            uvedit_uv_deselect(scene, efa, tface, 2);
-                                       }
-                                       if(efa->v4 && BLI_in_rctf(&rectf, tface->uv[3][0], tface->uv[3][1])) {
-                                               if(select)      uvedit_uv_select(scene, efa, tface, 3);
-                                               else            uvedit_uv_deselect(scene, efa, tface, 3);
-                                       }
-                               }
-                               else if(pinned) {
-                                       if((tface->unwrap & TF_PIN1) && 
-                                               BLI_in_rctf(&rectf, tface->uv[0][0], tface->uv[0][1])) {
-                                               
-                                               if(select)      uvedit_uv_select(scene, efa, tface, 0);
-                                               else            uvedit_uv_deselect(scene, efa, tface, 0);
-                                       }
-                                       if((tface->unwrap & TF_PIN2) && 
-                                               BLI_in_rctf(&rectf, tface->uv[1][0], tface->uv[1][1])) {
-                                               
-                                               if(select)      uvedit_uv_select(scene, efa, tface, 1);
-                                               else            uvedit_uv_deselect(scene, efa, tface, 1);
-                                       }
-                                       if((tface->unwrap & TF_PIN3) && 
-                                               BLI_in_rctf(&rectf, tface->uv[2][0], tface->uv[2][1])) {
-                                               
-                                               if(select)      uvedit_uv_select(scene, efa, tface, 2);
-                                               else            uvedit_uv_deselect(scene, efa, tface, 2);
-                                       }
-                                       if((efa->v4) && (tface->unwrap & TF_PIN4) && BLI_in_rctf(&rectf, tface->uv[3][0], tface->uv[3][1])) {
-                                               if(select)      uvedit_uv_select(scene, efa, tface, 3);
-                                               else            uvedit_uv_deselect(scene, efa, tface, 3);
+                               } else if(pinned) {
+                                       if ((luv->flag & MLOOPUV_PINNED) && 
+                                           BLI_in_rctf(&rectf, luv->uv[0], luv->uv[1])) {
+                                               if(select)      uvedit_uv_select(em, scene, l);
+                                               else            uvedit_uv_deselect(em, scene, l);
                                        }
                                }
                        }
@@ -2219,20 +2434,20 @@ static int border_select_exec(bContext *C, wmOperator *op)
 
        if(change) {
                /* make sure newly selected vert selection is updated*/
+#if 0 //ok, I think the BM_Select API handles all of this?
                if(ts->uv_flag & UV_SYNC_SELECTION) {
                        if(ts->selectmode != SCE_SELECT_FACE) {
                                if(select)      EM_select_flush(em);
                                else            EM_deselect_flush(em);
                        }
                }
+#endif
 
                WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
                
-               BKE_mesh_end_editmesh(obedit->data, em);
                return OPERATOR_FINISHED;
        }
-       
-       BKE_mesh_end_editmesh(obedit->data, em);
+
        return OPERATOR_CANCELLED;
 } 
 
@@ -2260,20 +2475,23 @@ void UV_OT_select_border(wmOperatorType *ot)
 
 /* ******************** circle select operator **************** */
 
-static void select_uv_inside_ellipse(SpaceImage *sima, Scene *scene, int select, EditFace *efa, MTFace *tface, int index, float *offset, float *ell, int select_index)
+static void select_uv_inside_ellipse(BMEditMesh *em, SpaceImage *sima, 
+                                    Scene *scene, int select, float *offset,
+                                    float *ell, BMLoop *l, MLoopUV *luv)
 {
        /* normalized ellipse: ell[0] = scaleX, ell[1] = scaleY */
        float x, y, r2, *uv;
        
-       uv= tface->uv[index];
+       
+       uv= luv->uv;
 
        x= (uv[0] - offset[0])*ell[0];
        y= (uv[1] - offset[1])*ell[1];
 
        r2 = x*x + y*y;
        if(r2 < 1.0) {
-               if(select)      uvedit_uv_select(scene, efa, tface, select_index);
-               else uvedit_uv_deselect(scene, efa, tface, select_index);
+               if(select) uvedit_uv_select(em, scene, l);
+               else uvedit_uv_deselect(em, scene, l);
        }
 }
 
@@ -2282,10 +2500,13 @@ int circle_select_exec(bContext *C, wmOperator *op)
        SpaceImage *sima= CTX_wm_space_image(C);
        Scene *scene= CTX_data_scene(C);
        Object *obedit= CTX_data_edit_object(C);
-       EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
+       BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh;
        ARegion *ar= CTX_wm_region(C);
-       EditFace *efa;
-       MTFace *tface;
+       BMFace *efa;
+       BMLoop *l;
+       BMIter iter, liter;
+       MLoopUV *luv;
+       MTexPoly *tface;
        int x, y, radius, width, height, select;
        float zoomx, zoomy, offset[2], ellipse[2];
        int gesture_mode= RNA_int_get(op->ptr, "gesture_mode");
@@ -2307,21 +2528,19 @@ int circle_select_exec(bContext *C, wmOperator *op)
        UI_view2d_region_to_view(&ar->v2d, x, y, &offset[0], &offset[1]);
        
        /* do selection */
-       for(efa= em->faces.first; efa; efa= efa->next) {
-               tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-               select_uv_inside_ellipse(sima, scene, select, efa, tface, 0, offset, ellipse, 0);
-               select_uv_inside_ellipse(sima, scene, select, efa, tface, 1, offset, ellipse, 1);
-               select_uv_inside_ellipse(sima, scene, select, efa, tface, 2, offset, ellipse, 2);
-               if(efa->v4)
-                       select_uv_inside_ellipse(sima, scene, select, efa, tface, 3, offset, ellipse, 3);
+       BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+               BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                       luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+                       select_uv_inside_ellipse(em, sima, scene, select, offset, ellipse, l, luv);
+               }
        }
 
+#if 0 //I think the BM_Select api stuff handles all this as necassary?
        if(select) EM_select_flush(em);
        else EM_deselect_flush(em);
-
+#endif
        WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
 
-       BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;
 }
 
@@ -2420,97 +2639,88 @@ void UV_OT_snap_cursor(wmOperatorType *ot)
 
 static int snap_uvs_to_cursor(Scene *scene, Image *ima, Object *obedit, SpaceImage *sima)
 {
-       EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
-       EditFace *efa;
-       MTFace *tface;
+       BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh;
+       BMFace *efa;
+       BMLoop *l;
+       BMIter iter, liter;
+       MTexPoly *tface;
+       MLoopUV *luv;
        short change= 0;
 
-       for(efa= em->faces.first; efa; efa= efa->next) {
-               tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-               if(uvedit_face_visible(scene, ima, efa, tface)) {
-                       if(uvedit_uv_selected(scene, efa, tface, 0))            VECCOPY2D(tface->uv[0], sima->cursor);
-                       if(uvedit_uv_selected(scene, efa, tface, 1))            VECCOPY2D(tface->uv[1], sima->cursor);
-                       if(uvedit_uv_selected(scene, efa, tface, 2))            VECCOPY2D(tface->uv[2], sima->cursor);
-                       if(efa->v4)
-                               if(uvedit_uv_selected(scene, efa, tface, 3))    VECCOPY2D(tface->uv[3], sima->cursor);
+       BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+               tface= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+               if(!uvedit_face_visible(scene, ima, efa, tface))
+                       continue;
 
-                       change= 1;
+               BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                       if(uvedit_uv_selected(em, scene, l)) {
+                               luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+                               VECCOPY2D(luv->uv, sima->cursor);
+                               change= 1;
+                       }
                }
        }
 
-       BKE_mesh_end_editmesh(obedit->data, em);
        return change;
 }
 
 static int snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object *obedit)
 {
-       EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
-       EditFace *efa;
-       EditVert *eve;
-       MTFace *tface;
+       BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh;
+       BMFace *efa;
+       BMLoop *l;
+       BMIter iter, liter;
+       BMVert *eve;
+       MTexPoly *tface;
+       MLoopUV *luv;
        short change = 0;
        int count = 0;
        float *coords;
        short *usercount, users;
        
        /* set all verts to -1 : an unused index*/
-       for(eve= em->verts.first; eve; eve= eve->next)
-               eve->tmp.l=-1;
+       BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL)
+               BMINDEX_SET(eve, -1);
        
        /* index every vert that has a selected UV using it, but only once so as to
         * get unique indicies and to count how much to malloc */
-       for(efa= em->faces.first; efa; efa= efa->next) {
-               tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-
-               if(uvedit_face_visible(scene, ima, efa, tface)) {
-                       if(uvedit_uv_selected(scene, efa, tface, 0) && efa->v1->tmp.l==-1)              efa->v1->tmp.l= count++;
-                       if(uvedit_uv_selected(scene, efa, tface, 1) && efa->v2->tmp.l==-1)              efa->v2->tmp.l= count++;
-                       if(uvedit_uv_selected(scene, efa, tface, 2) && efa->v3->tmp.l==-1)              efa->v3->tmp.l= count++;
-                       if(efa->v4)
-                               if(uvedit_uv_selected(scene, efa, tface, 3) && efa->v4->tmp.l==-1)      efa->v4->tmp.l= count++;
+       BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+               tface= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+               if(!uvedit_face_visible(scene, ima, efa, tface)) {
+                       BMINDEX_SET(efa, 0);
+                       continue;
+               } else {
+                       BMINDEX_SET(efa, 1);
+               }
 
-                       change = 1;
-                       
-                       /* optional speedup */
-                       efa->tmp.p = tface;
+               change = 1;
+               BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                       if (uvedit_uv_selected(em, scene, l) && BMINDEX_GET(l->v) == -1) {
+                               BMINDEX_SET(l->v, count);
+                               count++;
+                       }
                }
-               else
-                       efa->tmp.p = NULL;
        }
        
        coords = MEM_callocN(sizeof(float)*count*2, "snap to adjacent coords");
        usercount = MEM_callocN(sizeof(short)*count, "snap to adjacent counts");
        
        /* add all UV coords from visible, unselected UV coords as well as counting them to average later */
-       for(efa= em->faces.first; efa; efa= efa->next) {
-               if((tface=(MTFace *)efa->tmp.p)) {
-                       /* is this an unselected UV we can snap to? */
-                       if(efa->v1->tmp.l >= 0 && (!uvedit_uv_selected(scene, efa, tface, 0))) {
-                               coords[efa->v1->tmp.l*2] +=             tface->uv[0][0];
-                               coords[(efa->v1->tmp.l*2)+1] += tface->uv[0][1];
-                               usercount[efa->v1->tmp.l]++;
-                               change = 1;
-                       }
-                       if(efa->v2->tmp.l >= 0 && (!uvedit_uv_selected(scene, efa, tface, 1))) {
-                               coords[efa->v2->tmp.l*2] +=             tface->uv[1][0];
-                               coords[(efa->v2->tmp.l*2)+1] += tface->uv[1][1];
-                               usercount[efa->v2->tmp.l]++;
-                               change = 1;
-                       }
-                       if(efa->v3->tmp.l >= 0 && (!uvedit_uv_selected(scene, efa, tface, 2))) {
-                               coords[efa->v3->tmp.l*2] +=             tface->uv[2][0];
-                               coords[(efa->v3->tmp.l*2)+1] += tface->uv[2][1];
-                               usercount[efa->v3->tmp.l]++;
-                               change = 1;
-                       }
-                       
-                       if(efa->v4) {
-                               if(efa->v4->tmp.l >= 0 && (!uvedit_uv_selected(scene, efa, tface, 3))) {
-                                       coords[efa->v4->tmp.l*2] +=             tface->uv[3][0];
-                                       coords[(efa->v4->tmp.l*2)+1] += tface->uv[3][1];
-                                       usercount[efa->v4->tmp.l]++;
-                                       change = 1;
-                               }
+       BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+               if (!BMINDEX_GET(efa))
+                       continue;
+
+               tface= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+               if(!uvedit_face_visible(scene, ima, efa, tface))
+                       continue;
+
+               BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                       if (BMINDEX_GET(l->v) >= 0 && 
+                           (!uvedit_uv_selected(em, scene, l))) {
+                                   luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+                                   coords[BMINDEX_GET(l->v)*2] += luv->uv[0];
+                                   coords[BMINDEX_GET(l->v)*2+1] += luv->uv[1];
+                                   change = 1;
                        }
                }
        }
@@ -2519,46 +2729,24 @@ static int snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object *obe
        if(!change) {
                MEM_freeN(coords);
                MEM_freeN(usercount);
-               BKE_mesh_end_editmesh(obedit->data, em);
                return change;
        }
        
        /* copy the averaged unselected UVs back to the selected UVs */
-       for(efa= em->faces.first; efa; efa= efa->next) {
-               if((tface=(MTFace *)efa->tmp.p)) {
-                       
-                       if(     uvedit_uv_selected(scene, efa, tface, 0) &&
-                                       efa->v1->tmp.l >= 0 &&
-                                       (users = usercount[efa->v1->tmp.l])
-                       ) {
-                               tface->uv[0][0] = coords[efa->v1->tmp.l*2]              / users;
-                               tface->uv[0][1] = coords[(efa->v1->tmp.l*2)+1]  / users;
-                       }
+       BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+               if (!BMINDEX_GET(efa))
+                       continue;
 
-                       if(     uvedit_uv_selected(scene, efa, tface, 1) &&
-                                       efa->v2->tmp.l >= 0 &&
-                                       (users = usercount[efa->v2->tmp.l])
-                       ) {
-                               tface->uv[1][0] = coords[efa->v2->tmp.l*2]              / users;
-                               tface->uv[1][1] = coords[(efa->v2->tmp.l*2)+1]  / users;
-                       }
-                       
-                       if(     uvedit_uv_selected(scene, efa, tface, 2) &&
-                                       efa->v3->tmp.l >= 0 &&
-                                       (users = usercount[efa->v3->tmp.l])
-                       ) {
-                               tface->uv[2][0] = coords[efa->v3->tmp.l*2]              / users;
-                               tface->uv[2][1] = coords[(efa->v3->tmp.l*2)+1]  / users;
-                       }
-                       
-                       if(efa->v4) {
-                               if(     uvedit_uv_selected(scene, efa, tface, 3) &&
-                                               efa->v4->tmp.l >= 0 &&
-                                               (users = usercount[efa->v4->tmp.l])
-                               ) {
-                                       tface->uv[3][0] = coords[efa->v4->tmp.l*2]              / users;
-                                       tface->uv[3][1] = coords[(efa->v4->tmp.l*2)+1]  / users;
-                               }
+               tface= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+               if(!uvedit_face_visible(scene, ima, efa, tface))
+                       continue;
+
+               BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                       if (uvedit_uv_selected(em, scene, l) && BMINDEX_GET(l->v) >= 0
+                           && (users = usercount[BMINDEX_GET(l->v)])) {
+                               luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+                               luv->uv[0] = coords[BMINDEX_GET(l->v)*2];
+                               luv->uv[1] = coords[BMINDEX_GET(l->v)*2+1];
                        }
                }
        }
@@ -2566,43 +2754,41 @@ static int snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object *obe
        MEM_freeN(coords);
        MEM_freeN(usercount);
 
-       BKE_mesh_end_editmesh(obedit->data, em);
        return change;
 }
 
 static int snap_uvs_to_pixels(SpaceImage *sima, Scene *scene, Object *obedit)
 {
-       EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
-       Image *ima;
-       EditFace *efa;
-       MTFace *tface;
+       BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh;
+       Image *ima= sima->image;
+       BMFace *efa;
+       BMLoop *l;
+       BMIter iter, liter;
+       MTexPoly *tface;
+       MLoopUV *luv;
        int width= 0, height= 0;
        float w, h;
        short change = 0;
 
-       if(!sima)
-               return 0;
-       
-       ima= sima->image;
-       
        ED_space_image_size(sima, &width, &height);
        w = (float)width;
        h = (float)height;
        
-       for(efa= em->faces.first; efa; efa= efa->next) {
-               tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-               if(uvedit_face_visible(scene, ima, efa, tface)) {
-                       if(uvedit_uv_selected(scene, efa, tface, 0)) snap_uv_to_pixel(tface->uv[0], w, h);
-                       if(uvedit_uv_selected(scene, efa, tface, 1)) snap_uv_to_pixel(tface->uv[1], w, h);
-                       if(uvedit_uv_selected(scene, efa, tface, 2)) snap_uv_to_pixel(tface->uv[2], w, h);
-                       if(efa->v4)
-                               if(uvedit_uv_selected(scene, efa, tface, 3)) snap_uv_to_pixel(tface->uv[3], w, h);
+       BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+               tface= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+               if(!uvedit_face_visible(scene, ima, efa, tface))
+                       continue;
 
-                       change = 1;
+               BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                       if (uvedit_uv_selected(em, scene, l)) {
+                               luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+                               snap_uv_to_pixel(luv->uv, w, h);
+                       }
                }
+
+               change = 1;
        }
 
-       BKE_mesh_end_editmesh(obedit->data, em);
        return change;
 }
 
@@ -2664,35 +2850,34 @@ static int pin_exec(bContext *C, wmOperator *op)
        Scene *scene= CTX_data_scene(C);
        Object *obedit= CTX_data_edit_object(C);
        Image *ima= CTX_data_edit_image(C);
-       EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
-       EditFace *efa;
-       MTFace *tface;
+       BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh;
+       BMFace *efa;
+       BMLoop *l;
+       BMIter iter, liter;
+       MTexPoly *tface;
+       MLoopUV *luv;
        int clear= RNA_boolean_get(op->ptr, "clear");
        
-       for(efa= em->faces.first; efa; efa= efa->next) {
-               tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+       BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+               tface= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+               if(!uvedit_face_visible(scene, ima, efa, tface))
+                       continue;
 
-               if(uvedit_face_visible(scene, ima, efa, tface)) {
+               BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                       luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+                       
                        if(!clear) {
-                               if(uvedit_uv_selected(scene, efa, tface, 0)) tface->unwrap |= TF_PIN1;
-                               if(uvedit_uv_selected(scene, efa, tface, 1)) tface->unwrap |= TF_PIN2;
-                               if(uvedit_uv_selected(scene, efa, tface, 2)) tface->unwrap |= TF_PIN3;
-                               if(efa->v4)
-                                       if(uvedit_uv_selected(scene, efa, tface, 3)) tface->unwrap |= TF_PIN4;
-                       }
-                       else {
-                               if(uvedit_uv_selected(scene, efa, tface, 0)) tface->unwrap &= ~TF_PIN1;
-                               if(uvedit_uv_selected(scene, efa, tface, 1)) tface->unwrap &= ~TF_PIN2;
-                               if(uvedit_uv_selected(scene, efa, tface, 2)) tface->unwrap &= ~TF_PIN3;
-                               if(efa->v4)
-                                       if(uvedit_uv_selected(scene, efa, tface, 3)) tface->unwrap &= ~TF_PIN4;
+                               if (uvedit_uv_selected(em, scene, l))
+                                       luv->flag |= MLOOPUV_PINNED;
+                       } else {
+                               if (uvedit_uv_selected(em, scene, l))
+                                       luv->flag &= ~MLOOPUV_PINNED;
                        }
                }
        }
        
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
 
-       BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;
 }
 
@@ -2719,26 +2904,28 @@ static int select_pinned_exec(bContext *C, wmOperator *op)
        Scene *scene= CTX_data_scene(C);
        Object *obedit= CTX_data_edit_object(C);
        Image *ima= CTX_data_edit_image(C);
-       EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
-       EditFace *efa;
-       MTFace *tface;
-       
-       for(efa= em->faces.first; efa; efa= efa->next) {
-               tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-
-               if(uvedit_face_visible(scene, ima, efa, tface)) {
-                       if(tface->unwrap & TF_PIN1) uvedit_uv_select(scene, efa, tface, 0);
-                       if(tface->unwrap & TF_PIN2) uvedit_uv_select(scene, efa, tface, 1);
-                       if(tface->unwrap & TF_PIN3) uvedit_uv_select(scene, efa, tface, 2);
-                       if(efa->v4) {
-                               if(tface->unwrap & TF_PIN4) uvedit_uv_select(scene, efa, tface, 3);
-                       }
+       BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh;
+       BMFace *efa;
+       BMLoop *l;
+       BMIter iter, liter;
+       MTexPoly *tface;
+       MLoopUV *luv;
+       
+       BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+               tface= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+               if(!uvedit_face_visible(scene, ima, efa, tface))
+                       continue;
+
+               BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                       luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+                       
+                       if (luv->flag & MLOOPUV_PINNED)
+                               uvedit_uv_select(em, scene, l);
                }
        }
        
        WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
 
-       BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;
 }
 
@@ -2762,125 +2949,51 @@ static int hide_exec(bContext *C, wmOperator *op)
        SpaceImage *sima= CTX_wm_space_image(C);
        ToolSettings *ts= CTX_data_tool_settings(C);
        Object *obedit= CTX_data_edit_object(C);
-       EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
-       EditFace *efa;
-       MTFace *tf;
+       Scene *scene = CTX_data_scene(C);
+       BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh;
+       BMFace *efa;
+       BMLoop *l;
+       BMIter iter, liter;
+       MTexPoly *tf;
+       MLoopUV *luv;
        int swap= RNA_boolean_get(op->ptr, "unselected");
-       int facemode= sima ? sima->flag & SI_SELACTFACE : 0;
 
        if(ts->uv_flag & UV_SYNC_SELECTION) {
-               EM_hide_mesh(em, swap);
+               EDBM_hide_mesh(em, swap);
                WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
 
-               BKE_mesh_end_editmesh(obedit->data, em);
                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(facemode) {
-                                       /* 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(facemode) {
-                                       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);
-                                       }
+       BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+               int hide = 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);
+               BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                       luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
 
-                                       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);
-                               }
+                       if (luv->flag & MLOOPUV_VERTSEL) {
+                               hide = 1;
+                               break;
                        }
                }
+
+               if (swap)
+                       hide = !hide;
+               
+               if (hide) {
+                       BM_Select(em->bm, efa, 0);
+                       uvedit_face_deselect(scene, em, efa);
+               }
        }
        
-       /*deselects too many but ok for now*/
-       if(em->selectmode & (SCE_SELECT_EDGE|SCE_SELECT_VERTEX))
-               EM_deselect_flush(em);
+       ///*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);
+       EDBM_validate_selections(em);
        WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
 
-       BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;
 }
 
@@ -2907,114 +3020,44 @@ static int reveal_exec(bContext *C, wmOperator *op)
        SpaceImage *sima= CTX_wm_space_image(C);
        ToolSettings *ts= CTX_data_tool_settings(C);
        Object *obedit= CTX_data_edit_object(C);
-       EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
-       EditFace *efa;
-       MTFace *tf;
-       int facemode= sima ? sima->flag & SI_SELACTFACE : 0;
-       int stickymode= sima ? (sima->sticky != SI_STICKY_DISABLE) : 1;
+       Scene *scene = CTX_data_scene(C);
+       BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh;
+       BMFace *efa;
+       BMLoop *l;
+       BMVert *v;
+       BMIter iter, liter;
+       MTexPoly *tf;
+       MLoopUV *luv;
        
+       BM_ITER(v, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
+               BMINDEX_SET(v, BM_TestHFlag(v, BM_SELECT));
+       }
+
        /* call the mesh function if we are in mesh sync sel */
        if(ts->uv_flag & UV_SYNC_SELECTION) {
-               EM_reveal_mesh(em);
+               EDBM_reveal_mesh(em);
                WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
 
-               BKE_mesh_end_editmesh(obedit->data, em);
                return OPERATOR_FINISHED;
        }
-       
-       if(facemode) {
-               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(!stickymode) {
-                               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;
-                                       }
+       BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+               if (em->selectmode == SCE_SELECT_FACE) {
+                       uvedit_face_select(scene, em, efa);
+               } else {
+                       BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                               if (!BMINDEX_GET(l->v)) {
+                                       luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+                                       luv->flag |= MLOOPUV_VERTSEL;
                                }
                        }
-                       
-                       /* 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);
+               BM_Select(em->bm, efa, 1);
        }
 
        WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
 
-       BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;
 }