svn merge ^/trunk/blender -r41226:41227 .
[blender.git] / source / blender / editors / transform / transform_conversions.c
index a9f9208..6e1fc6d 100644 (file)
@@ -72,6 +72,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"
 
 #include "BLI_math.h"
 #include "BLI_blenlib.h"
 #include "BLI_editVert.h"
+#include "BLI_array.h"
 #include "BLI_utildefines.h"
+#include "BLI_smallhash.h"
 
 #include "RNA_access.h"
 
 extern ListBase editelems;
 
 #include "transform.h"
+#include "bmesh.h"
 
 #include "BLO_sys_types.h" // for intptr_t support
 
@@ -287,18 +291,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)
@@ -316,14 +322,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;
@@ -334,12 +343,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++;
@@ -1807,113 +1816,144 @@ void flushTransParticles(TransInfo *t)
 /* proportional distance based on connectivity  */
 #define THRESHOLDFACTOR (1.0f-0.0001f)
 
-static int connectivity_edge(float mtx[][3], EditVert *v1, EditVert *v2)
+/*I did this wrong, it should be a breadth-first search
+  but instead it's a depth-first search, fudged
+  to report shortest distances.  I have no idea how fast
+  or slow this is.*/
+static void editmesh_set_connectivity_distance(BMEditMesh *em, float mtx[][3], float *dists)
 {
-       float edge_vec[3];
-       float edge_len;
-       int done = 0;
-
-       /* note: hidden verts are not being checked for, this assumes
-        * flushing of hidden faces & edges is working right */
-       
-       if (v1->f2 + v2->f2 == 4)
-               return 0;
+       BMVert **queue = NULL;
+       float *dqueue = NULL;
+       int *tots = MEM_callocN(sizeof(int)*em->bm->totvert, "tots editmesh_set_connectivity_distance");
+       BLI_array_declare(queue);
+       BLI_array_declare(dqueue);
+       SmallHash svisit, *visit=&svisit;
+       BMVert *v;
+       BMIter viter;
+       int i, start;
        
-       sub_v3_v3v3(edge_vec, v1->co, v2->co);
-       mul_m3_v3(mtx, edge_vec);
-
-       edge_len = len_v3(edge_vec);
-
-       if (v1->f2) {
-               if (v2->f2) {
-                       if (v2->tmp.fp + edge_len < THRESHOLDFACTOR * v1->tmp.fp) {
-                               v1->tmp.fp = v2->tmp.fp + edge_len;
-                               done = 1;
-                       } else if (v1->tmp.fp + edge_len < THRESHOLDFACTOR * v2->tmp.fp) {
-                               v2->tmp.fp = v1->tmp.fp + edge_len;
-                               done = 1;
-                       }
-               }
-               else {
-                       v2->f2 = 1;
-                       v2->tmp.fp = v1->tmp.fp + edge_len;
-                       done = 1;
-               }
-       }
-       else if (v2->f2) {
-               v1->f2 = 1;
-               v1->tmp.fp = v2->tmp.fp + edge_len;
-               done = 1;
+       i = 0;
+       BM_ITER(v, &viter, em->bm, BM_VERTS_OF_MESH, NULL) {
+               BM_SetIndex(v, i);
+               dists[i] = FLT_MAX;
+               i++;
        }
+       
+       BLI_smallhash_init(visit);
 
-       return done;
-}
-
-static void editmesh_set_connectivity_distance(EditMesh *em, float mtx[][3])
-{
-       EditVert *eve;
-       EditEdge *eed;
-       EditFace *efa;
-       int done= 1;
-
-       /* f2 flag is used for 'selection' */
-       /* tmp.l is offset on scratch array   */
-       for(eve= em->verts.first; eve; eve= eve->next) {
-               if(eve->h==0) {
-                       eve->tmp.fp = 0;
-
-                       if(eve->f & SELECT) {
-                               eve->f2= 2;
-                       }
-                       else {
-                               eve->f2 = 0;
-                       }
-               }
+       BM_ITER(v, &viter, em->bm, BM_VERTS_OF_MESH, NULL) {
+               if (BM_TestHFlag(v, BM_SELECT)==0 || BM_TestHFlag(v, BM_HIDDEN))
+                       continue;
+                       
+               
+               BLI_smallhash_insert(visit, (uintptr_t)v, NULL);
+               BLI_array_append(queue, v);
+               BLI_array_append(dqueue, 0.0f);
+               dists[BM_GetIndex(v)] = 0.0f;
        }
+       
+       start = 0;
+       while (start < BLI_array_count(queue)) {
+               BMIter eiter;
+               BMEdge *e;
+               BMVert *v3, *v2;
+               float d, vec[3];
+               
+               v2 = queue[start];
+               d = dqueue[start];
+               
+               BM_ITER(e, &eiter, em->bm, BM_EDGES_OF_VERT, v2) {
+                       float d2;
+                       v3 = BM_OtherEdgeVert(e, v2);
+                       
+                       if (BM_TestHFlag(v3, BM_SELECT) || BM_TestHFlag(v3, BM_HIDDEN))
+                               continue;
+                       
+                       sub_v3_v3v3(vec, v2->co, v3->co);
+                       mul_m3_v3(mtx, vec);
+                       
+                       d2 = d + len_v3(vec);
+                       
+                       if (dists[BM_GetIndex(v3)] != FLT_MAX)
+                               dists[BM_GetIndex(v3)] = MIN2(d2, dists[BM_GetIndex(v3)]);
+                       else
+                               dists[BM_GetIndex(v3)] = d2;
+                       
+                       tots[BM_GetIndex(v3)] = 1;
 
-
-       /* Floodfill routine */
-       /*
-       At worst this is n*n of complexity where n is number of edges
-       Best case would be n if the list is ordered perfectly.
-       Estimate is n log n in average (so not too bad)
-       */
-       while(done) {
-               done= 0;
-
-               for(eed= em->edges.first; eed; eed= eed->next) {
-                       if(eed->h==0) {
-                               done |= connectivity_edge(mtx, eed->v1, eed->v2);
-                       }
+                       if (BLI_smallhash_haskey(visit, (uintptr_t)v3))
+                               continue;
+                       
+                       BLI_smallhash_insert(visit, (uintptr_t)v3, NULL);
+                       
+                       BLI_array_append(queue, v3);
+                       BLI_array_append(dqueue, d2);
                }
+               
+               start++;
+       }
 
-               /* do internal edges for quads */
-               for(efa= em->faces.first; efa; efa= efa->next) {
-                       if (efa->v4 && efa->h==0) {
-                               done |= connectivity_edge(mtx, efa->v1, efa->v3);
-                               done |= connectivity_edge(mtx, efa->v2, efa->v4);
-                       }
-               }
+       BLI_smallhash_release(visit);
+       
+       for (i=0; i<em->bm->totvert; i++) {
+               if (tots[i])
+                       dists[i] /= (float)tots[i];
        }
+       
+       BLI_array_free(queue);
+       BLI_array_free(dqueue);
+       MEM_freeN(tots);
 }
 
 /* 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) {
-               copy_v3_v3(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;\
+       copy_v3_v3(td->center, td->loc);\
+       if(t->around==V3D_LOCAL && (em->selectmode & SCE_SELECT_FACE))\
+               get_face_center(td->center, em, eve);\
+       copy_v3_v3(td->iloc, td->loc);\
+       copy_v3_v3(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)
@@ -1943,50 +1983,99 @@ static void VertsToTransData(TransInfo *t, TransData *td, EditMesh *em, EditVert
                td->ival = eve->bweight;
        }
 }
+#endif
 
-#if 0
-static void createTransBMeshVerts(TransInfo *t, BME_Mesh *bm, BME_TransData_Head *td) {
-       BME_Vert *v;
-       BME_TransData *vtd;
-       TransData *tob;
-       int i;
+/* *********************** CrazySpace correction. Now without doing subsurf optimal ****************** */
+
+static void make_vertexcos__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s))
+{
+       float *vec = userData;
 
-       tob = t->data = MEM_callocN(td->len*sizeof(TransData), "TransObData(Bevel tool)");
+       vec+= 3*index;
+       VECCOPY(vec, co);
+}
 
-       for (i=0,v=bm->verts.first;v;v=v->next) {
-               if ( (vtd = BME_get_transdata(td,v)) ) {
-                       tob->loc = vtd->loc;
-                       tob->val = &vtd->factor;
-                       copy_v3_v3(tob->iloc,vtd->co);
-                       copy_v3_v3(tob->center,vtd->org);
-                       copy_v3_v3(tob->axismtx[0],vtd->vec);
-                       tob->axismtx[1][0] = vtd->max ? *vtd->max : 0;
-                       tob++;
-                       i++;
-               }
+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, 0);
        }
-       /* 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;
+
+       /* 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;
 }
-#endif
+
+#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 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;
+       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 *dists=NULL;
+       int count=0, countsel=0, a, totleft, *selstate = NULL;
+       BLI_array_declare(selstate);
        int propmode = (t->flag & T_PROP_EDIT) ? (t->flag & (T_PROP_EDIT | T_PROP_CONNECTED)) : 0;
        int mirror = 0;
        short selectmode = ts->selectmode;
 
        if (t->flag & T_MIRROR)
        {
+               EDBM_CacheMirrorVerts(em);
                mirror = 1;
        }
 
@@ -1997,53 +2086,83 @@ 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;
-                       else
-                               eve->f1= 0;
+               BM_ITER(eve, &iter, bm, BM_VERTS_OF_MESH, NULL) {
+                       if (BM_Selected(bm, eve)) {
+                               BM_SetIndex(eve, SELECT);
+                       }
+                       else {
+                               BM_SetIndex(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)) BM_SetIndex(eve, 0);
+
+               eed = BMIter_New(&iter, bm, BM_EDGES_OF_MESH, NULL);
+               for( ; eed; eed=BMIter_Step(&iter)) {
+                       if (BM_Selected(bm, eed)) {
+                               BM_SetIndex(eed->v1, SELECT);
+                               BM_SetIndex(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)) BM_SetIndex(eve, 0);
+
+               efa = BMIter_New(&iter, bm, BM_FACES_OF_MESH, NULL);
+               for( ; efa; efa=BMIter_Step(&iter)) {
+                       if (BM_Selected(bm, efa)) {
+                               BMIter liter;
+                               BMLoop *l;
+
+                               l = BMIter_New(&liter, bm, BM_LOOPS_OF_FACE, efa);
+                               for (; l; l=BMIter_Step(&liter)) {
+                                       BM_SetIndex(l->v, SELECT);
+                               }
                        }
                }
        }
 
-       /* now we can count */
-       for(eve= em->verts.first; eve; eve= eve->next) {
-               if(eve->h==0) {
-                       if(eve->f1) countsel++;
-                       if(propmode) count++;
+       /* 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_GetIndex(eve)) {
+                       selstate[a] = 1;
+                       countsel++;
                }
+               if(propmode) count++;
        }
 
-        /* note: in prop mode we need at least 1 selected */
-       if (countsel==0) return;
+       /* note: in prop mode we need at least 1 selected */
+       if (countsel == 0) {
+               goto cleanup;
+       }
 
        /* check active */
-       if (em->selected.last) {
-               EditSelection *ese = em->selected.last;
-               if ( ese->type == EDITVERT ) {
-                       eve_act = (EditVert *)ese->data;
+       if (em->bm->selected.last) {
+               BMEditSelection *ese = em->bm->selected.last;
+               if ( ese->type == BM_VERT ) {
+                       eve_act = (BMVert *)ese->data;
                }
        }
 
 
-       if(propmode) t->total = count;
+       if(propmode) {
+               t->total = count;
+
+               /* allocating scratch arrays */
+               if (propmode & T_PROP_CONNECTED)
+                       dists = MEM_mallocN(em->bm->totvert * sizeof(float), "scratch nears");
+       }
        else t->total = countsel;
 
        tob= t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(Mesh EditMode)");
@@ -2051,16 +2170,15 @@ static void createTransEditVerts(bContext *C, TransInfo *t)
        copy_m3_m4(mtx, t->obedit->obmat);
        invert_m3_m3(smtx, mtx);
 
-       if(propmode & T_PROP_CONNECTED) {
-               editmesh_set_connectivity_distance(em, mtx);
-       }
+       if(propmode & T_PROP_CONNECTED)
+               editmesh_set_connectivity_distance(em, mtx, dists);
 
        /* detect CrazySpace [tm] */
        if(modifiers_getCageIndex(t->scene, t->obedit, NULL, 1)>=0) {
                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
@@ -2080,8 +2198,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;
@@ -2092,34 +2211,36 @@ 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);
 
                                /* 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) {
-                                       if (eve->f2) {
-                                               tob->dist= eve->tmp.fp;
-                                       }
-                                       else {
+                                       if (propmode & T_PROP_CONNECTED) {
+                                               tob->dist = dists[a];
+                                       } else {
                                                tob->flag |= TD_NOTCONNECTED;
                                                tob->dist = MAXFLOAT;
                                        }
                                }
 
                                /* CrazySpace */
-                               if(defmats || (quats && eve->tmp.p)) {
-                                       float mat[3][3], imat[3][3], qmat[3][3];
+                               if(defmats || (quats && BM_GetIndex(eve) != -1)) {
+                                       float mat[3][3], qmat[3][3], imat[3][3];
 
                                        /* use both or either quat and defmat correction */
-                                       if(quats && eve->tmp.f) {
-                                               quat_to_mat3( qmat,eve->tmp.p);
+                                       if(quats && BM_GetIndex(eve) != -1) {
+                                               quat_to_mat3(qmat, quats + 4*BM_GetIndex(eve));
 
                                                if(defmats)
                                                        mul_serie_m3(mat, mtx, qmat, defmats[a],
@@ -2141,9 +2262,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;
                                        }
                                }
@@ -2163,12 +2286,23 @@ static void createTransEditVerts(bContext *C, TransInfo *t)
                        }
                }
        }
-       
+
+cleanup:
        /* crazy space free */
        if(quats)
                MEM_freeN(quats);
        if(defmats)
                MEM_freeN(defmats);
+       if (dists)
+               MEM_freeN(dists);
+       
+       BLI_array_free(selstate);
+
+       if (t->flag & T_MIRROR)
+       {
+               EDBM_EndMirrorCache(em);
+               mirror = 1;
+       }
 }
 
 /* *** NODE EDITOR *** */
@@ -2340,30 +2474,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)) {
+                       BM_SetIndex(efa, 0);
+                       continue;
+               }
+               
+               BM_SetIndex(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++;
                }
        }
 
@@ -2382,20 +2519,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 (!BM_GetIndex(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));
                }
        }
 
@@ -2417,6 +2551,8 @@ void flushTransUVs(TransInfo *t)
 
        /* flush to 2d vector from internally used 3d vector */
        for(a=0, td= t->data2d; a<t->total; a++, td++) {
+               if (!td->loc2d) continue;
+               
                td->loc2d[0]= td->loc[0]*invx;
                td->loc2d[1]= td->loc[1]*invy;
 
@@ -4759,7 +4895,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);
                        }
                }
        }
@@ -4998,9 +5134,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)) {