merge with/from trunk at r35190
[blender.git] / source / blender / editors / transform / transform_conversions.c
index d1bf030e17c2584c5ca9308bb79c16d4a1a67d19..e55e6ba33e9da07802f287fa7b90be1938482a86 100644 (file)
@@ -69,6 +69,7 @@
 #include "BKE_sequencer.h"
 #include "BKE_pointcache.h"
 #include "BKE_bmesh.h"
+#include "BKE_tessmesh.h"
 #include "BKE_scene.h"
 #include "BKE_report.h"
 
@@ -92,6 +93,7 @@
 #include "BLI_math.h"
 #include "BLI_blenlib.h"
 #include "BLI_editVert.h"
+#include "BLI_array.h"
 #include "BLI_utildefines.h"
 
 #include "RNA_access.h"
 extern ListBase editelems;
 
 #include "transform.h"
+#include "bmesh.h"
 
 #include "BLO_sys_types.h" // for intptr_t support
 
@@ -284,18 +287,20 @@ static void createTransTexspace(TransInfo *t)
 /* ********************* edge (for crease) ***** */
 
 static void createTransEdge(TransInfo *t) {
-       EditMesh *em = ((Mesh *)t->obedit->data)->edit_mesh;
+       BMEditMesh *em = ((Mesh *)t->obedit->data)->edit_btmesh;
        TransData *td = NULL;
-       EditEdge *eed;
+       BMEdge *eed;
+       BMIter iter;
        float mtx[3][3], smtx[3][3];
        int count=0, countsel=0;
        int propmode = t->flag & T_PROP_EDIT;
 
-       for(eed= em->edges.first; eed; eed= eed->next) {
-               if(eed->h==0) {
-                       if (eed->f & SELECT) countsel++;
-                       if (propmode) count++;
-               }
+       BM_ITER(eed, &iter, em->bm, BM_EDGES_OF_MESH, NULL) {
+               if (BM_TestHFlag(eed, BM_HIDDEN))
+                       continue;
+
+               if (BM_TestHFlag(eed, BM_SELECT)) countsel++;
+               if (propmode) count++;
        }
 
        if (countsel == 0)
@@ -313,14 +318,17 @@ static void createTransEdge(TransInfo *t) {
        copy_m3_m4(mtx, t->obedit->obmat);
        invert_m3_m3(smtx, mtx);
 
-       for(eed= em->edges.first; eed; eed= eed->next) {
-               if(eed->h==0 && (eed->f & SELECT || propmode)) {
+       BM_ITER(eed, &iter, em->bm, BM_EDGES_OF_MESH, NULL) {
+               if(!BM_TestHFlag(eed, BM_HIDDEN) && (BM_TestHFlag(eed, BM_SELECT) || propmode)) { 
+                       float *bweight = CustomData_bmesh_get(&em->bm->edata, eed->head.data, CD_BWEIGHT);
+                       float *crease = CustomData_bmesh_get(&em->bm->edata, eed->head.data, CD_CREASE);
+                       
                        /* need to set center for center calculations */
                        add_v3_v3v3(td->center, eed->v1->co, eed->v2->co);
                        mul_v3_fl(td->center, 0.5f);
 
                        td->loc= NULL;
-                       if (eed->f & SELECT)
+                       if (BM_TestHFlag(eed, BM_SELECT))
                                td->flag= TD_SELECTED;
                        else
                                td->flag= 0;
@@ -331,12 +339,12 @@ static void createTransEdge(TransInfo *t) {
 
                        td->ext = NULL;
                        if (t->mode == TFM_BWEIGHT) {
-                               td->val = &(eed->bweight);
-                               td->ival = eed->bweight;
+                               td->val = bweight;
+                               td->ival = bweight ? *bweight : 1.0f;
                        }
                        else {
-                               td->val = &(eed->crease);
-                               td->ival = eed->crease;
+                               td->val = crease;
+                               td->ival = crease ? *crease : 0.0f;
                        }
 
                        td++;
@@ -1895,22 +1903,54 @@ static void editmesh_set_connectivity_distance(EditMesh *em, float mtx[][3])
 }
 
 /* loop-in-a-loop I know, but we need it! (ton) */
-static void get_face_center(float *cent, EditMesh *em, EditVert *eve)
+ static void get_face_center(float *centout, BMesh *bm, BMVert *eve)
+
 {
-       EditFace *efa;
+       BMFace *efa;
+       BMLoop *l;
+       BMIter iter;
+       float cent[3] = {0.0, 0.0, 0.0};
 
-       for(efa= em->faces.first; efa; efa= efa->next)
-               if(efa->f & SELECT)
-                       if(efa->v1==eve || efa->v2==eve || efa->v3==eve || efa->v4==eve)
-                               break;
-       if(efa) {
-               VECCOPY(cent, efa->cent);
+       efa = BMIter_New(&iter, bm, BM_FACES_OF_VERT, eve);
+       if (efa) {
+               l = BMIter_New(&iter, bm, BM_LOOPS_OF_FACE, efa);
+               for ( ; l; l=BMIter_Step(&iter)) {
+                       VECADD(cent, cent, l->v->co);
+               }
+
+               mul_v3_fl(cent, 1.0f / (float)efa->len);
        }
+
+       if (cent[0] == 0.0f && cent[1] == 0.0f && cent[2] == 0.0f) cent[2] = 1.0f;
+       copy_v3_v3(centout, cent);
 }
 
+#define VertsToTransData(t, td, em, eve, bweight) \
+       td->flag = 0;\
+       td->loc = eve->co;\
+       VECCOPY(td->center, td->loc);\
+       if(t->around==V3D_LOCAL && (em->selectmode & SCE_SELECT_FACE))\
+               get_face_center(td->center, em, eve);\
+       VECCOPY(td->iloc, td->loc);\
+       VECCOPY(td->axismtx[2], eve->no);\
+       td->axismtx[0][0]               =\
+               td->axismtx[0][1]       =\
+               td->axismtx[0][2]       =\
+               td->axismtx[1][0]       =\
+               td->axismtx[1][1]       =\
+               td->axismtx[1][2]       = 0.0f;\
+       td->ext = NULL;\
+       td->val = NULL;\
+       td->extra = NULL;\
+       if (t->mode == TFM_BWEIGHT) {\
+               td->val = bweight;\
+               td->ival = bweight ? *(bweight) : 1.0f;\
+       }
+
+#if 0
 //way to overwrite what data is edited with transform
 //static void VertsToTransData(TransData *td, EditVert *eve, BakeKey *key)
-static void VertsToTransData(TransInfo *t, TransData *td, EditMesh *em, EditVert *eve)
+inline void VertsToTransData(TransInfo *t, TransData *td, BMesh *em, BMVert *eve)
 {
        td->flag = 0;
        //if(key)
@@ -1940,9 +1980,152 @@ static void VertsToTransData(TransInfo *t, TransData *td, EditMesh *em, EditVert
                td->ival = eve->bweight;
        }
 }
+#endif
+
+/* *********************** CrazySpace correction. Now without doing subsurf optimal ****************** */
+
+static void make_vertexcos__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
+{
+       float *vec = userData;
+
+       vec+= 3*index;
+       VECCOPY(vec, co);
+}
+
+static int modifiers_disable_subsurf_temporary(Object *ob)
+{
+       ModifierData *md;
+       int disabled = 0;
+
+       for(md=ob->modifiers.first; md; md=md->next)
+               if(md->type==eModifierType_Subsurf)
+                       if(md->mode & eModifierMode_OnCage) {
+                               md->mode ^= eModifierMode_DisableTemporary;
+                               disabled= 1;
+                       }
+
+       return disabled;
+}
+
+/* disable subsurf temporal, get mapped cos, and enable it */
+static float *get_crazy_mapped_editverts(TransInfo *t)
+{
+       Mesh *me= t->obedit->data;
+       DerivedMesh *dm;
+       float *vertexcos;
+
+       /* disable subsurf temporal, get mapped cos, and enable it */
+       if(modifiers_disable_subsurf_temporary(t->obedit)) {
+               /* need to make new derivemesh */
+               makeDerivedMesh(t->scene, t->obedit, me->edit_btmesh, CD_MASK_BAREMESH);
+       }
+
+       /* now get the cage */
+       dm= editbmesh_get_derived_cage(t->scene, t->obedit, me->edit_btmesh, CD_MASK_BAREMESH);
+
+       vertexcos= MEM_mallocN(3*sizeof(float)*me->edit_btmesh->bm->totvert, "vertexcos map");
+       dm->foreachMappedVert(dm, make_vertexcos__mapFunc, vertexcos);
+
+       dm->release(dm);
+
+       /* set back the flag, no new cage needs to be built, transform does it */
+       modifiers_disable_subsurf_temporary(t->obedit);
+
+       return vertexcos;
+}
+
+#define TAN_MAKE_VEC(a, b, c)  a[0]= b[0] + 0.2f*(b[0]-c[0]); a[1]= b[1] + 0.2f*(b[1]-c[1]); a[2]= b[2] + 0.2f*(b[2]-c[2])
+static void set_crazy_vertex_quat(float *quat, float *v1, float *v2, float *v3, float *def1, float *def2, float *def3)
+{
+       float vecu[3], vecv[3];
+       float q1[4], q2[4];
+
+       TAN_MAKE_VEC(vecu, v1, v2);
+       TAN_MAKE_VEC(vecv, v1, v3);
+       tri_to_quat( q1,v1, vecu, vecv);
+
+       TAN_MAKE_VEC(vecu, def1, def2);
+       TAN_MAKE_VEC(vecv, def1, def3);
+       tri_to_quat( q2,def1, vecu, vecv);
+
+       sub_qt_qtqt(quat, q2, q1);
+}
+#undef TAN_MAKE_VEC
 
+static void set_crazyspace_quats(BMEditMesh *em, float *origcos, float *mappedcos, float *quats)
+{
 #if 0
+       BMVert *eve, *prev;
+       BMFace *efa;
+       float *v1, *v2, *v3, *v4, *co1, *co2, *co3, *co4;
+       intptr_t index= 0;
+
+       /* two abused locations in vertices */
+       for(eve= em->verts.first; eve; eve= eve->next, index++) {
+               eve->tmp.p = NULL;
+               eve->prev= (BMVert *)index;
+       }
+
+       /* first store two sets of tangent vectors in vertices, we derive it just from the face-edges */
+       for(efa= em->faces.first; efa; efa= efa->next) {
+
+               /* retrieve mapped coordinates */
+               v1= mappedcos + 3*(intptr_t)(efa->v1->prev);
+               v2= mappedcos + 3*(intptr_t)(efa->v2->prev);
+               v3= mappedcos + 3*(intptr_t)(efa->v3->prev);
+
+               co1= (origcos)? origcos + 3*(intptr_t)(efa->v1->prev): efa->v1->co;
+               co2= (origcos)? origcos + 3*(intptr_t)(efa->v2->prev): efa->v2->co;
+               co3= (origcos)? origcos + 3*(intptr_t)(efa->v3->prev): efa->v3->co;
+
+               if(efa->v2->tmp.p==NULL && efa->v2->f1) {
+                       set_crazy_vertex_quat(quats, co2, co3, co1, v2, v3, v1);
+                       efa->v2->tmp.p= (void*)quats;
+                       quats+= 4;
+               }
+
+               if(efa->v4) {
+                       v4= mappedcos + 3*(intptr_t)(efa->v4->prev);
+                       co4= (origcos)? origcos + 3*(intptr_t)(efa->v4->prev): efa->v4->co;
+
+                       if(efa->v1->tmp.p==NULL && efa->v1->f1) {
+                               set_crazy_vertex_quat(quats, co1, co2, co4, v1, v2, v4);
+                               efa->v1->tmp.p= (void*)quats;
+                               quats+= 4;
+                       }
+                       if(efa->v3->tmp.p==NULL && efa->v3->f1) {
+                               set_crazy_vertex_quat(quats, co3, co4, co2, v3, v4, v2);
+                               efa->v3->tmp.p= (void*)quats;
+                               quats+= 4;
+                       }
+                       if(efa->v4->tmp.p==NULL && efa->v4->f1) {
+                               set_crazy_vertex_quat(quats, co4, co1, co3, v4, v1, v3);
+                               efa->v4->tmp.p= (void*)quats;
+                               quats+= 4;
+                       }
+               }
+               else {
+                       if(efa->v1->tmp.p==NULL && efa->v1->f1) {
+                               set_crazy_vertex_quat(quats, co1, co2, co3, v1, v2, v3);
+                               efa->v1->tmp.p= (void*)quats;
+                               quats+= 4;
+                       }
+                       if(efa->v3->tmp.p==NULL && efa->v3->f1) {
+                               set_crazy_vertex_quat(quats, co3, co1, co2, v3, v1, v2);
+                               efa->v3->tmp.p= (void*)quats;
+                               quats+= 4;
+                       }
+               }
+       }
+
+       /* restore abused prev pointer */
+       for(prev= NULL, eve= em->verts.first; eve; prev= eve, eve= eve->next)
+               eve->prev= prev;
+#endif
+}
+
 static void createTransBMeshVerts(TransInfo *t, BME_Mesh *bm, BME_TransData_Head *td) {
+#if 0
        BME_Vert *v;
        BME_TransData *vtd;
        TransData *tob;
@@ -1965,25 +2148,32 @@ static void createTransBMeshVerts(TransInfo *t, BME_Mesh *bm, BME_TransData_Head
        /* since td is a memarena, it can hold more transdata than actual elements
         * (i.e. we can't depend on td->len to determine the number of actual elements) */
        t->total = i;
-}
 #endif
+       t->total = 0;
+}
 
 static void createTransEditVerts(bContext *C, TransInfo *t)
 {
        ToolSettings *ts = CTX_data_tool_settings(C);
        TransData *tob = NULL;
-       EditMesh *em = ((Mesh *)t->obedit->data)->edit_mesh;
-       EditVert *eve;
-       EditVert *eve_act = NULL;
+       BMEditMesh *em = ((Mesh *)t->obedit->data)->edit_btmesh;
+       BMesh *bm = em->bm;
+       BMVert *eve;
+       BMVert **nears = NULL;
+       BMIter iter;
+       BMVert *eve_act = NULL;
        float *mappedcos = NULL, *quats= NULL;
        float mtx[3][3], smtx[3][3], (*defmats)[3][3] = NULL, (*defcos)[3] = NULL;
-       int count=0, countsel=0, a, totleft;
+       float *vectors=NULL;
+       int count=0, countsel=0, a, totleft, *selstate = NULL;
+       BLI_array_declare(selstate);
        int propmode = t->flag & T_PROP_EDIT;
        int mirror = 0;
        short selectmode = ts->selectmode;
 
        if (t->flag & T_MIRROR)
        {
+               EDBM_CacheMirrorVerts(em);
                mirror = 1;
        }
 
@@ -1994,36 +2184,56 @@ static void createTransEditVerts(bContext *C, TransInfo *t)
 
        // transform now requires awareness for select mode, so we tag the f1 flags in verts
        if(selectmode & SCE_SELECT_VERTEX) {
-               for(eve= em->verts.first; eve; eve= eve->next) {
-                       if(eve->h==0 && (eve->f & SELECT))
-                               eve->f1= SELECT;
+               BM_ITER(eve, &iter, bm, BM_VERTS_OF_MESH, NULL) {
+                       if(!BM_TestHFlag(eve, BM_HIDDEN) && BM_TestHFlag(eve, BM_SELECT))
+                               BMINDEX_SET(eve, SELECT);
                        else
-                               eve->f1= 0;
+                               BMINDEX_SET(eve, 0);
                }
        }
        else if(selectmode & SCE_SELECT_EDGE) {
-               EditEdge *eed;
-               for(eve= em->verts.first; eve; eve= eve->next) eve->f1= 0;
-               for(eed= em->edges.first; eed; eed= eed->next) {
-                       if(eed->h==0 && (eed->f & SELECT))
-                               eed->v1->f1= eed->v2->f1= SELECT;
+               BMEdge *eed;
+
+               eve = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
+               for( ; eve; eve=BMIter_Step(&iter)) BMINDEX_SET(eve, 0);
+
+               eed = BMIter_New(&iter, bm, BM_EDGES_OF_MESH, NULL);
+               for( ; eed; eed=BMIter_Step(&iter)) {
+                       if(!BM_TestHFlag(eed, BM_HIDDEN) && BM_TestHFlag(eed, BM_SELECT))
+                               BMINDEX_SET(eed->v1, SELECT), BMINDEX_SET(eed->v2, SELECT);
                }
        }
        else {
-               EditFace *efa;
-               for(eve= em->verts.first; eve; eve= eve->next) eve->f1= 0;
-               for(efa= em->faces.first; efa; efa= efa->next) {
-                       if(efa->h==0 && (efa->f & SELECT)) {
-                               efa->v1->f1= efa->v2->f1= efa->v3->f1= SELECT;
-                               if(efa->v4) efa->v4->f1= SELECT;
+               BMFace *efa;
+               eve = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
+               for( ; eve; eve=BMIter_Step(&iter)) BMINDEX_SET(eve, 0);
+
+               efa = BMIter_New(&iter, bm, BM_FACES_OF_MESH, NULL);
+               for( ; efa; efa=BMIter_Step(&iter)) {
+                       if(!BM_TestHFlag(efa, BM_HIDDEN) && BM_TestHFlag(efa, BM_SELECT)) {
+                               BMIter liter;
+                               BMLoop *l;
+
+                               l = BMIter_New(&liter, bm, BM_LOOPS_OF_FACE, efa);
+                               for (; l; l=BMIter_Step(&liter)) {
+                                       BMINDEX_SET(l->v, SELECT);
+                               }
                        }
                }
        }
 
-       /* now we can count */
-       for(eve= em->verts.first; eve; eve= eve->next) {
-               if(eve->h==0) {
-                       if(eve->f1) countsel++;
+       /* now we can count. we store selection state in selstate, since
+          get_crazy_mapped_editverts messes up the index state of the
+          verts*/
+       eve = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
+       for(a=0; eve; eve=BMIter_Step(&iter), a++) {
+               BLI_array_growone(selstate);
+
+               if(!BM_TestHFlag(eve, BM_HIDDEN)) {     
+                       if(BMINDEX_GET(eve)) {
+                               selstate[a] = 1;
+                               countsel++;
+                       }
                        if(propmode) count++;
                }
        }
@@ -2032,15 +2242,21 @@ static void createTransEditVerts(bContext *C, TransInfo *t)
        if (countsel==0) return;
 
        /* check active */
-       if (em->selected.last) {
-               EditSelection *ese = em->selected.last;
+       if (em->bm->selected.last) {
+               BMEditSelection *ese = em->bm->selected.last;
                if ( ese->type == EDITVERT ) {
-                       eve_act = (EditVert *)ese->data;
+                       eve_act = (BMVert *)ese->data;
                }
        }
 
 
-       if(propmode) t->total = count;
+       if(propmode) {
+               t->total = count;
+
+               /* allocating scratch arrays */
+               vectors = (float *)MEM_mallocN(t->total * 3 * sizeof(float), "scratch vectors");
+               nears = (BMVert**)MEM_mallocN(t->total * sizeof(BMVert*), "scratch nears");
+       }
        else t->total = countsel;
 
        tob= t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(Mesh EditMode)");
@@ -2048,7 +2264,7 @@ static void createTransEditVerts(bContext *C, TransInfo *t)
        copy_m3_m4(mtx, t->obedit->obmat);
        invert_m3_m3(smtx, mtx);
 
-       if(propmode) editmesh_set_connectivity_distance(em, mtx);
+       //BMESH_TODO if(propmode) editmesh_set_connectivity_distance(em, t->total, vectors, nears);
 
        /* detect CrazySpace [tm] */
        if(propmode==0) {
@@ -2056,7 +2272,8 @@ static void createTransEditVerts(bContext *C, TransInfo *t)
                        if(modifiers_isCorrectableDeformed(t->obedit)) {
                                /* check if we can use deform matrices for modifier from the
                                   start up to stack, they are more accurate than quats */
-                               totleft= editmesh_get_first_deform_matrices(t->scene, t->obedit, em, &defmats, &defcos);
+
+                               totleft= editbmesh_get_first_deform_matrices(t->scene, t->obedit, em, &defmats, &defcos);
 
                                /* if we still have more modifiers, also do crazyspace
                                   correction with quats, relative to the coordinates after
@@ -2077,8 +2294,9 @@ static void createTransEditVerts(bContext *C, TransInfo *t)
 
        /* find out which half we do */
        if(mirror) {
-               for (eve=em->verts.first; eve; eve=eve->next) {
-                       if(eve->h==0 && eve->f1 && eve->co[0]!=0.0f) {
+               eve = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
+               for(a=0; eve; eve=BMIter_Step(&iter), a++) {
+                       if(!BM_TestHFlag(eve, BM_HIDDEN) && selstate[a] && eve->co[0]!=0.0f) {
                                if(eve->co[0]<0.0f)
                                {
                                        t->mirror = -1;
@@ -2089,33 +2307,43 @@ static void createTransEditVerts(bContext *C, TransInfo *t)
                }
        }
 
-       for (a=0, eve=em->verts.first; eve; eve=eve->next, a++) {
-               if(eve->h==0) {
-                       if(propmode || eve->f1) {
-                               VertsToTransData(t, tob, em, eve);
+       eve = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
+       for(a=0; eve; eve=BMIter_Step(&iter), a++) {
+               if(!BM_TestHFlag(eve, BM_HIDDEN)) {
+                       if(propmode || selstate[a]) {
+                               float *bweight = CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_BWEIGHT);
+                               
+                               VertsToTransData(t, tob, bm, eve, bweight);
+
+                               /* pinned */
+                               if(BM_TestHFlag(eve,BM_PINNED)) tob->flag |= TD_SKIP;
 
                                /* selected */
-                               if(eve->f1) tob->flag |= TD_SELECTED;
+                               if(selstate[a]) tob->flag |= TD_SELECTED;
 
                                /* active */
                                if(eve == eve_act) tob->flag |= TD_ACTIVE;
 
                                if(propmode) {
+                                       /*BMESH_TODO
+                                       this has to do with edge connectivity
+                                       PEP mode, I think. -joeedh
                                        if (eve->f2) {
                                                tob->dist= eve->tmp.fp;
                                        }
-                                       else {
+                                       else {*/
                                                tob->flag |= TD_NOTCONNECTED;
                                                tob->dist = MAXFLOAT;
-                                       }
+                                       //}
                                }
 
                                /* CrazySpace */
-                               if(defmats || (quats && eve->tmp.p)) {
+                               if(defmats) { // || (quats && eve->tmp.p)) {
                                        float mat[3][3], imat[3][3], qmat[3][3];
 
                                        /* use both or either quat and defmat correction */
-                                       if(quats && eve->tmp.f) {
+                                       //BMESH_TODO, need to restore this quats thing
+                                       /*if(quats && eve->tmp.f) {
                                                quat_to_mat3( qmat,eve->tmp.p);
 
                                                if(defmats)
@@ -2124,7 +2352,7 @@ static void createTransEditVerts(bContext *C, TransInfo *t)
                                                else
                                                        mul_m3_m3m3(mat, mtx, qmat);
                                        }
-                                       else
+                                       else*/
                                                mul_m3_m3m3(mat, mtx, defmats[a]);
 
                                        invert_m3_m3(imat, mat);
@@ -2138,9 +2366,11 @@ static void createTransEditVerts(bContext *C, TransInfo *t)
                                }
 
                                /* Mirror? */
+
+                               //BMESH_TODO
                                if( (mirror>0 && tob->iloc[0]>0.0f) || (mirror<0 && tob->iloc[0]<0.0f)) {
-                                       EditVert *vmir= editmesh_get_x_mirror_vert(t->obedit, em, eve, tob->iloc, a);   /* initializes octree on first call */
-                                       if(vmir != eve) {
+                                       BMVert *vmir= EDBM_GetMirrorVert(em, eve); //t->obedit, em, eve, tob->iloc, a);
+                                       if(vmir && vmir != eve) {
                                                tob->extra = vmir;
                                        }
                                }
@@ -2161,11 +2391,20 @@ static void createTransEditVerts(bContext *C, TransInfo *t)
                }
        }
        
+
        /* crazy space free */
        if(quats)
                MEM_freeN(quats);
        if(defmats)
                MEM_freeN(defmats);
+
+       BLI_array_free(selstate);
+
+       if (t->flag & T_MIRROR)
+       {
+               EDBM_EndMirrorCache(em);
+               mirror = 1;
+       }
 }
 
 /* *** NODE EDITOR *** */
@@ -2321,30 +2560,33 @@ static void createTransUVs(bContext *C, TransInfo *t)
        Scene *scene = t->scene;
        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_space_image_show_uvedit(sima, 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;
                }
        }
 
@@ -2363,20 +2605,17 @@ 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));
                }
        }
 
@@ -4676,7 +4915,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
        if (t->spacetype==SPACE_VIEW3D) {
                if (t->obedit) {
                        if (cancelled==0) {
-                               EM_automerge(t->scene, t->obedit, 1);
+                               EDBM_automerge(t->scene, t->obedit, 1);
                        }
                }
        }
@@ -4883,9 +5122,9 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
        else if (t->obedit) {
                if (t->obedit->type == OB_MESH)
                {
-                       EditMesh *em = ((Mesh *)t->obedit->data)->edit_mesh;
+                       BMEditMesh *em = ((Mesh *)t->obedit->data)->edit_btmesh;
                        /* table needs to be created for each edit command, since vertices can move etc */
-                       mesh_octree_table(t->obedit, em, NULL, 'e');
+                       // BMESH_TODO mesh_octree_table(t->obedit, em, NULL, 'e');
                }
        }
        else if ((t->flag & T_POSE) && (t->poseobj)) {
@@ -4942,8 +5181,8 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
 
                for (i = 0; i < t->total; i++) {
                        TransData *td = t->data + i;
-                       ListBase pidlist;
-                       PTCacheID *pid;
+                               ListBase pidlist;
+                               PTCacheID *pid;
                        ob = td->ob;
 
                        if (td->flag & TD_NOACTION)
@@ -4960,9 +5199,9 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
                        }
                        BLI_freelistN(&pidlist);
 
-                       /* pointcache refresh */
+                               /* pointcache refresh */
                        if (BKE_ptcache_object_reset(t->scene, ob, PTCACHE_RESET_OUTDATED))
-                               ob->recalc |= OB_RECALC_DATA;
+                                       ob->recalc |= OB_RECALC_DATA;
 
                        /* Needed for proper updating of "quick cached" dynamics. */
                        /* Creates troubles for moving animated objects without */
@@ -5013,7 +5252,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
 #endif
 }
 
-static void createTransObject(bContext *C, TransInfo *t)
+static void createTransObject(struct bContext *C, TransInfo *t)
 {
        TransData *td = NULL;
        TransDataExtension *tx;