first pass at the uv code. uv editor now mostly uses new bmesh structures for uvs.
authorJoseph Eagar <joeedh@gmail.com>
Tue, 21 Jul 2009 08:39:58 +0000 (08:39 +0000)
committerJoseph Eagar <joeedh@gmail.com>
Tue, 21 Jul 2009 08:39:58 +0000 (08:39 +0000)
24 files changed:
source/blender/blenkernel/intern/editderivedbmesh.c
source/blender/bmesh/bmesh_queries.h
source/blender/bmesh/intern/bmesh_mesh.c
source/blender/bmesh/intern/bmesh_polygon.c
source/blender/bmesh/operators/mesh_conv.c
source/blender/editors/include/ED_mesh.h
source/blender/editors/include/ED_uvedit.h
source/blender/editors/mesh/bmesh_select.c
source/blender/editors/mesh/bmesh_tools.c
source/blender/editors/mesh/bmeshutils.c
source/blender/editors/mesh/editmesh_add.c
source/blender/editors/mesh/editmesh_mods.c
source/blender/editors/screen/Makefile
source/blender/editors/screen/SConscript
source/blender/editors/screen/screen_ops.c
source/blender/editors/space_image/Makefile
source/blender/editors/space_image/SConscript
source/blender/editors/space_image/space_image.c
source/blender/editors/transform/transform_conversions.c
source/blender/editors/uvedit/SConscript
source/blender/editors/uvedit/uvedit_draw.c
source/blender/editors/uvedit/uvedit_intern.h
source/blender/editors/uvedit/uvedit_ops.c
source/blender/makesdna/DNA_meshdata_types.h

index fa9747ec54fad99832fdd745f61be07c46fadb83..bfea160012149bf694e1bb28198936d991c1a224 100644 (file)
@@ -192,11 +192,11 @@ static void BMEdit_RecalcTesselation_intern(BMEditMesh *tm)
                                looptris[i*3+1] = efa->v2->tmp.p;
                                looptris[i*3+2] = efa->v3->tmp.p;
 
-                               if (looptris[i*3]->head.eflag2 > looptris[i*3+1]->head.eflag2);
+                               if (looptris[i*3]->head.eflag2 < looptris[i*3+1]->head.eflag2);
                                        SWAP(BMLoop*, looptris[i*3], looptris[i*3+1]);
-                               if (looptris[i*3+1]->head.eflag2 > looptris[i*3+2]->head.eflag2);
+                               if (looptris[i*3+1]->head.eflag2 < looptris[i*3+2]->head.eflag2);
                                        SWAP(BMLoop*, looptris[i*3+1], looptris[i*3+2]);
-                               if (looptris[i*3]->head.eflag2 > looptris[i*3+1]->head.eflag2);
+                               if (looptris[i*3]->head.eflag2 < looptris[i*3+1]->head.eflag2);
                                        SWAP(BMLoop*, looptris[i*3], looptris[i*3+1]);
 
                                i += 1;
index ddcd67a3bab9561ad1c47f3dca0ed6053649eda6..dc38004929e7e4e17f253f472e9fefa69735cf3d 100644 (file)
@@ -3,6 +3,10 @@
 #include <stdio.h>
 
 /*Queries*/
+
+/*get the area of face f*/
+float BM_face_area(BMFace *f);
+
 /*counts number of elements of type type are in the mesh.*/
 int BM_Count_Element(struct BMesh *bm, int type);
 
index 4339e22b45ea241d1af7331a04176292c213e32f..10aa4f2fdd46b9656efa65b14cd207f223d9fb2e 100644 (file)
@@ -164,6 +164,8 @@ void BM_Free_Mesh_Data(BMesh *bm)
        if (bm->vtar) MEM_freeN(bm->vtar);
        if (bm->plar) MEM_freeN(bm->plar);
 
+       BLI_freelistN(&bm->selected);
+
        BMO_ClearStack(bm);
 }
 
index 9df2bb8c202379e25fe83f38bec46d0d78deb95e..9d91a6d6d2975b703b14e661a343b04fc75e7713 100644 (file)
@@ -108,7 +108,7 @@ static void compute_poly_normal(float normal[3], float (*verts)[3], int nverts)
                Normalize_d(v2);
 
                l = INPR(v1, v2);
-               if (l < 0.01 && l > -0.01)
+               if (ABS(l) < 0.1)
                        continue;
 
                /* newell's method
@@ -189,6 +189,31 @@ static int compute_poly_center(float center[3], float *area, float (*verts)[3],
        return 0;
 }
 
+float BM_face_area(BMFace *f)
+{
+       BMLoop *l;
+       BMIter iter;
+       float (*verts)[3], stackv[100][3];
+       float area, center[3];
+       int i;
+
+       if (f->len <= 100) 
+               verts = stackv;
+       else verts = MEM_callocN(sizeof(float)*f->len*3, "bm_face_area tmp");
+
+       i = 0;
+       BM_ITER(l, &iter, NULL, BM_LOOPS_OF_FACE, f) {
+               VECCOPY(verts[i], l->v->co);
+               i++;
+       }
+
+       compute_poly_center(center, &area, verts, f->len);
+
+       if (f->len > 100)
+               MEM_freeN(verts);
+
+       return area;
+}
 /*
 computes center of face in 3d.  uses center of bounding box.
 */
index 9944c9b8d23e23f341096e0c11eaa2895c2f58aa..47173b356bf3d7e8f926b5fd1e310732b8c78c90 100644 (file)
@@ -244,6 +244,10 @@ void bmesh_to_mesh_exec(BMesh *bm, BMOperator *op) {
                mvert->flag = BMFlags_To_MEFlags(v);
 
                BMINDEX_SET(v, i);
+
+               /*copy over customdata*/
+               CustomData_from_bmesh_block(&bm->vdata, &me->vdata, v->head.data, i);
+
                i++;
                mvert++;
        }
@@ -262,6 +266,10 @@ void bmesh_to_mesh_exec(BMesh *bm, BMOperator *op) {
                medge->flag = BMFlags_To_MEFlags(e);
 
                BMINDEX_SET(e, i);
+
+               /*copy over customdata*/
+               CustomData_from_bmesh_block(&bm->edata, &me->edata, e->head.data, i);
+
                i++;
                medge++;
        }
@@ -308,10 +316,16 @@ void bmesh_to_mesh_exec(BMesh *bm, BMOperator *op) {
                for ( ; l; l=BMIter_Step(&liter), j++, mloop++) {
                        mloop->e = BMINDEX_GET(l->e);
                        mloop->v = BMINDEX_GET(l->v);
+
+                       /*copy over customdata*/
+                       CustomData_from_bmesh_block(&bm->ldata, &me->ldata, l->head.data, j);
                }
                
                if (f == bm->act_face) me->act_face = i;
 
+               /*copy over customdata*/
+               CustomData_from_bmesh_block(&bm->pdata, &me->pdata, f->head.data, i);
+
                i++;
                mpoly++;
        }
index dd29f2706809d5b4b6bf253aa7d37067993c42ff..8a6bce21b44e4517aa95b1b1863bbecbfeb77c1e 100644 (file)
@@ -53,6 +53,8 @@ struct BMesh;
 struct BMVert;
 struct BMEdge;
 struct BMFace;
+struct UvVertMap;
+struct UvMapVert;
 
 // edge and face flag both
 #define EM_FGON                2
@@ -78,23 +80,26 @@ struct BMFace;
 
 /* bmeshutils.c */
 
-/*this function is currently defunct, dead*/
-void EDBM_Tesselate(struct EditMesh *em);
 void EDBM_RecalcNormals(struct BMEditMesh *em);
+
 void EDBM_MakeEditBMesh(struct Scene *scene, struct Object *ob);
 void EDBM_FreeEditBMesh(struct BMEditMesh *tm);
 void EDBM_LoadEditBMesh(struct Scene *scene, struct Object *ob);
+
 void EDBM_init_index_arrays(struct BMEditMesh *tm, int forvert, int foredge, int forface);
 void EDBM_free_index_arrays(struct BMEditMesh *tm);
 struct BMVert *EDBM_get_vert_for_index(struct BMEditMesh *tm, int index);
 struct BMEdge *EDBM_get_edge_for_index(struct BMEditMesh *tm, int index);
 struct BMFace *EDBM_get_face_for_index(struct BMEditMesh *tm, int index);
 struct BMFace *EDBM_get_actFace(struct BMEditMesh *em, int sloppy);
+
 void EDBM_selectmode_flush(struct BMEditMesh *em);
 int EDBM_get_actSelection(struct BMEditMesh *em, struct BMEditSelection *ese);
+
 void EDBM_editselection_center(struct BMEditMesh *em, float *center, struct BMEditSelection *ese);
 void EDBM_editselection_plane(struct BMEditMesh *em, float *plane, struct BMEditSelection *ese);
 void EDBM_editselection_normal(float *normal, struct BMEditSelection *ese);
+
 void EDBM_selectmode_set(struct BMEditMesh *em);
 void EDBM_convertsel(struct BMEditMesh *em, short oldmode, short selectmode);
 
@@ -104,6 +109,19 @@ void               EDBM_free_backbuf(void);
 int                    EDBM_init_backbuf_border(struct ViewContext *vc, short xmin, short ymin, short xmax, short ymax);
 int                    EDBM_init_backbuf_circle(struct ViewContext *vc, short xs, short ys, short rads);
 
+void EDBM_select_swap(struct BMEditMesh *em); /* exported for UV */
+void EDBM_set_actFace(struct BMEditMesh *em, struct BMFace *efa);
+
+int EDBM_texFaceCheck(struct BMEditMesh *em);
+struct MTexPoly *EDBM_get_active_mtexpoly(struct BMEditMesh *em, struct BMFace **act_efa, int sloppy);
+
+void EDBM_free_uv_vert_map(struct UvVertMap *vmap);
+struct UvMapVert *EDBM_get_uv_map_vert(struct UvVertMap *vmap, unsigned int v);
+struct UvVertMap *EDBM_make_uv_vert_map(struct BMEditMesh *em, int selected, int do_face_idx_array, float *limit);
+
+void EDBM_toggle_select_all(struct BMEditMesh *em);
+void EDBM_set_flag_all(struct BMEditMesh *em, int flag);
+
 /* meshtools.c */
 
 intptr_t       mesh_octree_table(struct Object *ob, struct BMEditMesh *em, float *co, char mode);
index 74a9be75db6d9eb721dc4b60d84f40a57f2fc3c3..e75eb751a0b8d34be868995fdaa64ad62586d825 100644 (file)
@@ -47,10 +47,10 @@ int ED_uvedit_minmax(struct Scene *scene, struct Image *ima, struct Object *obed
 int ED_uvedit_test_silent(struct Object *obedit);
 int ED_uvedit_test(struct Object *obedit);
 
-int uvedit_face_visible(struct Scene *scene, struct Image *ima, struct EditFace *efa, struct MTFace *tf);
-int uvedit_face_selected(struct Scene *scene, struct EditFace *efa, struct MTFace *tf);
-int uvedit_edge_selected(struct Scene *scene, struct EditFace *efa, struct MTFace *tf, int i);
-int uvedit_uv_selected(struct Scene *scene, struct EditFace *efa, struct MTFace *tf, int i);
+int uvedit_face_visible(struct Scene *scene, struct Image *ima, struct BMFace *efa, struct MTexPoly *tf);
+int uvedit_face_selected(struct Scene *scene, struct BMEditMesh *em, struct BMFace *efa);
+int uvedit_edge_selected(struct BMEditMesh *em, struct Scene *scene, struct BMLoop *l);
+int uvedit_uv_selected(struct BMEditMesh *em, struct Scene *scene, struct BMLoop *l);
 
 int ED_uvedit_nearest_uv(struct Scene *scene, struct Object *obedit, struct Image *ima, float co[2], float uv[2]);
 
index 760bb5b65e0bd1839c36fe4942107fb82eb4cc97..8dee58caddb0fd12eb2885f41e30f5829cbda52f 100644 (file)
@@ -1422,3 +1422,62 @@ void EDBM_convertsel(BMEditMesh *em, short oldmode, short selectmode)
                }
        }
 }
+
+
+void EDBM_select_swap(BMEditMesh *em) /* exported for UV */
+{
+       BMIter iter;
+       BMVert *eve;
+       BMEdge *eed;
+       BMFace *efa;
+       
+       if(em->bm->selectmode & SCE_SELECT_VERTEX) {
+               BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
+                       if (BM_TestHFlag(eve, BM_HIDDEN))
+                               continue;
+                       BM_Select(em->bm, eve, !BM_TestHFlag(eve, BM_SELECT));
+               }
+       }
+       else if(em->selectmode & SCE_SELECT_EDGE) {
+               BM_ITER(eed, &iter, em->bm, BM_EDGES_OF_MESH, NULL) {
+                       if (BM_TestHFlag(eed, BM_HIDDEN))
+                               continue;
+                       BM_Select(em->bm, eed, !BM_TestHFlag(eed, BM_SELECT));
+               }
+       }
+       else {
+               BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+                       if (BM_TestHFlag(efa, BM_HIDDEN))
+                               continue;
+                       BM_Select(em->bm, efa, !BM_TestHFlag(efa, BM_SELECT));
+               }
+
+       }
+//     if (EM_texFaceCheck())
+}
+
+static int select_inverse_mesh_exec(bContext *C, wmOperator *op)
+{
+       Object *obedit= CTX_data_edit_object(C);
+       BMEditMesh *em= ((Mesh *)obedit->data)->edit_btmesh;
+       
+       EDBM_select_swap(em);
+       
+       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+
+       return OPERATOR_FINISHED;       
+}
+
+void MESH_OT_select_inverse(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Select Inverse";
+       ot->idname= "MESH_OT_select_inverse";
+       
+       /* api callbacks */
+       ot->exec= select_inverse_mesh_exec;
+       ot->poll= ED_operator_editmesh;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
index 194a3ea9ebea9a181b80fdfb72070744ffc02114..11049bc12107545a134c90dba688051eb44cf647 100644 (file)
@@ -1392,3 +1392,62 @@ void MESH_OT_edge_split(wmOperatorType *ot)
 
        RNA_def_int(ot->srna, "number_cuts", 1, 1, 10, "Number of Cuts", "", 1, INT_MAX);
 }
+
+/****************** add duplicate operator ***************/
+
+static int mesh_duplicate_exec(bContext *C, wmOperator *op)
+{
+       Scene *scene= CTX_data_scene(C);
+       Object *ob= CTX_data_edit_object(C);
+       BMEditMesh *em= ((Mesh*)ob->data)->edit_btmesh;
+       BMOperator bmop;
+
+       EDBM_InitOpf(em, &bmop, op, "dupe geom=%hvef", BM_SELECT);
+       
+       BMO_Exec_Op(em->bm, &bmop);
+       EDBM_clear_flag_all(em, BM_SELECT);
+
+       BMO_HeaderFlag_Buffer(em->bm, &bmop, "newout", BM_SELECT);
+
+       if (!EDBM_FinishOp(em, &bmop, op, 1))
+               return OPERATOR_CANCELLED;
+
+       DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, ob);
+       
+       return OPERATOR_FINISHED;
+}
+
+static int mesh_duplicate_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+       int ret;
+
+       WM_cursor_wait(1);
+       ret = mesh_duplicate_exec(C, op);
+       WM_cursor_wait(0);
+
+       if (ret == OPERATOR_CANCELLED)
+               return OPERATOR_CANCELLED;
+       
+       RNA_int_set(op->ptr, "mode", TFM_TRANSLATION);
+       WM_operator_name_call(C, "TFM_OT_transform", WM_OP_INVOKE_REGION_WIN, op->ptr);
+       
+       return OPERATOR_FINISHED;
+}
+
+void MESH_OT_duplicate(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Duplicate";
+       ot->idname= "MESH_OT_duplicate";
+       
+       /* api callbacks */
+       ot->invoke= mesh_duplicate_invoke;
+       ot->exec= mesh_duplicate_exec;
+       
+       ot->poll= ED_operator_editmesh;
+       
+       /* to give to transform */
+       RNA_def_int(ot->srna, "mode", TFM_TRANSLATION, 0, INT_MAX, "Mode", "", 0, INT_MAX);
+}
+
index 5e8c295d7b806553fe662b1fe515c0cd3bcd7ae4..71f79f7e944e7bec7c695b48550b90b734b01877 100644 (file)
@@ -521,3 +521,180 @@ void undo_push_mesh(bContext *C, char *name)
 {
        undo_editmode_push(C, name, getEditMesh, free_undo, undoMesh_to_editbtMesh, editbtMesh_to_undoMesh, NULL);
 }
+
+/*write comment here*/
+UvVertMap *EDBM_make_uv_vert_map(BMEditMesh *em, int selected, int do_face_idx_array, float *limit)
+{
+       BMVert *ev;
+       BMFace *efa;
+       BMLoop *l;
+       BMIter iter, liter;
+       /* vars from original func */
+       UvVertMap *vmap;
+       UvMapVert *buf;
+       MTexPoly *tf;
+       MLoopUV *luv;
+       unsigned int a;
+       int totverts, i, totuv;
+       
+       if (do_face_idx_array)
+               EDBM_init_index_arrays(em, 0, 0, 1);
+       
+       /* we need the vert */
+       totverts=0;
+       BM_ITER(ev, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
+               BMINDEX_SET(ev, totverts);
+               totverts++;
+       }
+       
+       totuv = 0;
+
+       /* generate UvMapVert array */
+       BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+               if(!selected || ((!BM_TestHFlag(efa, BM_HIDDEN)) && BM_TestHFlag(efa, BM_SELECT)))
+                       totuv += efa->len;
+       }
+
+       if(totuv==0) {
+               if (do_face_idx_array)
+                       EDBM_free_index_arrays(em);
+               return NULL;
+       }
+       vmap= (UvVertMap*)MEM_callocN(sizeof(*vmap), "UvVertMap");
+       if (!vmap) {
+               if (do_face_idx_array)
+                       EDBM_free_index_arrays(em);
+               return NULL;
+       }
+
+       vmap->vert= (UvMapVert**)MEM_callocN(sizeof(*vmap->vert)*totverts, "UvMapVert*");
+       buf= vmap->buf= (UvMapVert*)MEM_callocN(sizeof(*vmap->buf)*totuv, "UvMapVert");
+
+       if (!vmap->vert || !vmap->buf) {
+               free_uv_vert_map(vmap);
+               if (do_face_idx_array)
+                       EDBM_free_index_arrays(em);
+               return NULL;
+       }
+       
+       a = 0;
+       BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+               if(!selected || ((!BM_TestHFlag(efa, BM_HIDDEN)) && BM_TestHFlag(efa, BM_SELECT))) {
+                       i = 0;
+                       BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                               buf->tfindex= i;
+                               buf->f= a;
+                               buf->separate = 0;
+                               
+                               buf->next= vmap->vert[BMINDEX_GET(((BMLoop*)l->head.next)->v)];
+                               vmap->vert[BMINDEX_GET(l->v)]= buf;
+                               
+                               buf++;
+                               i++;
+                       }
+               }
+
+               a++;
+       }
+       
+       /* sort individual uvs for each vert */
+       a = 0;
+       BM_ITER(ev, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
+               UvMapVert *newvlist= NULL, *vlist=vmap->vert[a];
+               UvMapVert *iterv, *v, *lastv, *next;
+               float *uv, *uv2, uvdiff[2];
+
+               while(vlist) {
+                       v= vlist;
+                       vlist= vlist->next;
+                       v->next= newvlist;
+                       newvlist= v;
+
+                       efa = EDBM_get_face_for_index(em, v->f);
+                       tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+                       
+                       l = BMIter_AtIndex(em->bm, BM_LOOPS_OF_FACE, efa, v->tfindex);
+                       luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+                       uv = luv->uv; 
+                       
+                       lastv= NULL;
+                       iterv= vlist;
+
+                       while(iterv) {
+                               next= iterv->next;
+                               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);
+                               luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+                               uv2 = luv->uv; 
+                               
+                               Vec2Subf(uvdiff, uv2, uv);
+
+                               if(fabs(uv[0]-uv2[0]) < limit[0] && fabs(uv[1]-uv2[1]) < limit[1]) {
+                                       if(lastv) lastv->next= next;
+                                       else vlist= next;
+                                       iterv->next= newvlist;
+                                       newvlist= iterv;
+                               }
+                               else
+                                       lastv=iterv;
+
+                               iterv= next;
+                       }
+
+                       newvlist->separate = 1;
+               }
+
+               vmap->vert[a]= newvlist;
+               a++;
+       }
+       
+       if (do_face_idx_array)
+               EDBM_free_index_arrays(em);
+       
+       return vmap;
+}
+
+
+UvMapVert *EDBM_get_uv_map_vert(UvVertMap *vmap, unsigned int v)
+{
+       return vmap->vert[v];
+}
+
+void EDBM_free_uv_vert_map(UvVertMap *vmap)
+{
+       if (vmap) {
+               if (vmap->vert) MEM_freeN(vmap->vert);
+               if (vmap->buf) MEM_freeN(vmap->buf);
+               MEM_freeN(vmap);
+       }
+}
+
+
+/* last_sel, use em->act_face otherwise get the last selected face in the editselections
+ * at the moment, last_sel is mainly useful for gaking sure the space image dosnt flicker */
+MTexPoly *EDBM_get_active_mtexpoly(BMEditMesh *em, BMFace **act_efa, int sloppy)
+{
+       BMFace *efa = NULL;
+       
+       if(!EDBM_texFaceCheck(em))
+               return NULL;
+       
+       efa = EDBM_get_actFace(em, sloppy);
+       
+       if (efa) {
+               if (act_efa) *act_efa = efa; 
+               return CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+       }
+
+       if (act_efa) *act_efa= NULL;
+       return NULL;
+}
+
+/* can we edit UV's for this mesh?*/
+int EDBM_texFaceCheck(BMEditMesh *em)
+{
+       /* some of these checks could be a touch overkill */
+       return em && em->bm->totface && CustomData_has_layer(&em->bm->pdata, CD_MTEXPOLY);
+}
\ No newline at end of file
index 4b891843f5e8bdbe1eb1fcb00a52f8a07b66916a..806ef4c299e9d3a8724f36e1e752f57b8eeb1cbc 100644 (file)
@@ -1557,50 +1557,3 @@ void MESH_OT_primitive_ico_sphere_add(wmOperatorType *ot)
        RNA_def_int(ot->srna, "subdivisions", 2, 0, 6, "Subdivisions", "", 0, 8);
        RNA_def_float(ot->srna, "size", 1.0f, 0.0f, FLT_MAX, "Size", "", 0.001f, 100.00);
 }
-
-/****************** add duplicate operator ***************/
-
-static int mesh_duplicate_exec(bContext *C, wmOperator *op)
-{
-       Scene *scene= CTX_data_scene(C);
-       Object *ob= CTX_data_edit_object(C);
-       EditMesh *em= BKE_mesh_get_editmesh(ob->data);
-
-       adduplicateflag(em, SELECT);
-
-       BKE_mesh_end_editmesh(ob->data, em);
-
-       DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, ob);
-       
-       return OPERATOR_FINISHED;
-}
-
-static int mesh_duplicate_invoke(bContext *C, wmOperator *op, wmEvent *event)
-{
-       WM_cursor_wait(1);
-       mesh_duplicate_exec(C, op);
-       WM_cursor_wait(0);
-       
-       RNA_int_set(op->ptr, "mode", TFM_TRANSLATION);
-       WM_operator_name_call(C, "TFM_OT_transform", WM_OP_INVOKE_REGION_WIN, op->ptr);
-       
-       return OPERATOR_FINISHED;
-}
-
-void MESH_OT_duplicate(wmOperatorType *ot)
-{
-       /* identifiers */
-       ot->name= "Duplicate";
-       ot->idname= "MESH_OT_duplicate";
-       
-       /* api callbacks */
-       ot->invoke= mesh_duplicate_invoke;
-       ot->exec= mesh_duplicate_exec;
-       
-       ot->poll= ED_operator_editmesh;
-       
-       /* to give to transform */
-       RNA_def_int(ot->srna, "mode", TFM_TRANSLATION, 0, INT_MAX, "Mode", "", 0, INT_MAX);
-}
-
index aa7a5e6b2925568d3b97bc5d0f7682a5f73b0f4d..1d92d93442d75706144491973695f2b68de86ec5 100644 (file)
@@ -2683,69 +2683,6 @@ void MESH_OT_select_non_manifold(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
-void EM_select_swap(EditMesh *em) /* exported for UV */
-{
-       EditVert *eve;
-       EditEdge *eed;
-       EditFace *efa;
-       
-       if(em->selectmode & SCE_SELECT_VERTEX) {
-
-               for(eve= em->verts.first; eve; eve= eve->next) {
-                       if(eve->h==0) {
-                               if(eve->f & SELECT) eve->f &= ~SELECT;
-                               else eve->f|= SELECT;
-                       }
-               }
-       }
-       else if(em->selectmode & SCE_SELECT_EDGE) {
-               for(eed= em->edges.first; eed; eed= eed->next) {
-                       if(eed->h==0) {
-                               EM_select_edge(eed, !(eed->f & SELECT));
-                       }
-               }
-       }
-       else {
-               for(efa= em->faces.first; efa; efa= efa->next) {
-                       if(efa->h==0) {
-                               EM_select_face(efa, !(efa->f & SELECT));
-                       }
-               }
-       }
-
-       EM_selectmode_flush(em);
-       
-//     if (EM_texFaceCheck())
-
-}
-
-static int select_inverse_mesh_exec(bContext *C, wmOperator *op)
-{
-       Object *obedit= CTX_data_edit_object(C);
-       EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data));
-       
-       EM_select_swap(em);
-       
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
-
-       BKE_mesh_end_editmesh(obedit->data, em);
-       return OPERATOR_FINISHED;       
-}
-
-void MESH_OT_select_inverse(wmOperatorType *ot)
-{
-       /* identifiers */
-       ot->name= "Select Inverse";
-       ot->idname= "MESH_OT_select_inverse";
-       
-       /* api callbacks */
-       ot->exec= select_inverse_mesh_exec;
-       ot->poll= ED_operator_editmesh;
-       
-       /* flags */
-       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
-}
-       
 static int bmesh_test_exec(bContext *C, wmOperator *op)
 {
        return OPERATOR_FINISHED;
index 923a020afcfdedec5aa0078b81653a41567fe0de..ce6c59b69ed36bc2b168cc91514c3f5277aaa654 100644 (file)
@@ -42,6 +42,7 @@ CPPFLAGS += -I$(OPENGL_HEADERS)
 CPPFLAGS += -I../../windowmanager
 CPPFLAGS += -I../../blenloader
 CPPFLAGS += -I../../blenkernel
+CPPFLAGS += -I../../bmesh
 CPPFLAGS += -I../../blenlib
 CPPFLAGS += -I../../makesdna
 CPPFLAGS += -I../../makesrna
index 3972efd8eedd8b7a31d823921ca9d637a296b781..affc6192290987495c6923e50e6a6936bf733307 100644 (file)
@@ -5,7 +5,7 @@ sources = env.Glob('*.c')
 
 incs = '../include ../../blenlib ../../blenkernel ../../blenfont ../../makesdna ../../imbuf'
 incs += ' ../../blenloader ../../windowmanager ../../python ../../makesrna'
-incs += ' ../../render/extern/include'
+incs += ' ../../render/extern/include ../../bmesh'
 incs += ' #/intern/guardedalloc #/extern/glew/include'
 
 defs = ''
index 19cbf93a83ced756b3d125617794d1b6e838786e..8f0a60359c21be0a0d19cf2bbd37478db3b38536 100644 (file)
@@ -53,6 +53,7 @@
 #include "BKE_report.h"
 #include "BKE_screen.h"
 #include "BKE_utildefines.h"
+#include "BKE_tessmesh.h"
 
 #include "WM_api.h"
 #include "WM_types.h"
@@ -228,36 +229,27 @@ int ED_operator_posemode(bContext *C)
 int ED_operator_uvedit(bContext *C)
 {
        Object *obedit= CTX_data_edit_object(C);
-       EditMesh *em= NULL;
+       BMEditMesh *em= NULL;
 
        if(obedit && obedit->type==OB_MESH)
-               em= BKE_mesh_get_editmesh((Mesh *)obedit->data);
-
-       if(em && (em->faces.first) && (CustomData_has_layer(&em->fdata, CD_MTFACE))) {
-               BKE_mesh_end_editmesh(obedit->data, em);
+               em= ((Mesh *)obedit->data)->edit_btmesh;
+       if (em && em->bm->totface && CustomData_has_layer(&em->bm->pdata, CD_MTEXPOLY))
                return 1;
-       }
 
-       if(obedit)
-               BKE_mesh_end_editmesh(obedit->data, em);
        return 0;
 }
 
 int ED_operator_uvmap(bContext *C)
 {
        Object *obedit= CTX_data_edit_object(C);
-       EditMesh *em= NULL;
+       BMEditMesh *em= NULL;
 
        if(obedit && obedit->type==OB_MESH)
-               em= BKE_mesh_get_editmesh((Mesh *)obedit->data);
+               em= ((Mesh *)obedit->data)->edit_btmesh;
 
-       if(em && (em->faces.first)) {
-               BKE_mesh_end_editmesh(obedit->data, em);
+       if(em && (em->bm->totface))
                return 1;
-       }
 
-       if(obedit)
-               BKE_mesh_end_editmesh(obedit->data, em);
        return 0;
 }
 
index e7e9a9b5665854137dacd0f78f4ed58719171697..5a69cb7fc65d835e7f91e4928a5ee4428dae0115 100644 (file)
@@ -47,6 +47,7 @@ CPPFLAGS += -I../../makesrna
 CPPFLAGS += -I../../imbuf
 CPPFLAGS += -I../../python
 CPPFLAGS += -I../../render/extern/include
+CPPFLAGS += -I../../bmesh
 CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
 
 # own include 
index e7041ef045861b4d9562d9be00457b350a1b86f2..5fa2509bf5f0c076c8680d4d8934fff3809dbfb3 100644 (file)
@@ -5,7 +5,7 @@ sources = env.Glob('*.c')
 
 incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
 incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
-incs += ' ../../render/extern/include ../../makesrna'
+incs += ' ../../render/extern/include ../../makesrna ../../bmesh'
 
 defs = []
 
index 709fbb6299ba6f87c0030198d1d3cb2a29377088..512053490f99e38398d73be9e36bc34622b2dad0 100644 (file)
@@ -50,6 +50,7 @@
 #include "BKE_mesh.h"
 #include "BKE_screen.h"
 #include "BKE_utildefines.h"
+#include "BKE_tessmesh.h"
 
 #include "IMB_imbuf.h"
 #include "IMB_imbuf_types.h"
@@ -256,13 +257,13 @@ static void image_refresh(const bContext *C, ScrArea *sa)
        if(ima && (ima->source==IMA_SRC_VIEWER || sima->pin));
        else if(obedit && obedit->type == OB_MESH) {
                Mesh *me= (Mesh*)obedit->data;
-               EditMesh *em= BKE_mesh_get_editmesh(me);
-               MTFace *tf;
+               BMEditMesh *em= me->edit_btmesh;
+               MTexPoly *tf;
                
-               if(em && EM_texFaceCheck(em)) {
+               if(em && EDBM_texFaceCheck(em)) {
                        sima->image= ima= NULL;
                        
-                       tf = EM_get_active_mtface(em, NULL, NULL, 1); /* partially selected face is ok */
+                       tf = EDBM_get_active_mtexpoly(em, NULL, 1); /* partially selected face is ok */
                        
                        if(tf && (tf->mode & TF_TEX)) {
                                /* don't need to check for pin here, see above */
@@ -272,8 +273,6 @@ static void image_refresh(const bContext *C, ScrArea *sa)
                                else sima->curtile= tf->tile;
                        }
                }
-
-               BKE_mesh_end_editmesh(obedit->data, em);
        }
 }
 
@@ -748,13 +747,9 @@ int ED_space_image_show_uvedit(SpaceImage *sima, Object *obedit)
                return 0;
 
        if(obedit && obedit->type == OB_MESH) {
-               EditMesh *em = BKE_mesh_get_editmesh(obedit->data);
-               int ret;
-       
-               ret = EM_texFaceCheck(em);
+               BMEditMesh *em = ((Mesh*)obedit->data)->edit_btmesh;
 
-               BKE_mesh_end_editmesh(obedit->data, em);
-               return ret;
+               return EDBM_texFaceCheck(em);
        }
 
        return 0;
@@ -767,13 +762,9 @@ int ED_space_image_show_uvshadow(SpaceImage *sima, Object *obedit)
 
        if(ED_space_image_show_paint(sima))
                if(obedit && obedit->type == OB_MESH) {
-                       EditMesh *em = BKE_mesh_get_editmesh(obedit->data);
-                       int ret;
-
-                       ret = EM_texFaceCheck(em);
+                       BMEditMesh *em = ((Mesh*)obedit->data)->edit_btmesh;
 
-                       BKE_mesh_end_editmesh(obedit->data, em);
-                       return ret;
+                       return EDBM_texFaceCheck(em);
                }
 
        return 0;
index f8b66dbca216d59d1608ed3f52c9bd9d387341a1..623c6bb24c35803806451dbf031a8bac70d72889 100644 (file)
@@ -2451,36 +2451,38 @@ static void UVsToTransData(SpaceImage *sima, TransData *td, TransData2D *td2d, f
 
 static void createTransUVs(bContext *C, TransInfo *t)
 {
-#if 0
        SpaceImage *sima = (SpaceImage*)CTX_wm_space_data(C);
        Image *ima = CTX_data_edit_image(C);
        Scene *scene = CTX_data_scene(C);
        TransData *td = NULL;
        TransData2D *td2d = NULL;
-       MTFace *tf;
+       MTexPoly *tf;
+       MLoopUV *luv;
+       BMEditMesh *em = ((Mesh *)t->obedit->data)->edit_btmesh;
+       BMFace *efa;
+       BMLoop *l;
+       BMIter iter, liter;
        int count=0, countsel=0;
        int propmode = t->flag & T_PROP_EDIT;
 
-       EditMesh *em = ((Mesh *)t->obedit->data)->edit_mesh;
-       EditFace *efa;
-
        if(!ED_uvedit_test(t->obedit)) return;
 
        /* count */
-       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)) {
-                       efa->tmp.p = tf;
+               if(!uvedit_face_visible(scene, ima, efa, tf)) {
+                       BMINDEX_SET(efa, 0);
+                       continue;
+               }
+               
+               BMINDEX_SET(efa, 1);
+               BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                       if (uvedit_uv_selected(em, scene, l)) 
+                               countsel++;
 
-                       if (uvedit_uv_selected(scene, efa, tf, 0)) countsel++;
-                       if (uvedit_uv_selected(scene, efa, tf, 1)) countsel++;
-                       if (uvedit_uv_selected(scene, efa, tf, 2)) countsel++;
-                       if (efa->v4 && uvedit_uv_selected(scene, efa, tf, 3)) countsel++;
                        if(propmode)
-                               count += (efa->v4)? 4: 3;
-               } else {
-                       efa->tmp.p = NULL;
+                               count += efa->len;
                }
        }
 
@@ -2499,26 +2501,22 @@ static void createTransUVs(bContext *C, TransInfo *t)
        td= t->data;
        td2d= t->data2d;
 
-       for (efa= em->faces.first; efa; efa= efa->next) {
-               if ((tf=(MTFace *)efa->tmp.p)) {
-                       if (propmode) {
-                               UVsToTransData(sima, td++, td2d++, tf->uv[0], uvedit_uv_selected(scene, efa, tf, 0));
-                               UVsToTransData(sima, td++, td2d++, tf->uv[1], uvedit_uv_selected(scene, efa, tf, 1));
-                               UVsToTransData(sima, td++, td2d++, tf->uv[2], uvedit_uv_selected(scene, efa, tf, 2));
-                               if(efa->v4)
-                                       UVsToTransData(sima, td++, td2d++, tf->uv[3], uvedit_uv_selected(scene, efa, tf, 3));
-                       } else {
-                               if(uvedit_uv_selected(scene, efa, tf, 0))                               UVsToTransData(sima, td++, td2d++, tf->uv[0], 1);
-                               if(uvedit_uv_selected(scene, efa, tf, 1))                               UVsToTransData(sima, td++, td2d++, tf->uv[1], 1);
-                               if(uvedit_uv_selected(scene, efa, tf, 2))                               UVsToTransData(sima, td++, td2d++, tf->uv[2], 1);
-                               if(efa->v4 && uvedit_uv_selected(scene, efa, tf, 3))    UVsToTransData(sima, td++, td2d++, tf->uv[3], 1);
-                       }
+       BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+               if (!BMINDEX_GET(efa))
+                       continue;
+
+               tf= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+               BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                       if (!propmode && !uvedit_uv_selected(em, scene, l))
+                               continue;
+                       
+                       luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+                       UVsToTransData(sima, td++, td2d++, luv->uv, uvedit_uv_selected(em, scene, l));
                }
        }
 
        if (sima->flag & SI_LIVE_UNWRAP)
                ED_uvedit_live_unwrap_begin(t->scene, t->obedit);
-#endif
 }
 
 void flushTransUVs(TransInfo *t)
index b472b89d23dfe390a831fbe7c01d83294aea9590..9926eb0c7ea135a05773a627cfdfe938abaff2b8 100644 (file)
@@ -5,6 +5,6 @@ sources = env.Glob('*.c')
 
 incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
 incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
-incs += ' ../../makesrna #/intern/opennl/extern ../../gpu'
+incs += ' ../../makesrna #/intern/opennl/extern ../../gpu ../../bmesh'
 
 env.BlenderLib ( 'bf_editors_uvedit', sources, Split(incs), [], libtype=['core'], priority=[45] )
index 0a747c951f57744267c70a33bed05c2cdd7b8c54..8ec87976064e96298eb33272456497c2b2037251 100644 (file)
@@ -28,6 +28,9 @@
 #include <float.h>
 #include <math.h>
 #include <stdlib.h>
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
 
 #include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
@@ -41,7 +44,7 @@
 #include "BKE_mesh.h"
 #include "BKE_object.h"
 #include "BKE_utildefines.h"
-#include "BKE_mesh.h"
+#include "BKE_tessmesh.h"
 
 #include "BLI_arithb.h"
 #include "BLI_editVert.h"
@@ -120,34 +123,33 @@ static int draw_uvs_face_check(Scene *scene)
 
 static void draw_uvs_shadow(SpaceImage *sima, Object *obedit)
 {
-       EditMesh *em;
-       EditFace *efa;
-       MTFace *tf;
+       BMEditMesh *em;
+       BMFace *efa;
+       BMLoop *l;
+       BMIter iter, liter;
+       MLoopUV *luv;
        
-       em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
+       em= ((Mesh*)obedit->data)->edit_btmesh;
 
        /* draws the grey mesh when painting */
        glColor3ub(112, 112, 112);
 
-       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) {
                glBegin(GL_LINE_LOOP);
-                       glVertex2fv(tf->uv[0]);
-                       glVertex2fv(tf->uv[1]);
-                       glVertex2fv(tf->uv[2]);
-                       if(efa->v4) glVertex2fv(tf->uv[3]);
+               BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                       luv= CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+
+                       glVertex2fv(luv->uv);
+               }
                glEnd();
        }
-
-       BKE_mesh_end_editmesh(obedit->data, em);
 }
 
 static int draw_uvs_dm_shadow(DerivedMesh *dm)
 {
        /* draw shadow mesh - this is the mesh with the modifier applied */
 
-       if(dm && dm->drawUVEdges && CustomData_has_layer(&dm->faceData, CD_MTFACE)) {
+       if(dm && dm->drawUVEdges && CustomData_has_layer(&dm->loopData, CD_MLOOPUV)) {
                glColor3ub(112, 112, 112);
                dm->drawUVEdges(dm);
                return 1;
@@ -156,13 +158,19 @@ static int draw_uvs_dm_shadow(DerivedMesh *dm)
        return 0;
 }
 
-static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, EditMesh *em, MTFace *activetf)
+static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTexPoly *activetf)
 {
-       EditFace *efa;
-       MTFace *tf;
+       BMFace *efa;
+       BMLoop *l;
+       BMIter iter, liter;
+       MTexPoly *tf;
+       MLoopUV *luv;
        Image *ima= sima->image;
-       float aspx, aspy, col[4], tf_uv[4][2];
-       
+       V_DECLARE(tf_uv);
+       V_DECLARE(tf_uvorig);
+       float aspx, aspy, col[4], (*tf_uv)[2] = NULL, (*tf_uvorig)[2] = NULL;
+       int i;
+
        ED_space_image_uv_aspect(sima, &aspx, &aspy);
        
        switch(sima->dt_uvstretch) {
@@ -170,21 +178,37 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, EditMesh *em, MTFac
                {
                        float totarea=0.0f, totuvarea=0.0f, areadiff, uvarea, area;
                        
-                       for(efa= em->faces.first; efa; efa= efa->next) {
-                               tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-                               uv_copy_aspect(tf->uv, tf_uv, aspx, aspy);
+                       BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+                               tf= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+                               
+                               V_RESET(tf_uv);
+                               V_RESET(tf_uvorig);
+                               
+                               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);
+                                       V_GROW(tf_uv);
+                                       V_GROW(tf_uvorig);
+
+                                       tf_uvorig[i][0] = luv->uv[0];
+                                       tf_uvorig[i][1] = luv->uv[1];
 
-                               totarea += EM_face_area(efa);
+                                       i++;
+                               }
+
+                               poly_copy_aspect(tf_uvorig, tf_uv, aspx, aspy, efa->len);
+
+                               totarea += BM_face_area(efa);
                                //totuvarea += tf_area(tf, efa->v4!=0);
-                               totuvarea += uv_area(tf_uv, efa->v4!=0);
+                               totuvarea += poly_uv_area(tf_uv, efa->len);
                                
                                if(uvedit_face_visible(scene, ima, efa, tf)) {
-                                       efa->tmp.p = tf;
+                                       BMINDEX_SET(efa, 1);
                                }
                                else {
                                        if(tf == activetf)
                                                activetf= NULL;
-                                       efa->tmp.p = NULL;
+                                       BMINDEX_SET(efa, 0);
                                }
                        }
                        
@@ -192,24 +216,41 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, EditMesh *em, MTFac
                                col[0] = 1.0;
                                col[1] = col[2] = 0.0;
                                glColor3fv(col);
-                               for(efa= em->faces.first; efa; efa= efa->next) {
-                                       if((tf=(MTFace *)efa->tmp.p)) {
-                                               glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
-                                                       glVertex2fv(tf->uv[0]);
-                                                       glVertex2fv(tf->uv[1]);
-                                                       glVertex2fv(tf->uv[2]);
-                                                       if(efa->v4) glVertex2fv(tf->uv[3]);
+                               BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+                                       if(BMINDEX_GET(efa)) {
+                                               glBegin(GL_POLYGON);
+                                               BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                                                       luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+                                                       glVertex2fv(luv->uv);
+                                               }
                                                glEnd();
                                        }
                                }
                        }
                        else {
-                               for(efa= em->faces.first; efa; efa= efa->next) {
-                                       if((tf=(MTFace *)efa->tmp.p)) {
-                                               area = EM_face_area(efa) / totarea;
-                                               uv_copy_aspect(tf->uv, tf_uv, aspx, aspy);
+                               BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+                                       if(BMINDEX_GET(efa)) {
+                                               area = BM_face_area(efa) / totarea;
+
+                                               V_RESET(tf_uv);
+                                               V_RESET(tf_uvorig);
+
+                                               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);
+                                                       V_GROW(tf_uv);
+                                                       V_GROW(tf_uvorig);
+
+                                                       tf_uvorig[i][0] = luv->uv[0];
+                                                       tf_uvorig[i][1] = luv->uv[1];
+
+                                                       i++;
+                                               }
+
+                                               poly_copy_aspect(tf_uvorig, tf_uv, aspx, aspy, efa->len);
+
                                                //uvarea = tf_area(tf, efa->v4!=0) / totuvarea;
-                                               uvarea = uv_area(tf_uv, efa->v4!=0) / totuvarea;
+                                               uvarea = poly_uv_area(tf_uv, efa->len) / totuvarea;
                                                
                                                if(area < FLT_EPSILON || uvarea < FLT_EPSILON)
                                                        areadiff = 1.0;
@@ -221,11 +262,11 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, EditMesh *em, MTFac
                                                weight_to_rgb(areadiff, col, col+1, col+2);
                                                glColor3fv(col);
                                                
-                                               glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
-                                                       glVertex2fv(tf->uv[0]);
-                                                       glVertex2fv(tf->uv[1]);
-                                                       glVertex2fv(tf->uv[2]);
-                                                       if(efa->v4) glVertex2fv(tf->uv[3]);
+                                               glBegin(GL_POLYGON);
+                                               BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                                                       luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+                                                       glVertex2fv(luv->uv);
+                                               }
                                                glEnd();
                                        }
                                }
@@ -234,6 +275,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, EditMesh *em, MTFac
                }
                case SI_UVDT_STRETCH_ANGLE:
                {
+#if 0 //BMESH_TODO
                        float uvang1,uvang2,uvang3,uvang4;
                        float ang1,ang2,ang3,ang4;
                        float av1[3], av2[3], av3[3], av4[3]; /* use for 2d and 3d  angle vectors */
@@ -244,7 +286,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, EditMesh *em, MTFac
                        glShadeModel(GL_SMOOTH);
                        
                        for(efa= em->faces.first; efa; efa= efa->next) {
-                               tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+                               tf= CustomData_em_get(&em->fdata, efa->head.data, CD_MTFACE);
                                
                                if(uvedit_face_visible(scene, ima, efa, tf)) {
                                        efa->tmp.p = tf;
@@ -375,11 +417,13 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, EditMesh *em, MTFac
 
                        glShadeModel(GL_FLAT);
                        break;
+
+#endif
                }
        }
 }
 
-static void draw_uvs_other(SpaceImage *sima, Scene *scene, Object *obedit, MTFace *activetf)
+static void draw_uvs_other(SpaceImage *sima, Scene *scene, Object *obedit, MTexPoly *activetf)
 {
        Base *base;
        Image *curimage;
@@ -399,17 +443,19 @@ static void draw_uvs_other(SpaceImage *sima, Scene *scene, Object *obedit, MTFac
                        Mesh *me= ob->data;
 
                        if(me->mtface) {
-                               MFace *mface= me->mface;
-                               MTFace *tface= me->mtface;
-                               int a;
+                               MPoly *mface= me->mpoly;
+                               MTexPoly *tface= me->mtpoly;
+                               MLoopUV *mloopuv;
+                               int a, b;
 
-                               for(a=me->totface; a>0; a--, tface++, mface++) {
+                               for(a=me->totpoly; a>0; a--, tface++, mface++) {
                                        if(tface->tpage == curimage) {
                                                glBegin(GL_LINE_LOOP);
-                                               glVertex2fv(tface->uv[0]);
-                                               glVertex2fv(tface->uv[1]);
-                                               glVertex2fv(tface->uv[2]);
-                                               if(mface->v4) glVertex2fv(tface->uv[3]);
+
+                                               mloopuv = me->mloopuv + mface->loopstart;
+                                               for (b=0; b<mface->totloop; b++, mloopuv++) {
+                                                       glVertex2fv(mloopuv->uv);
+                                               }
                                                glEnd();
                                        }
                                }
@@ -423,18 +469,22 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
 {
        ToolSettings *ts;
        Mesh *me= obedit->data;
-       EditMesh *em;
-       EditFace *efa, *efa_act;
-       MTFace *tf, *activetf = NULL;
+       BMEditMesh *em;
+       BMFace *efa, *efa_act, *activef;
+       BMLoop *l;
+       BMIter iter, liter;
+       MTexPoly *tf, *activetf = NULL;
+       MLoopUV *luv;
        DerivedMesh *finaldm, *cagedm;
        char col1[4], col2[4];
        float pointsize;
        int drawfaces, interpedges, lastsel, sel;
+       int i;
        Image *ima= sima->image;
        
-       em= BKE_mesh_get_editmesh(me);
-       activetf= EM_get_active_mtface(em, &efa_act, NULL, 0); /* will be set to NULL if hidden */
-
+       em= me->edit_btmesh;
+       activetf= EDBM_get_active_mtexpoly(em, &efa_act, 0); /* will be set to NULL if hidden */
+       activef = EDBM_get_actFace(em, 0);
        ts= scene->toolsettings;
 
        drawfaces= draw_uvs_face_check(scene);
@@ -478,45 +528,46 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
                glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
                glEnable(GL_BLEND);
                
-               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)) {
-                               efa->tmp.p = tf;
-                               if(tf==activetf) continue; /* important the temp pointer is set above */
+                               BMINDEX_SET(efa, 1);
+                               if(tf==activetf) continue; /* important the temp boolean is set above */
 
-                               if(uvedit_face_selected(scene, efa, tf))
+                               if(uvedit_face_selected(scene, em, efa))
                                        glColor4ubv((GLubyte *)col2);
                                else
                                        glColor4ubv((GLubyte *)col1);
-                                       
-                               glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
-                                       glVertex2fv(tf->uv[0]);
-                                       glVertex2fv(tf->uv[1]);
-                                       glVertex2fv(tf->uv[2]);
-                                       if(efa->v4) glVertex2fv(tf->uv[3]);
+                               
+                               glBegin(GL_POLYGON);
+                               BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                                       luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+                                       glVertex2fv(luv->uv);
+                               }
                                glEnd();
                        }
                        else {
                                if(tf == activetf)
                                        activetf= NULL;
-                               efa->tmp.p = NULL;
+                               BMINDEX_SET(efa, 0);
                        }
                }
                glDisable(GL_BLEND);
        }
        else {
                /* would be nice to do this within a draw loop but most below are optional, so it would involve too many checks */
-               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)) {          
-                               efa->tmp.p = tf;
+                               BMINDEX_SET(efa, 1);
                        }
                        else {
                                if(tf == activetf)
                                        activetf= NULL;
-                               efa->tmp.p = NULL;
+                               BMINDEX_SET(efa, 0);
                        }
                }
                
@@ -524,7 +575,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
        
        /* 3. draw active face stippled */
 
-       if(activetf) {
+       if(activef) {
                glEnable(GL_BLEND);
                glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
                UI_ThemeColor4(TH_EDITMESH_ACTIVE);
@@ -532,11 +583,11 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
                glEnable(GL_POLYGON_STIPPLE);
                glPolygonStipple(stipple_quarttone);
 
-               glBegin(efa_act->v4? GL_QUADS: GL_TRIANGLES);
-                       glVertex2fv(activetf->uv[0]);
-                       glVertex2fv(activetf->uv[1]);
-                       glVertex2fv(activetf->uv[2]);
-                       if(efa_act->v4) glVertex2fv(activetf->uv[3]);
+               glBegin(GL_POLYGON);
+               BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, activef) {
+                       luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+                       glVertex2fv(luv->uv);
+               }
                glEnd();
 
                glDisable(GL_POLYGON_STIPPLE);
@@ -553,39 +604,38 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
        
        switch(sima->dt_uv) {
                case SI_UVDT_DASH:
-                       for(efa= em->faces.first; efa; efa= efa->next) {
-                               tf= (MTFace *)efa->tmp.p; /* visible faces cached */
+                       BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+                               if (!BMINDEX_GET(efa))
+                                       continue;
+                               tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
 
                                if(tf) {
                                        cpack(0x111111);
 
                                        glBegin(GL_LINE_LOOP);
-                                               glVertex2fv(tf->uv[0]);
-                                               glVertex2fv(tf->uv[1]);
-                                               glVertex2fv(tf->uv[2]);
-                                               if(efa->v4) glVertex2fv(tf->uv[3]);
+                                       BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                                               luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+                                               glVertex2fv(luv->uv);
+                                       }
                                        glEnd();
-                               
+
                                        setlinestyle(2);
                                        cpack(0x909090);
 
-                                       glBegin(GL_LINE_STRIP);
-                                               glVertex2fv(tf->uv[0]);
-                                               glVertex2fv(tf->uv[1]);
-                                       glEnd();
-               
-                                       glBegin(GL_LINE_STRIP);
-                                               glVertex2fv(tf->uv[0]);
-                                               if(efa->v4) glVertex2fv(tf->uv[3]);
-                                               else glVertex2fv(tf->uv[2]);
-                                       glEnd();
-               
-                                       glBegin(GL_LINE_STRIP);
-                                               glVertex2fv(tf->uv[1]);
-                                               glVertex2fv(tf->uv[2]);
-                                               if(efa->v4) glVertex2fv(tf->uv[3]);
+                                       glBegin(GL_LINE_LOOP);
+                                       BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                                               luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+                                               glVertex2fv(luv->uv);
+                                       }
                                        glEnd();
 
+                                       /*glBegin(GL_LINE_STRIP);
+                                               luv = CustomData_bmesh_get(&em->bm->ldata, efa->loopbase->head.data, CD_MLOOPUV);
+                                               glVertex2fv(luv->uv);
+                                               luv = CustomData_bmesh_get(&em->bm->ldata, efa->loopbase->head.next->data, CD_MLOOPUV);
+                                               glVertex2fv(luv->uv);
+                                       glEnd();*/
+
                                        setlinestyle(0);
                                }
                        }
@@ -595,34 +645,32 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
                        if(sima->dt_uv==SI_UVDT_WHITE) glColor3f(1.0f, 1.0f, 1.0f);
                        else glColor3f(0.0f, 0.0f, 0.0f);
 
-                       for(efa= em->faces.first; efa; efa= efa->next) {
-                               tf= (MTFace *)efa->tmp.p; /* visible faces cached */
+                       BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+                               if (!BMINDEX_GET(efa))
+                                       continue;
 
-                               if(tf) {
-                                       glBegin(GL_LINE_LOOP);
-                                               glVertex2fv(tf->uv[0]);
-                                               glVertex2fv(tf->uv[1]);
-                                               glVertex2fv(tf->uv[2]);
-                                               if(efa->v4) glVertex2fv(tf->uv[3]);
-                                       glEnd();
+                               glBegin(GL_LINE_LOOP);
+                               BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                                       luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+                                       glVertex2fv(luv->uv);
                                }
+                               glEnd();
                        }
                        break;
                case SI_UVDT_OUTLINE:
                        glLineWidth(3);
                        cpack(0x0);
                        
-                       for(efa= em->faces.first; efa; efa= efa->next) {
-                               tf= (MTFace *)efa->tmp.p; /* visible faces cached */
-
-                               if(tf) {
-                                       glBegin(GL_LINE_LOOP);
-                                               glVertex2fv(tf->uv[0]);
-                                               glVertex2fv(tf->uv[1]);
-                                               glVertex2fv(tf->uv[2]);
-                                               if(efa->v4) glVertex2fv(tf->uv[3]);
-                                       glEnd();
+                       BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+                               if (!BMINDEX_GET(efa))
+                                       continue;
+
+                               glBegin(GL_LINE_LOOP);
+                               BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                                       luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+                                       glVertex2fv(luv->uv);
                                }
+                               glEnd();
                        }
                        
                        glLineWidth(1);
@@ -636,83 +684,60 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
                                if(interpedges) {
                                        glShadeModel(GL_SMOOTH);
 
-                                       for(efa= em->faces.first; efa; efa= efa->next) {
-                                               tf= (MTFace *)efa->tmp.p; /* visible faces cached */
+                                       BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+                                               if (!BMINDEX_GET(efa))
+                                                       continue;
 
-                                               if(tf) {
-                                                       glBegin(GL_LINE_LOOP);
-                                                       sel = (uvedit_uv_selected(scene, efa, tf, 0)? 1 : 0);
-                                                       if(sel != lastsel) { glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2); lastsel = sel; }
-                                                       glVertex2fv(tf->uv[0]);
-                                                       
-                                                       sel = uvedit_uv_selected(scene, efa, tf, 1)? 1 : 0;
-                                                       if(sel != lastsel) { glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2); lastsel = sel; }
-                                                       glVertex2fv(tf->uv[1]);
-                                                       
-                                                       sel = uvedit_uv_selected(scene, efa, tf, 2)? 1 : 0;
+                                               glBegin(GL_LINE_LOOP);
+                                               i = 0;
+                                               BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                                                       sel = (uvedit_uv_selected(em, scene, l)? 1 : 0);
                                                        if(sel != lastsel) { glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2); lastsel = sel; }
-                                                       glVertex2fv(tf->uv[2]);
-                                                       
-                                                       if(efa->v4) {
-                                                               sel = uvedit_uv_selected(scene, efa, tf, 3)? 1 : 0;
-                                                               if(sel != lastsel) { glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2); lastsel = sel; }
-                                                               glVertex2fv(tf->uv[3]);
-                                                       }
-                                                       
-                                                       glEnd();
+
+                                                       luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+                                                       glVertex2fv(luv->uv);
+                                                       luv = CustomData_bmesh_get(&em->bm->ldata, l->head.next->data, CD_MLOOPUV);
+                                                       glVertex2fv(luv->uv);
+                                                       i += 1;
                                                }
+                                               glEnd();
                                        }
 
                                        glShadeModel(GL_FLAT);
                                }
                                else {
-                                       for(efa= em->faces.first; efa; efa= efa->next) {
-                                               tf= (MTFace *)efa->tmp.p; /* visible faces cached */
+                                       BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+                                               if (!BMINDEX_GET(efa))
+                                                       continue;
 
-                                               if(tf) {
-                                                       glBegin(GL_LINES);
-                                                       sel = (uvedit_edge_selected(scene, efa, tf, 0)? 1 : 0);
-                                                       if(sel != lastsel) { glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2); lastsel = sel; }
-                                                       glVertex2fv(tf->uv[0]);
-                                                       glVertex2fv(tf->uv[1]);
-                                                       
-                                                       sel = uvedit_edge_selected(scene, efa, tf, 1)? 1 : 0;
-                                                       if(sel != lastsel) { glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2); lastsel = sel; }
-                                                       glVertex2fv(tf->uv[1]);
-                                                       glVertex2fv(tf->uv[2]);
-                                                       
-                                                       sel = uvedit_edge_selected(scene, efa, tf, 2)? 1 : 0;
+                                               glBegin(GL_LINE_LOOP);
+                                               i = 0;
+                                               BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                                                       sel = (uvedit_edge_selected(em, scene, l)? 1 : 0);
                                                        if(sel != lastsel) { glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2); lastsel = sel; }
-                                                       glVertex2fv(tf->uv[2]);
-                                                       
-                                                       if(efa->v4) {
-                                                               glVertex2fv(tf->uv[3]);
-
-                                                               sel = uvedit_edge_selected(scene, efa, tf, 3)? 1 : 0;
-                                                               if(sel != lastsel) { glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2); lastsel = sel; }
-                                                               glVertex2fv(tf->uv[3]);
-                                                       }
-
-                                                       glVertex2fv(tf->uv[0]);
-                                                       
-                                                       glEnd();
+
+                                                       luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+                                                       glVertex2fv(luv->uv);
+                                                       luv = CustomData_bmesh_get(&em->bm->ldata, l->head.next->data, CD_MLOOPUV);
+                                                       glVertex2fv(luv->uv);
+                                                       i += 1;
                                                }
+                                               glEnd();
                                        }
                                }
                        }
                        else {
                                /* no nice edges */
-                               for(efa= em->faces.first; efa; efa= efa->next) {
-                                       tf= (MTFace *)efa->tmp.p; /* visible faces cached */
-
-                                       if(tf) {
-                                               glBegin(GL_LINE_LOOP);
-                                                       glVertex2fv(tf->uv[0]);
-                                                       glVertex2fv(tf->uv[1]);
-                                                       glVertex2fv(tf->uv[2]);
-                                                       if(efa->v4) glVertex2fv(tf->uv[3]);
-                                               glEnd();
+                               BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+                                       if (!BMINDEX_GET(efa))
+                                               continue;
+                               
+                                       glBegin(GL_LINE_LOOP);
+                                       BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
+                                               luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+                                               glVertex2fv(luv->uv);
                                        }
+                                       glEnd();
                                }
                        }
                        
@@ -736,11 +761,12 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
                UI_ThemeColor(TH_WIRE);
 
                bglBegin(GL_POINTS);
-               for(efa= em->faces.first; efa; efa= efa->next) {
-                       tf= (MTFace *)efa->tmp.p; /* visible faces cached */
+               BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+                       if (!BMINDEX_GET(efa))
+                               continue;
 
-                       if(tf && !uvedit_face_selected(scene, efa, tf)) {
-                               uv_center(tf->uv, cent, efa->v4 != NULL);
+                       if(!uvedit_face_selected(scene, em, efa)) {
+                               poly_uv_center(em, efa, cent);
                                bglVertex2fv(cent);
                        }
                }
@@ -750,11 +776,12 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
                UI_ThemeColor(TH_FACE_DOT);
 
                bglBegin(GL_POINTS);
-               for(efa= em->faces.first; efa; efa= efa->next) {
-                       tf= (MTFace *)efa->tmp.p; /* visible faces cached */
+               BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+                       if (!BMINDEX_GET(efa))
+                               continue;
 
-                       if(tf && uvedit_face_selected(scene, efa, tf)) {
-                               uv_center(tf->uv, cent, efa->v4 != NULL);
+                       if(uvedit_face_selected(scene, em, efa)) {
+                               poly_uv_center(em, efa, cent);
                                bglVertex2fv(cent);
                        }
                }
@@ -770,18 +797,14 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
                glPointSize(pointsize);
        
                bglBegin(GL_POINTS);
-               for(efa= em->faces.first; efa; efa= efa->next) {
-                       tf= (MTFace *)efa->tmp.p; /* visible faces cached */
-
-                       if(tf) {
-                               if(!uvedit_uv_selected(scene, efa, tf, 0))
-                                       bglVertex2fv(tf->uv[0]);
-                               if(!uvedit_uv_selected(scene, efa, tf, 1))
-                                       bglVertex2fv(tf->uv[1]);
-                               if(!uvedit_uv_selected(scene, efa, tf, 2))
-                                       bglVertex2fv(tf->uv[2]);
-                               if(efa->v4 && !uvedit_uv_selected(scene, efa, tf, 3))
-                                       bglVertex2fv(tf->uv[3]);
+               BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+                       if (!BMINDEX_GET(efa))
+                               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(!uvedit_uv_selected(em, scene, l))
+                                       bglVertex2fv(luv->uv);
                        }
                }
                bglEnd();
@@ -792,46 +815,39 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
                cpack(0xFF);
        
                bglBegin(GL_POINTS);
-               for(efa= em->faces.first; efa; efa= efa->next) {
-                       tf= (MTFace *)efa->tmp.p; /* visible faces cached */
-
-                       if(tf) {
-                               if(tf->unwrap & TF_PIN1)
-                                       bglVertex2fv(tf->uv[0]);
-                               if(tf->unwrap & TF_PIN2)
-                                       bglVertex2fv(tf->uv[1]);
-                               if(tf->unwrap & TF_PIN3)
-                                       bglVertex2fv(tf->uv[2]);
-                               if(efa->v4 && (tf->unwrap & TF_PIN4))
-                                       bglVertex2fv(tf->uv[3]);
+               BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+                       if (!BMINDEX_GET(efa))
+                               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)
+                                       bglVertex2fv(luv->uv);
                        }
                }
                bglEnd();
        
                /* selected uvs */
                UI_ThemeColor(TH_VERTEX_SELECT);
-           glPointSize(pointsize);
+               glPointSize(pointsize);
        
                bglBegin(GL_POINTS);
-               for(efa= em->faces.first; efa; efa= efa->next) {
-                       tf= (MTFace *)efa->tmp.p; /* visible faces cached */
-
-                       if(tf) {
-                               if(uvedit_uv_selected(scene, efa, tf, 0))
-                                       bglVertex2fv(tf->uv[0]);
-                               if(uvedit_uv_selected(scene, efa, tf, 1))
-                                       bglVertex2fv(tf->uv[1]);
-                               if(uvedit_uv_selected(scene, efa, tf, 2))
-                                       bglVertex2fv(tf->uv[2]);
-                               if(efa->v4 && uvedit_uv_selected(scene, efa, tf, 3))
-                                       bglVertex2fv(tf->uv[3]);
+               BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+                       if (!BMINDEX_GET(efa))
+                               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(uvedit_uv_selected(em, scene, l))
+                                       bglVertex2fv(luv->uv);
                        }
                }
                bglEnd();       
        }
 
        glPointSize(1.0);
-       BKE_mesh_end_editmesh(obedit->data, em);
 }
 
 void draw_uvedit_main(SpaceImage *sima, ARegion *ar, Scene *scene, Object *obedit)
index cca357c86858a3afe2f5f5b4dd5ede016f191bdc..a203fc9b55bd31e18e5ad947ab13e141def2c353 100644 (file)
 #define ED_UVEDIT_INTERN_H
 
 struct SpaceImage;
-struct EditFace;
-struct MTFace;
+struct MTexPoly;
 struct Scene;
 struct Image;
 struct Object;
 struct wmOperatorType;
+struct BMEditMesh;
+struct BMFace;
+struct BMLoop;
+struct BMEdge;
+struct BMVert;
 
 #define UV_SELECT_ALL       1
 #define UV_SELECT_PINNED    2
@@ -45,26 +49,28 @@ struct wmOperatorType;
 #define TF_SEL_MASK(id) (TF_SEL1 << id)
 
 /* visibility and selection */
-int uvedit_face_visible_nolocal(struct Scene *scene, struct EditFace *efa);
-int uvedit_face_visible(struct Scene *scene, struct Image *ima, struct EditFace *efa, struct MTFace *tf);
+int uvedit_face_visible_nolocal(struct Scene *scene, struct BMFace *efa);
 
-int uvedit_face_selected(struct Scene *scene, struct EditFace *efa, struct MTFace *tf);
-void uvedit_face_select(struct Scene *scene, struct EditFace *efa, struct MTFace *tf);
-void uvedit_face_deselect(struct Scene *scene, struct EditFace *efa, struct MTFace *tf);
+/*all the uvedit_xxxx_[de]selected functions are
+   declared in ED_uvedit.h*/
+int uvedit_face_select(struct Scene *scene, struct BMEditMesh *em, struct BMFace *efa);
+int uvedit_face_deselect(struct Scene *scene, struct BMEditMesh *em, struct BMFace *efa);
 
-int uvedit_edge_selected(struct Scene *scene, struct EditFace *efa, struct MTFace *tf, int i);
-void uvedit_edge_select(struct Scene *scene, struct EditFace *efa, struct MTFace *tf, int i);
-void uvedit_edge_deselect(struct Scene *scene, struct EditFace *efa, struct MTFace *tf, int i);
+void uvedit_edge_select(struct BMEditMesh *em, struct Scene *scene, struct BMLoop *l);
+void uvedit_edge_deselect(struct BMEditMesh *em, struct Scene *scene, struct BMLoop *l);
 
-int uvedit_uv_selected(struct Scene *scene, struct EditFace *efa, struct MTFace *tf, int i);
-void uvedit_uv_select(struct Scene *scene, struct EditFace *efa, struct MTFace *tf, int i);
-void uvedit_uv_deselect(struct Scene *scene, struct EditFace *efa, struct MTFace *tf, int i);
+void uvedit_uv_select(struct BMEditMesh *em, struct Scene *scene, struct BMLoop *l);
+void uvedit_uv_deselect(struct BMEditMesh *em, struct Scene *scene, struct BMLoop *l);
 
 /* geometric utilities */
 void uv_center(float uv[][2], float cent[2], int quad);
 float uv_area(float uv[][2], int quad);
 void uv_copy_aspect(float uv_orig[][2], float uv[][2], float aspx, float aspy);
 
+float poly_uv_area(float uv[][2], int len);
+void poly_copy_aspect(float uv_orig[][2], float uv[][2], float aspx, float aspy, int len);
+void poly_uv_center(struct BMEditMesh *em, struct BMFace *f, float cent[2]);
+
 /* operators */
 void UV_OT_average_islands_scale(struct wmOperatorType *ot);
 void UV_OT_cube_project(struct wmOperatorType *ot);
index 6f8d710ed3eb6fb85a6804ca0b189b95e8bb2124..ddae9fc075b9ccaf0d8f00360d94050b66a49747 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_mesh_types.h"
 #include "DNA_meshdata_types.h"
+#include "DNA_image_types.h"
 #include "DNA_space_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_screen_types.h"
@@ -53,6 +55,7 @@
 #include "BKE_mesh.h"
 #include "BKE_report.h"
 #include "BKE_utildefines.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->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;
 }
@@ -91,9 +95,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... */
@@ -104,21 +109,20 @@ 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_MTFACE);
                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) {
@@ -140,17 +144,16 @@ void ED_uvedit_assign_image(Scene *scene, Object *obedit, Image *ima, Image *pre
        /* and update depdency graph */
        if(update)
                DAG_object_flush_update(scene, obedit, 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))
@@ -160,18 +163,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_object_flush_update(scene, obedit, OB_RECALC_DATA);
        WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit);
-       BKE_mesh_end_editmesh(obedit->data, em);
 }
 
 /*********************** space conversion *********************/
@@ -188,18 +190,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)
@@ -208,134 +209,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->head.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->head.next->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->head.next->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->head.next->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)
 {
@@ -357,6 +440,28 @@ float uv_area(float uv[][2], int quad)
                return AreaF2Dfl(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 AreaF2Dfl(uv[0], uv[1], uv[2]) + AreaF2Dfl(uv[0], uv[2], uv[3]); 
+       else
+               return AreaF2Dfl(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;
@@ -374,33 +479,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;
        
@@ -411,14 +525,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;
+                               }
                        }
                }
        }
@@ -427,108 +545,140 @@ 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;
-
-                       for(i=0; i<nverts; i++) {
-                               dist= PdistVL2Dfl(co, tf->uv[i], tf->uv[(i+1)%nverts]);
+       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->head.next->data, CD_MLOOPUV);
 
-                               if(dist < mindist) {
-                                       hit->tf= tf;
-                                       hit->efa= efa;
-                                       hit->edge= i;
-                                       mindist= dist;
+                       dist= PdistVL2Dfl(co, luv->uv, nextluv->uv);
 
-                                       hit->vert= (*(&efa->v1 + i))->tmp.l;
-                                       hit->vert2= (*(&efa->v1 + ((i+1)%nverts)))->tmp.l;
-                               }
+                       if(dist < mindist) {
+                               hit->tf= tf;
+                               hit->efa= efa;
+                               
+                               hit->l = l;
+                               hit->nextl = (BMLoop*)l->head.next;
+                               hit->luv = luv;
+                               hit->nextluv = nextluv;
+                               hit->lindex = i;
+                               hit->vert1 = BMINDEX_GET(hit->l->v);
+                               hit->vert2 = BMINDEX_GET(((BMLoop*)hit->l->head.next)->v);
                        }
+
+                       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;
+       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);
 
-                       for(i=0; i<nverts; i++) {
-                               cent[0] += tf->uv[i][0];
-                               cent[1] += tf->uv[i][1];
-                       }
+                       cent[0] += luv->uv[0];
+                       cent[1] += luv->uv[1];
+               }
 
-                       cent[0] /= nverts;
-                       cent[1] /= nverts;
-                       dist= fabs(co[0]- cent[0]) + fabs(co[1]- cent[1]);
+               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;
-                       }
+               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];
-       Vec2Subf(v1, tf->uv[id1], tf->uv[id]);
-       Vec2Subf(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++;
+       }
+
+       VecSubf(v1, uv1, uv);
+       VecSubf(v2, uv3, uv);
 
        /* m and v2 on same side of v-v1? */
        c1= v1[0]*m[1] - v1[1]*m[0];
@@ -544,83 +694,98 @@ 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;
 
        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->head.next;
+                               hit->luv = luv;
+                               hit->nextluv = CustomData_bmesh_get(&em->bm->ldata, l->head.next->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;
 }
 
@@ -642,26 +807,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 */
@@ -675,8 +842,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++;
@@ -700,8 +867,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;
                        }
                }
@@ -710,41 +877,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->vert1);
+       iterv2= uv_vertex_map_get(vmap, hit->efa, (hit->vert1+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;
@@ -755,11 +928,12 @@ 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);
@@ -767,9 +941,9 @@ static int select_edgeloop(Scene *scene, Image *ima, EditMesh *em, NearestHit *h
 
                                        /* 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);
@@ -782,16 +956,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= efa->len;
+       iterv1= uv_vertex_map_get(vmap, hit->efa, hit->vert1);
+       iterv2= uv_vertex_map_get(vmap, hit->efa, (hit->vert1+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;
@@ -799,66 +971,82 @@ 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_em_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, j, stacksize= 0, *stack;
        char *flag;
 
-       vmap= EM_make_uv_vert_map(em, 1, 1, limit);
+       vmap= EDBM_make_uv_vert_map(em, 1, 1, limit);
        if(vmap == NULL)
                return;
 
-       stack= MEM_mallocN(sizeof(*stack)* BLI_countlist(&em->faces), "UvLinkStack");
-       flag= MEM_callocN(sizeof(*flag)*BLI_countlist(&em->faces), "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++;
                }
        }
 
@@ -866,15 +1054,21 @@ static void select_linked(Scene *scene, Image *ima, EditMesh *em, float limit[2]
                stacksize--;
                a= stack[stacksize];
                
-               for(j=0, efa= em->faces.first; efa; efa= efa->next, j++)
+               j = 0;
+               BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
                        if(j==a)
                                break;
 
-               nverts= efa->v4? 4: 3;
+                       j++;
+               }
+
+               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;
 
@@ -890,56 +1084,74 @@ static void select_linked(Scene *scene, Image *ima, EditMesh *em, float limit[2]
                                        break;
                                else if(!flag[iterv->f]) {
                                        flag[iterv->f]= 1;
-                                       stack[stacksize]= iterv->f;;
+                                       stack[stacksize]= iterv->f;
                                        stacksize++;
                                }
                        }
+
+                       i++;
                }
        }
 
-       if(!extend || hit) {
-               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 if(extend && hit) {
-               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);
+       EDBM_free_uv_vert_map(vmap);
 }
 
 /* ******************** mirror operator **************** */
@@ -993,31 +1205,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)
+                               }
                        }
                }
 
@@ -1027,41 +1241,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_object_flush_update(scene, obedit, OB_RECALC_DATA);
        WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit);
-
-       BKE_mesh_end_editmesh(obedit->data, em);
 }
 
 static int align_exec(bContext *C, wmOperator *op)
@@ -1126,16 +1338,19 @@ 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= (SpaceImage*)CTX_wm_space_data(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")) {
@@ -1147,15 +1362,15 @@ static int stitch_exec(bContext *C, wmOperator *op)
                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) {
+               
+               a = 0;
+               BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
                        vlist= EM_get_uv_map_vert(vmap, a);
 
                        while(vlist) {
@@ -1166,12 +1381,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++;
                                        }
                                }
@@ -1183,95 +1401,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;
                                }
                        }
                }
@@ -1282,7 +1477,6 @@ static int stitch_exec(bContext *C, wmOperator *op)
        DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
        WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit);
 
-       BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;
 }
 
@@ -1309,36 +1503,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_em_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_OBJECT|ND_GEOM_SELECT, obedit);
 
-       BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;
 }
 
@@ -1361,54 +1558,59 @@ static int de_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;
-       int sel;
+       MTexPoly *tf;
+       MLoopUV *luv;
+       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) {
                EDBM_toggle_select_all(((Mesh*)obedit->data)->edit_btmesh);
        }
        else {
-               sel= 0;
+               BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+                       tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
 
-               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))
+                               continue;
 
-                       if(uvedit_face_visible(scene, ima, efa, tf)) {
-                               if(tf->flag & (TF_SEL1+TF_SEL2+TF_SEL3+TF_SEL4)) {
-                                       sel= 1;
+                       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) {
+                                       sel= 0;
                                        break;
                                }
                        }
                }
        
-               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(efa->v4) {
-                                       if(sel) tf->flag &= ~(TF_SEL1+TF_SEL2+TF_SEL3+TF_SEL4);
-                                       else tf->flag |= (TF_SEL1+TF_SEL2+TF_SEL3+TF_SEL4);
-                               }
-                               else {
-                                       if(sel) tf->flag &= ~(TF_SEL1+TF_SEL2+TF_SEL3+TF_SEL4);
-                                       else tf->flag |= (TF_SEL1+TF_SEL2+TF_SEL3);
-                               }
+                       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 (sel) luv->flag |= MLOOPUV_VERTSEL;
+                               else luv->flag &= ~MLOOPUV_VERTSEL;
                        }
                }
        }
 
        WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
 
-       BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;
 }
 
@@ -1426,7 +1628,7 @@ void UV_OT_select_all_toggle(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;
 
@@ -1435,7 +1637,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])
@@ -1456,14 +1658,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;
+       V_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;
+       V_DECLARE(hituv);
+       float penalty[2];
+
        uvedit_pixel_to_float(sima, limit, 0.05f);
        uvedit_pixel_to_float(sima, penalty, 5.0f);
 
@@ -1491,76 +1699,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++) {
+                       V_GROW(hitv);
+                       V_GROW(hituv);
                        hitv[i]= 0xFFFFFFFF;
+               }
+
+               hitv[hit.lindex]= hit.vert1;
+               hituv[hit.lindex]= hit.luv->uv;
 
-               hitv[hit.uv]= hit.vert;
-               hituv[hit.uv]= hit.tf->uv[hit.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++) {
+                       V_GROW(hitv);
+                       V_GROW(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;
+                       V_GROW(hitv);
+                       V_GROW(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;
        }
 
@@ -1574,36 +1794,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;
@@ -1611,97 +1831,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_em_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_em_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) {
@@ -1709,11 +1921,10 @@ static int mouse_select(bContext *C, float co[2], int extend, int loop)
                        else if(flush==-1)      EM_deselect_flush(em);
                }
        }
-       
+#endif 
        DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
        WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
        
-       BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_PASS_THROUGH|OPERATOR_FINISHED;
 }
 
@@ -1820,13 +2031,12 @@ static int select_linked_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);
+       BMEditMesh *em= ((Mesh*)obedit->data)->edit_btmesh;
        float limit[2];
        int extend;
 
        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;
        }
 
@@ -1837,7 +2047,6 @@ static int select_linked_exec(bContext *C, wmOperator *op)
        DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
        WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
 
-       BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;
 }
 
@@ -1865,27 +2074,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;
 
-               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);
+               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->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;
                        }
                }
        }
@@ -1893,7 +2113,6 @@ static int unlink_selection_exec(bContext *C, wmOperator *op)
        DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
        WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
 
-       BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;
 }
 
@@ -1927,78 +2146,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)
@@ -2017,35 +2235,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)
@@ -2056,9 +2272,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;
@@ -2088,14 +2307,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;
                                }
                        }
                }
@@ -2107,51 +2328,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, 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(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((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);
                                        }
                                }
                        }
@@ -2160,20 +2356,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_OBJECT|ND_GEOM_SELECT, obedit);
                
-               BKE_mesh_end_editmesh(obedit->data, em);
                return OPERATOR_FINISHED;
        }
 
-       BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_CANCELLED;
 } 
 
@@ -2204,20 +2400,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);
        }
 }
 
@@ -2226,10 +2425,13 @@ int circle_select_exec(bContext *C, wmOperator *op)
        SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
        Scene *scene= CTX_data_scene(C);
        Object *obedit= CTX_data_edit_object(C);
-       EditMesh *em= 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];
 
@@ -2250,21 +2452,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_OBJECT|ND_GEOM_SELECT, obedit);
 
-       BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;
 }
 
@@ -2362,30 +2562,34 @@ void UV_OT_snap_cursor(wmOperatorType *ot)
 
 static int snap_uvs_to_cursor(Scene *scene, Image *ima, Object *obedit, View2D *v2d)
 {
-       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], v2d->cursor);
-                       if(uvedit_uv_selected(scene, efa, tface, 1))            VECCOPY2D(tface->uv[1], v2d->cursor);
-                       if(uvedit_uv_selected(scene, efa, tface, 2))            VECCOPY2D(tface->uv[2], v2d->cursor);
-                       if(efa->v4)
-                               if(uvedit_uv_selected(scene, efa, tface, 3))    VECCOPY2D(tface->uv[3], v2d->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, v2d->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)
 {
+#if 0
        EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
        EditFace *efa;
        EditVert *eve;
@@ -2405,11 +2609,11 @@ static int snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object *obe
                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(uvedit_uv_selected(em, scene, efa, tface, 0) && efa->v1->tmp.l==-1)          efa->v1->tmp.l= count++;
+                       if(uvedit_uv_selected(em, scene, efa, tface, 1) && efa->v2->tmp.l==-1)          efa->v2->tmp.l= count++;
+                       if(uvedit_uv_selected(em, 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++;
+                               if(uvedit_uv_selected(em, scene, efa, tface, 3) && efa->v4->tmp.l==-1)  efa->v4->tmp.l= count++;
 
                        change = 1;
                        
@@ -2427,19 +2631,19 @@ static int snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object *obe
        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))) {
+                       if(efa->v1->tmp.l >= 0 && (!uvedit_uv_selected(em, 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))) {
+                       if(efa->v2->tmp.l >= 0 && (!uvedit_uv_selected(em, 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))) {
+                       if(efa->v3->tmp.l >= 0 && (!uvedit_uv_selected(em, 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]++;
@@ -2447,7 +2651,7 @@ static int snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object *obe
                        }
                        
                        if(efa->v4) {
-                               if(efa->v4->tmp.l >= 0 && (!uvedit_uv_selected(scene, efa, tface, 3))) {
+                               if(efa->v4->tmp.l >= 0 && (!uvedit_uv_selected(em, 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]++;
@@ -2469,7 +2673,7 @@ static int snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object *obe
        for(efa= em->faces.first; efa; efa= efa->next) {
                if((tface=(MTFace *)efa->tmp.p)) {
                        
-                       if(     uvedit_uv_selected(scene, efa, tface, 0) &&
+                       if(     uvedit_uv_selected(em, scene, efa, tface, 0) &&
                                        efa->v1->tmp.l >= 0 &&
                                        (users = usercount[efa->v1->tmp.l])
                        ) {
@@ -2477,7 +2681,7 @@ static int snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object *obe
                                tface->uv[0][1] = coords[(efa->v1->tmp.l*2)+1]  / users;
                        }
 
-                       if(     uvedit_uv_selected(scene, efa, tface, 1) &&
+                       if(     uvedit_uv_selected(em, scene, efa, tface, 1) &&
                                        efa->v2->tmp.l >= 0 &&
                                        (users = usercount[efa->v2->tmp.l])
                        ) {
@@ -2485,7 +2689,7 @@ static int snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object *obe
                                tface->uv[1][1] = coords[(efa->v2->tmp.l*2)+1]  / users;
                        }
                        
-                       if(     uvedit_uv_selected(scene, efa, tface, 2) &&
+                       if(     uvedit_uv_selected(em, scene, efa, tface, 2) &&
                                        efa->v3->tmp.l >= 0 &&
                                        (users = usercount[efa->v3->tmp.l])
                        ) {
@@ -2494,7 +2698,7 @@ static int snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object *obe
                        }
                        
                        if(efa->v4) {
-                               if(     uvedit_uv_selected(scene, efa, tface, 3) &&
+                               if(     uvedit_uv_selected(em, scene, efa, tface, 3) &&
                                                efa->v4->tmp.l >= 0 &&
                                                (users = usercount[efa->v4->tmp.l])
                                ) {
@@ -2510,10 +2714,12 @@ static int snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object *obe
 
        BKE_mesh_end_editmesh(obedit->data, em);
        return change;
+#endif
 }
 
 static int snap_uvs_to_pixels(SpaceImage *sima, Scene *scene, Object *obedit)
 {
+#if 0
        EditMesh *em= BKE_mesh_get_editmesh((Mesh*)obedit->data);
        Image *ima= sima->image;
        EditFace *efa;
@@ -2529,11 +2735,11 @@ static int snap_uvs_to_pixels(SpaceImage *sima, Scene *scene, Object *obedit)
        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(uvedit_uv_selected(em, scene, efa, tface, 0)) snap_uv_to_pixel(tface->uv[0], w, h);
+                       if(uvedit_uv_selected(em, scene, efa, tface, 1)) snap_uv_to_pixel(tface->uv[1], w, h);
+                       if(uvedit_uv_selected(em, 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);
+                               if(uvedit_uv_selected(em, scene, efa, tface, 3)) snap_uv_to_pixel(tface->uv[3], w, h);
 
                        change = 1;
                }
@@ -2541,6 +2747,7 @@ static int snap_uvs_to_pixels(SpaceImage *sima, Scene *scene, Object *obedit)
 
        BKE_mesh_end_editmesh(obedit->data, em);
        return change;
+#endif
 }
 
 static int snap_selection_exec(bContext *C, wmOperator *op)
@@ -2598,6 +2805,7 @@ void UV_OT_snap_selection(wmOperatorType *ot)
 
 static int pin_exec(bContext *C, wmOperator *op)
 {
+#if 0
        Scene *scene= CTX_data_scene(C);
        Object *obedit= CTX_data_edit_object(C);
        Image *ima= CTX_data_edit_image(C);
@@ -2611,18 +2819,18 @@ static int pin_exec(bContext *C, wmOperator *op)
 
                if(uvedit_face_visible(scene, ima, efa, tface)) {
                        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(uvedit_uv_selected(em, scene, efa, tface, 0)) tface->unwrap |= TF_PIN1;
+                               if(uvedit_uv_selected(em, scene, efa, tface, 1)) tface->unwrap |= TF_PIN2;
+                               if(uvedit_uv_selected(em, 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, 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(uvedit_uv_selected(em, scene, efa, tface, 0)) tface->unwrap &= ~TF_PIN1;
+                               if(uvedit_uv_selected(em, scene, efa, tface, 1)) tface->unwrap &= ~TF_PIN2;
+                               if(uvedit_uv_selected(em, 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, efa, tface, 3)) tface->unwrap &= ~TF_PIN4;
                        }
                }
        }
@@ -2631,6 +2839,7 @@ static int pin_exec(bContext *C, wmOperator *op)
 
        BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;
+#endif
 }
 
 void UV_OT_pin(wmOperatorType *ot)
@@ -2652,6 +2861,7 @@ void UV_OT_pin(wmOperatorType *ot)
 
 static int select_pinned_exec(bContext *C, wmOperator *op)
 {
+#if 0
        Scene *scene= CTX_data_scene(C);
        Object *obedit= CTX_data_edit_object(C);
        Image *ima= CTX_data_edit_image(C);
@@ -2676,6 +2886,7 @@ static int select_pinned_exec(bContext *C, wmOperator *op)
 
        BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;
+#endif
 }
 
 void UV_OT_select_pinned(wmOperatorType *ot)
@@ -2694,6 +2905,7 @@ void UV_OT_select_pinned(wmOperatorType *ot)
 
 static int hide_exec(bContext *C, wmOperator *op)
 {
+#if 0
        SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
        ToolSettings *ts= CTX_data_tool_settings(C);
        Object *obedit= CTX_data_edit_object(C);
@@ -2817,6 +3029,7 @@ static int hide_exec(bContext *C, wmOperator *op)
 
        BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;
+#endif
 }
 
 void UV_OT_hide(wmOperatorType *ot)
@@ -2838,6 +3051,7 @@ void UV_OT_hide(wmOperatorType *ot)
 
 static int reveal_exec(bContext *C, wmOperator *op)
 {
+#if 0
        SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
        ToolSettings *ts= CTX_data_tool_settings(C);
        Object *obedit= CTX_data_edit_object(C);
@@ -2948,6 +3162,7 @@ static int reveal_exec(bContext *C, wmOperator *op)
 
        BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;
+#endif
 }
 
 void UV_OT_reveal(wmOperatorType *ot)
index 94713cf0d769597905809d543172033c4031a7c1..f54aee1dfc02346ba08c185a3cf9e3482c936445 100644 (file)
@@ -95,8 +95,14 @@ typedef struct MTexPoly{
 
 typedef struct MLoopUV{
        float uv[2];
+       int flag;
 }MLoopUV;
 
+/*mloopuv->flag*/
+#define MLOOPUV_EDGESEL        1
+#define MLOOPUV_VERTSEL        2
+#define MLOOPUV_PINNED 4
+
 typedef struct MLoopCol{
        char a, r, g, b;
        int pad;  /*waste!*/