svn merge -r38971:38972 https://svn.blender.org/svnroot/bf-blender/trunk/blender...
[blender.git] / source / blender / editors / transform / transform.c
index 181fb0f0aac2b4a508d43c89b3317318209b2ac5..6e9b78011a6dea6507024150f75c21786b3dd620 100644 (file)
@@ -84,6 +84,8 @@
 #include "BLI_editVert.h"
 #include "BLI_ghash.h"
 #include "BLI_linklist.h"
+#include "BLI_smallhash.h"
+#include "BLI_array.h"
 
 #include "UI_resources.h"
 
@@ -93,6 +95,8 @@
 
 #include "transform.h"
 
+#include <stdio.h>
+
 void drawTransformApply(const struct bContext *C, struct ARegion *ar, void *arg);
 int doEdgeSlide(TransInfo *t, float perc);
 
@@ -969,7 +973,7 @@ int transformEvent(TransInfo *t, wmEvent *event)
                        break;
                case OKEY:
                        if (t->flag & T_PROP_EDIT && event->shift) {
-                               t->prop_mode = (t->prop_mode + 1) % 6;
+                               t->prop_mode = (t->prop_mode + 1) % PROP_MODE_MAX;
                                calculatePropRatio(t);
                                t->redraw |= TREDRAW_HARD;
                        }
@@ -1006,9 +1010,11 @@ int transformEvent(TransInfo *t, wmEvent *event)
                        else view_editmove(event->type);
                        t->redraw= 1;
                        break;
-//             case NDOFMOTION:
-//            viewmoveNDOF(1);
-  //         break;
+#if 0
+               case NDOF_MOTION:
+                       // should have been caught by tranform_modal
+                       return OPERATOR_PASS_THROUGH;
+#endif
                default:
                        handled = 0;
                        break;
@@ -1017,43 +1023,6 @@ int transformEvent(TransInfo *t, wmEvent *event)
                // Numerical input events
                t->redraw |= handleNumInput(&(t->num), event);
 
-               // NDof input events
-               switch(handleNDofInput(&(t->ndof), event))
-               {
-                       case NDOF_CONFIRM:
-                               if ((t->options & CTX_NDOF) == 0)
-                               {
-                                       /* Confirm on normal transform only */
-                                       t->state = TRANS_CONFIRM;
-                               }
-                               break;
-                       case NDOF_CANCEL:
-                               if (t->options & CTX_NDOF)
-                               {
-                                       /* Cancel on pure NDOF transform */
-                                       t->state = TRANS_CANCEL;
-                               }
-                               else
-                               {
-                                       /* Otherwise, just redraw, NDof input was cancelled */
-                                       t->redraw |= TREDRAW_HARD;
-                               }
-                               break;
-                       case NDOF_NOMOVE:
-                               if (t->options & CTX_NDOF)
-                               {
-                                       /* Confirm on pure NDOF transform */
-                                       t->state = TRANS_CONFIRM;
-                               }
-                               break;
-                       case NDOF_REFRESH:
-                               t->redraw |= TREDRAW_HARD;
-                               break;
-                       default:
-                               handled = 0;
-                               break;
-               }
-
                // Snapping events
                t->redraw |= handleSnapping(t, event);
 
@@ -2886,10 +2855,6 @@ void initRotation(TransInfo *t)
        setInputPostFct(&t->mouse, postInputRotation);
        initMouseInputMode(t, &t->mouse, INPUT_ANGLE);
        
-       t->ndof.axis = 16;
-       /* Scale down and flip input for rotation */
-       t->ndof.factor[0] = -0.2f;
-       
        t->idx_max = 0;
        t->num.idx_max = 0;
        t->snap[0] = 0.0f;
@@ -3161,8 +3126,6 @@ int Rotation(TransInfo *t, const int UNUSED(mval[2]))
 
        final = t->values[0];
        
-       applyNDofInput(&t->ndof, &final);
-       
        snapGrid(t, &final);
        
        if ((t->con.mode & CON_APPLY) && t->con.applyRot) {
@@ -3216,11 +3179,6 @@ void initTrackball(TransInfo *t)
 
        initMouseInputMode(t, &t->mouse, INPUT_TRACKBALL);
 
-       t->ndof.axis = 40;
-       /* Scale down input for rotation */
-       t->ndof.factor[0] = 0.2f;
-       t->ndof.factor[1] = 0.2f;
-
        t->idx_max = 1;
        t->num.idx_max = 1;
        t->snap[0] = 0.0f;
@@ -3276,8 +3234,6 @@ int Trackball(TransInfo *t, const int UNUSED(mval[2]))
        phi[0] = t->values[0];
        phi[1] = t->values[1];
 
-       applyNDofInput(&t->ndof, phi);
-
        snapGrid(t, phi);
 
        if (hasNumInput(&t->num)) {
@@ -3331,8 +3287,6 @@ void initTranslation(TransInfo *t)
        t->num.flag = 0;
        t->num.idx_max = t->idx_max;
 
-       t->ndof.axis = (t->flag & T_2D_EDIT)? 1|2: 1|2|4;
-
        if(t->spacetype == SPACE_VIEW3D) {
                RegionView3D *rv3d = t->ar->regiondata;
 
@@ -3484,7 +3438,8 @@ static void applyTranslation(TransInfo *t, float vec[3]) {
                
                protectedTransBits(td->protectflag, tvec);
                
-               add_v3_v3v3(td->loc, td->iloc, tvec);
+               if (td->loc)
+                       add_v3_v3v3(td->loc, td->iloc, tvec);
                
                constraintTransLim(t, td);
        }
@@ -3507,7 +3462,6 @@ int Translation(TransInfo *t, const int UNUSED(mval[2]))
                headerTranslation(t, pvec, str);
        }
        else {
-               applyNDofInput(&t->ndof, t->values);
                snapGrid(t, t->values);
                applyNumInput(&t->num, t->values);
                if (hasNumInput(&t->num)) {
@@ -3616,10 +3570,6 @@ void initTilt(TransInfo *t)
 
        initMouseInputMode(t, &t->mouse, INPUT_ANGLE);
 
-       t->ndof.axis = 16;
-       /* Scale down and flip input for rotation */
-       t->ndof.factor[0] = -0.2f;
-
        t->idx_max = 0;
        t->num.idx_max = 0;
        t->snap[0] = 0.0f;
@@ -3643,8 +3593,6 @@ int Tilt(TransInfo *t, const int UNUSED(mval[2]))
 
        final = t->values[0];
 
-       applyNDofInput(&t->ndof, &final);
-
        snapGrid(t, &final);
 
        if (hasNumInput(&t->num)) {
@@ -3759,10 +3707,6 @@ void initPushPull(TransInfo *t)
 
        initMouseInputMode(t, &t->mouse, INPUT_VERTICAL_ABSOLUTE);
 
-       t->ndof.axis = 4;
-       /* Flip direction */
-       t->ndof.factor[0] = -1.0f;
-
        t->idx_max = 0;
        t->num.idx_max = 0;
        t->snap[0] = 0.0f;
@@ -3783,8 +3727,6 @@ int PushPull(TransInfo *t, const int UNUSED(mval[2]))
 
        distance = t->values[0];
 
-       applyNDofInput(&t->ndof, &distance);
-
        snapGrid(t, &distance);
 
        applyNumInput(&t->num, &distance);
@@ -4290,508 +4232,462 @@ int BoneEnvelope(TransInfo *t, const int UNUSED(mval[2]))
 }
 
 /* ********************  Edge Slide   *************** */
+static BMEdge *get_other_edge(BMesh *bm, BMVert *v, BMEdge *e)
+{
+       BMIter iter;
+       BMEdge *e2;
+
+       BM_ITER(e2, &iter, bm, BM_EDGES_OF_VERT, v) {
+               if (BM_TestHFlag(e2, BM_SELECT) && e2 != e)
+                       return e2;
+       }
+
+       return NULL;
+}
+
+static BMLoop *get_next_loop(BMesh *UNUSED(bm), BMVert *v, BMLoop *l, 
+                             BMEdge *olde, BMEdge *nexte, float vec[3])
+{
+       BMLoop *firstl;
+       float a[3] = {0.0f, 0.0f, 0.0f}, n[3] = {0.0f, 0.0f, 0.0f};
+       int i=0;
+
+       firstl = l;
+       do {
+               l = BM_OtherFaceLoop(l->e, l->f, v);
+               if (l->radial_next == l)
+                       return NULL;
+               
+               if (l->e == nexte) {
+                       if (i) {
+                               mul_v3_fl(a, 1.0f / (float)i);
+                       } else {
+                               float f1[3], f2[3], f3[3];
+
+                               sub_v3_v3v3(f1, BM_OtherEdgeVert(olde, v)->co, v->co);
+                               sub_v3_v3v3(f2, BM_OtherEdgeVert(nexte, v)->co, v->co);
+
+                               cross_v3_v3v3(f3, f1, l->f->no);
+                               cross_v3_v3v3(a, f2, l->f->no);
+                               mul_v3_fl(a, -1.0f);
+
+                               add_v3_v3(a, f3);
+                               mul_v3_fl(a, 0.5f);
+                       }
+                       
+                       VECCOPY(vec, a);
+                       return l;
+               } else {
+                       sub_v3_v3v3(n, BM_OtherEdgeVert(l->e, v)->co, v->co);
+                       add_v3_v3v3(a, a, n);
+                       i += 1;
+               }
+
+               if (BM_OtherFaceLoop(l->e, l->f, v)->e == nexte) {
+                       if (i)
+                               mul_v3_fl(a, 1.0f / (float)i);
+                       
+                       VECCOPY(vec, a);
+                       return BM_OtherFaceLoop(l->e, l->f, v);
+               }
+               
+               l = l->radial_next;
+       } while (l != firstl); 
+
+       if (i)
+               mul_v3_fl(a, 1.0f / (float)i);
+       
+       VECCOPY(vec, a);
+       
+       return NULL;
+}
 
 static int createSlideVerts(TransInfo *t)
 {
        Mesh *me = t->obedit->data;
-       EditMesh *em = me->edit_mesh;
-       EditFace *efa;
-       EditEdge *eed,*first=NULL,*last=NULL, *temp = NULL;
-       EditVert *ev, *nearest = NULL;
-       LinkNode *edgelist = NULL, *vertlist=NULL, *look;
-       GHash *vertgh;
+       BMEditMesh *em = me->edit_btmesh;
+       BMesh *bm = em->bm;
+       BMIter iter, iter2;
+       BMEdge *e, *e1, *ee, *le;
+       BMVert *v, *v2, *first;
+       BMLoop *l, *l1, *l2;
        TransDataSlideVert *tempsv;
-       float vertdist; // XXX, projectMat[4][4];
-       int i, j, numsel, numadded=0, timesthrough = 0, vertsel=0;
-       /* UV correction vars */
-       GHash **uvarray= NULL;
+       BMBVHTree *btree = BMBVH_NewBVH(em);
+       SmallHash table;
        SlideData *sld = MEM_callocN(sizeof(*sld), "sld");
-       int  uvlay_tot= CustomData_number_of_layers(&em->fdata, CD_MTFACE);
-       int uvlay_idx;
-       TransDataSlideUv *slideuvs=NULL, *suv=NULL, *suv_last=NULL;
-       RegionView3D *v3d = t->ar ? t->ar->regiondata : NULL; /* background mode support */
+       View3D *v3d = t->sa ? t->sa->spacedata.first : NULL;
+       RegionView3D *rv3d = t->ar ? t->ar->regiondata : NULL; /* background mode support */
+       ARegion *ar = t->ar;
        float projectMat[4][4];
-       float start[3] = {0.0f, 0.0f, 0.0f}, end[3] = {0.0f, 0.0f, 0.0f};
-       float vec[3];
-       float totvec=0.0;
+       float start[3] = {0.0f, 0.0f, 0.0f}, dir[3], end[3] = {0.0f, 0.0f, 0.0f};
+       float vec[3], vec2[3], lastvec[3], size, dis=0.0, z;
+       int numsel, i, j;
 
        if (!v3d) {
                /*ok, let's try to survive this*/
                unit_m4(projectMat);
        } else {
-               ED_view3d_ob_project_mat_get(v3d, t->obedit, projectMat);
+               ED_view3d_ob_project_mat_get(rv3d, t->obedit, projectMat);
        }
        
-       numsel =0;
-
-       // Get number of selected edges and clear some flags
-       for(eed=em->edges.first;eed;eed=eed->next) {
-               eed->f1 = 0;
-               eed->f2 = 0;
-               if(eed->f & SELECT) numsel++;
-       }
-
-       for(ev=em->verts.first;ev;ev=ev->next) {
-               ev->f1 = 0;
-       }
+       BLI_smallhash_init(&sld->vhash);
+       BLI_smallhash_init(&sld->origfaces);
+       BLI_smallhash_init(&table);
+       
+       /*ensure valid selection*/
+       BM_ITER(v, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
+               if (BM_TestHFlag(v, BM_SELECT)) {
+                       numsel = 0;
+                       BM_ITER(e, &iter2, em->bm, BM_EDGES_OF_VERT, v) {
+                               if (BM_TestHFlag(e, BM_SELECT)) {
+                                       /*BMESH_TODO: this is probably very evil,
+                                         set v->e to a selected edge*/
+                                       v->e = e;
 
-       //Make sure each edge only has 2 faces
-       // make sure loop doesn't cross face
-       for(efa=em->faces.first;efa;efa=efa->next) {
-               int ct = 0;
-               if(efa->e1->f & SELECT) {
-                       ct++;
-                       efa->e1->f1++;
-                       if(efa->e1->f1 > 2) {
-                               //BKE_report(op->reports, RPT_ERROR, "3+ face edge");
-                               MEM_freeN(sld);
-                               return 0;
-                       }
-               }
-               if(efa->e2->f & SELECT) {
-                       ct++;
-                       efa->e2->f1++;
-                       if(efa->e2->f1 > 2) {
-                               //BKE_report(op->reports, RPT_ERROR, "3+ face edge");
-                               MEM_freeN(sld);
-                               return 0;
-                       }
-               }
-               if(efa->e3->f & SELECT) {
-                       ct++;
-                       efa->e3->f1++;
-                       if(efa->e3->f1 > 2) {
-                               //BKE_report(op->reports, RPT_ERROR, "3+ face edge");
-                               MEM_freeN(sld);
-                               return 0;
+                                       numsel++;
+                               }
                        }
-               }
-               if(efa->e4 && efa->e4->f & SELECT) {
-                       ct++;
-                       efa->e4->f1++;
-                       if(efa->e4->f1 > 2) {
-                               //BKE_report(op->reports, RPT_ERROR, "3+ face edge");
-                               MEM_freeN(sld);
-                               return 0;
+
+                       if (numsel > 2) {
+                               return 0; //invalid edge selection
                        }
                }
-               // Make sure loop is not 2 edges of same face
-               if(ct > 1) {
-                  //BKE_report(op->reports, RPT_ERROR, "Loop crosses itself");
-                       MEM_freeN(sld);
-                       return 0;
+       }
+
+       BM_ITER(e, &iter, em->bm, BM_EDGES_OF_MESH, NULL) {
+               if (BM_TestHFlag(e, BM_SELECT)) {
+                       if (BM_Edge_FaceCount(e) > 2 || BM_Edge_FaceCount(e) == 0)
+                               return 0; //can't handle more then 2 faces around an edge
                }
        }
 
-       // Get # of selected verts
-       for(ev=em->verts.first;ev;ev=ev->next) {
-               if(ev->f & SELECT) vertsel++;
+       j = 0;
+       BM_ITER(v, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
+               if (BM_TestHFlag(v, BM_SELECT)) {
+                       BM_SetIndex(v, 1);
+                       BLI_smallhash_insert(&table, (uintptr_t)v, SET_INT_IN_POINTER(j));
+                       j += 1;
+               } else BM_SetIndex(v, 0);
        }
 
-       // Test for multiple segments
-       if(vertsel > numsel+1) {
-               //BKE_report(op->reports, RPT_ERROR, "Please choose a single edge loop");
-               MEM_freeN(sld);
+       if (!j)
                return 0;
-       }
 
-       // Get the edgeloop in order - mark f1 with SELECT once added
-       for(eed=em->edges.first;eed;eed=eed->next) {
-               if((eed->f & SELECT) && !(eed->f1 & SELECT)) {
-                       // If this is the first edge added, just put it in
-                       if(!edgelist) {
-                               BLI_linklist_prepend(&edgelist,eed);
-                               numadded++;
-                               first = eed;
-                               last  = eed;
-                               eed->f1 = SELECT;
-                       } else {
-                               if(editedge_getSharedVert(eed, last)) {
-                                       BLI_linklist_append(&edgelist,eed);
-                                       eed->f1 = SELECT;
-                                       numadded++;
-                                       last = eed;
-                               }  else if(editedge_getSharedVert(eed, first)) {
-                                       BLI_linklist_prepend(&edgelist,eed);
-                                       eed->f1 = SELECT;
-                                       numadded++;
-                                       first = eed;
-                               }
-                       }
-               }
-               if(eed->next == NULL && numadded != numsel) {
-                       eed=em->edges.first;
-                       timesthrough++;
-               }
+       tempsv = MEM_callocN(sizeof(TransDataSlideVert)*j, "tempsv");
+
+       j = 0;
+       while (1) {
+               v = NULL;
+               BM_ITER(v, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
+                       if (BM_GetIndex(v))
+                               break;
 
-               // It looks like there was an unexpected case - Hopefully should not happen
-               if(timesthrough >= numsel*2) {
-                       BLI_linklist_free(edgelist,NULL);
-                       //BKE_report(op->reports, RPT_ERROR, "Could not order loop");
-                       MEM_freeN(sld);
-                       return 0;
                }
-       }
 
-       // Put the verts in order in a linklist
-       look = edgelist;
-       while(look) {
-               eed = look->link;
-               if(!vertlist) {
-                       if(look->next) {
-                               temp = look->next->link;
+               if (!v)
+                       break;
 
-                               //This is the first entry takes care of extra vert
-                               if(eed->v1 != temp->v1 && eed->v1 != temp->v2) {
-                                       BLI_linklist_append(&vertlist,eed->v1);
-                                       eed->v1->f1 = 1;
-                               } else {
-                                       BLI_linklist_append(&vertlist,eed->v2);
-                                       eed->v2->f1 = 1;
-                               }
-                       } else {
-                               //This is the case that we only have 1 edge
-                               BLI_linklist_append(&vertlist,eed->v1);
-                               eed->v1->f1 = 1;
-                       }
-               }
-               // for all the entries
-               if(eed->v1->f1 != 1) {
-                       BLI_linklist_append(&vertlist,eed->v1);
-                       eed->v1->f1 = 1;
-               } else  if(eed->v2->f1 != 1) {
-                       BLI_linklist_append(&vertlist,eed->v2);
-                       eed->v2->f1 = 1;
-               }
-               look = look->next;
-       }
-
-       // populate the SlideVerts
-
-       vertgh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "createSlideVerts gh");
-       look = vertlist;
-       while(look) {
-               i=0;
-               j=0;
-               ev = look->link;
-               tempsv = (struct TransDataSlideVert*)MEM_mallocN(sizeof(struct TransDataSlideVert),"SlideVert");
-               tempsv->up = NULL;
-               tempsv->down = NULL;
-               tempsv->origvert.co[0] = ev->co[0];
-               tempsv->origvert.co[1] = ev->co[1];
-               tempsv->origvert.co[2] = ev->co[2];
-               tempsv->origvert.no[0] = ev->no[0];
-               tempsv->origvert.no[1] = ev->no[1];
-               tempsv->origvert.no[2] = ev->no[2];
-               // i is total edges that vert is on
-               // j is total selected edges that vert is on
-
-               for(eed=em->edges.first;eed;eed=eed->next) {
-                       if(eed->v1 == ev || eed->v2 == ev) {
-                               i++;
-                               if(eed->f & SELECT) {
-                                        j++;
-                               }
-                       }
-               }
-               // If the vert is in the middle of an edge loop, it touches 2 selected edges and 2 unselected edges
-               if(i == 4 && j == 2) {
-                       for(eed=em->edges.first;eed;eed=eed->next) {
-                               if(editedge_containsVert(eed, ev)) {
-                                       if(!(eed->f & SELECT)) {
-                                               if(!tempsv->up) {
-                                                       tempsv->up = eed;
-                                               } else if (!(tempsv->down)) {
-                                                       tempsv->down = eed;
-                                               }
-                                       }
-                               }
-                       }
-               }
-               // If it is on the end of the loop, it touches 1 selected and as least 2 more unselected
-               if(i >= 3 && j == 1) {
-                       for(eed=em->edges.first;eed;eed=eed->next) {
-                               if(editedge_containsVert(eed, ev) && eed->f & SELECT) {
-                                       for(efa = em->faces.first;efa;efa=efa->next) {
-                                               if(editface_containsEdge(efa, eed)) {
-                                                       if(editedge_containsVert(efa->e1, ev) && efa->e1 != eed) {
-                                                               if(!tempsv->up) {
-                                                                       tempsv->up = efa->e1;
-                                                               } else if (!(tempsv->down)) {
-                                                                       tempsv->down = efa->e1;
-                                                               }
-                                                       }
-                                                       if(editedge_containsVert(efa->e2, ev) && efa->e2 != eed) {
-                                                               if(!tempsv->up) {
-                                                                       tempsv->up = efa->e2;
-                                                               } else if (!(tempsv->down)) {
-                                                                       tempsv->down = efa->e2;
-                                                               }
-                                                       }
-                                                       if(editedge_containsVert(efa->e3, ev) && efa->e3 != eed) {
-                                                               if(!tempsv->up) {
-                                                                       tempsv->up = efa->e3;
-                                                               } else if (!(tempsv->down)) {
-                                                                       tempsv->down = efa->e3;
-                                                               }
-                                                       }
-                                                       if(efa->e4) {
-                                                               if(editedge_containsVert(efa->e4, ev) && efa->e4 != eed) {
-                                                                       if(!tempsv->up) {
-                                                                               tempsv->up = efa->e4;
-                                                                       } else if (!(tempsv->down)) {
-                                                                               tempsv->down = efa->e4;
-                                                                       }
-                                                               }
-                                                       }
+               if (!v->e)
+                       continue;
+               
+               first = v;
 
-                                               }
-                                       }
-                               }
+               /*walk along the edge loop*/
+               e = v->e;
+
+               /*first, rewind*/
+               numsel = 0;
+               do {
+                       e = get_other_edge(bm, v, e);
+                       if (!e) {
+                               e = v->e;
+                               break;
                        }
-               }
-               if(i > 4 && j == 2) {
-                       BLI_ghash_free(vertgh, NULL, (GHashValFreeFP)MEM_freeN);
-                       BLI_linklist_free(vertlist,NULL);
-                       BLI_linklist_free(edgelist,NULL);
-                       return 0;
-               }
-               BLI_ghash_insert(vertgh,ev,tempsv);
 
-               look = look->next;
-       }
+                       numsel += 1;
 
-       // make sure the UPs and DOWNs are 'faceloops'
-       // Also find the nearest slidevert to the cursor
+                       if (!BM_GetIndex(BM_OtherEdgeVert(e, v)))
+                               break;
 
-       look = vertlist;
-       nearest = NULL;
-       vertdist = -1;
-       while(look) {
-               tempsv  = BLI_ghash_lookup(vertgh,(EditVert*)look->link);
+                       v = BM_OtherEdgeVert(e, v);
+               } while (e != first->e);
 
-               if(!tempsv->up || !tempsv->down) {
-                       //BKE_report(op->reports, RPT_ERROR, "Missing rails");
-                       BLI_ghash_free(vertgh, NULL, (GHashValFreeFP)MEM_freeN);
-                       BLI_linklist_free(vertlist,NULL);
-                       BLI_linklist_free(edgelist,NULL);
-                       return 0;
-               }
+               BM_SetIndex(v, 0);
 
-               if(me->drawflag & ME_DRAWEXTRA_EDGELEN) {
-                       if(!(tempsv->up->f & SELECT)) {
-                               tempsv->up->f |= SELECT;
-                               tempsv->up->f2 |= 16;
-                       } else {
-                               tempsv->up->f2 |= ~16;
-                       }
-                       if(!(tempsv->down->f & SELECT)) {
-                               tempsv->down->f |= SELECT;
-                               tempsv->down->f2 |= 16;
-                       } else {
-                               tempsv->down->f2 |= ~16;
-                       }
-               }
+               l1 = l2 = l = NULL;
+               l1 = e->l;
+               l2 = e->l->radial_next;
 
-               if(look->next != NULL) {
-                       TransDataSlideVert *sv;
-                       
-                       ev = (EditVert*)look->next->link;
-                       sv = BLI_ghash_lookup(vertgh, ev);
+               l = BM_OtherFaceLoop(l1->e, l1->f, v);
+               sub_v3_v3v3(vec, BM_OtherEdgeVert(l->e, v)->co, v->co);
+
+               if (l2 != l1) {
+                       l = BM_OtherFaceLoop(l2->e, l2->f, v);
+                       sub_v3_v3v3(vec2, BM_OtherEdgeVert(l->e, v)->co, v->co);
+               } else {
+                       l2 = NULL;
+               }
 
-                       if(sv) {
-                               float co[3], co2[3], tvec[3];
+               /*iterate over the loop*/
+               first = v;
+               j = 0;
+               do {
+                       TransDataSlideVert *sv = tempsv + j;
 
-                               ev = (EditVert*)look->link;
+                       sv->v = v;
+                       sv->origvert = *v;
+                       VECCOPY(sv->upvec, vec);
+                       if (l2)
+                               VECCOPY(sv->downvec, vec2);
 
-                               if(!sharesFace(em, tempsv->up,sv->up)) {
-                                       EditEdge *swap;
-                                       swap = sv->up;
-                                       sv->up = sv->down;
-                                       sv->down = swap;
-                               }
-                               
-                               if (v3d) {
-                                       ED_view3d_project_float(t->ar, tempsv->up->v1->co, co, projectMat);
-                                       ED_view3d_project_float(t->ar, tempsv->up->v2->co, co2, projectMat);
-                               }
+                       l = BM_OtherFaceLoop(l1->e, l1->f, v);
+                       sv->up = BM_OtherEdgeVert(l->e, v);
 
-                               if (ev == tempsv->up->v1) {
-                                       sub_v3_v3v3(tvec, co, co2);
-                               } else {
-                                       sub_v3_v3v3(tvec, co2, co);
-                               }
+                       if (l2) {
+                               l = BM_OtherFaceLoop(l2->e, l2->f, v);
+                               sv->down = BM_OtherEdgeVert(l->e, v);
+                       }
 
-                               add_v3_v3(start, tvec);
+                       v2=v, v = BM_OtherEdgeVert(e, v);
 
-                               if (v3d) {
-                                       ED_view3d_project_float(t->ar, tempsv->down->v1->co, co, projectMat);
-                                       ED_view3d_project_float(t->ar, tempsv->down->v2->co, co2, projectMat);
-                               }
+                       e1 = e;
+                       e = get_other_edge(bm, v, e);
+                       if (!e) {
+                               //v2=v, v = BM_OtherEdgeVert(l1->e, v);
 
-                               if (ev == tempsv->down->v1) {
-                                       sub_v3_v3v3(tvec, co2, co);
-                               } else {
-                                       sub_v3_v3v3(tvec, co, co2);
+                               sv = tempsv + j + 1;
+                               sv->v = v;
+                               sv->origvert = *v;
+                               
+                               l = BM_OtherFaceLoop(l1->e, l1->f, v);
+                               sv->up = BM_OtherEdgeVert(l->e, v);
+                               sub_v3_v3v3(sv->upvec, BM_OtherEdgeVert(l->e, v)->co, v->co);
+
+                               if (l2) {
+                                       l = BM_OtherFaceLoop(l2->e, l2->f, v);
+                                       sv->down = BM_OtherEdgeVert(l->e, v);
+                                       sub_v3_v3v3(sv->downvec, BM_OtherEdgeVert(l->e, v)->co, v->co);
                                }
 
-                               add_v3_v3(end, tvec);
-
-                               totvec += 1.0f;
-                               nearest = (EditVert*)look->link;
+                               BM_SetIndex(v, 0);
+                               BM_SetIndex(v2, 0);
+                               
+                               j += 2;
+                               break;
                        }
-               }
 
+                       l1 = get_next_loop(bm, v, l1, e1, e, vec);
+                       l2 = l2 ? get_next_loop(bm, v, l2, e1, e, vec2) : NULL;
 
+                       j += 1;
 
-               look = look->next;
+                       BM_SetIndex(v, 0);
+                       BM_SetIndex(v2, 0);
+               } while (e != first->e && l1);
        }
 
-       add_v3_v3(start, end);
-       mul_v3_fl(start, 0.5f*(1.0f/totvec));
-       VECCOPY(vec, start);
-       start[0] = t->mval[0];
-       start[1] = t->mval[1];
-       add_v3_v3v3(end, start, vec);
+       //EDBM_clear_flag_all(em, BM_SELECT);
 
+       sld->sv = tempsv;
+       sld->totsv = j;
+       
+       /*find mouse vector*/
+       dis = z = -1.0f;
+       size = 50.0;
+       zero_v3(lastvec); zero_v3(dir);
+       ee = le = NULL;
+       BM_ITER(e, &iter, em->bm, BM_EDGES_OF_MESH, NULL) {
+               if (BM_TestHFlag(e, BM_SELECT)) {
+                       BMIter iter2;
+                       BMEdge *e2;
+                       float vec1[3], dis2, mval[2] = {t->mval[0], t->mval[1]}, d;
+                                               
+                       /*search cross edges for visible edge to the mouse cursor,
+              then use the shared vertex to calculate screen vector*/
+                       dis2 = -1.0f;
+                       for (i=0; i<2; i++) {
+                               v = i?e->v1:e->v2;
+                               BM_ITER(e2, &iter2, em->bm, BM_EDGES_OF_VERT, v) {
+                                       if (BM_TestHFlag(e2, BM_SELECT))
+                                               continue;
+                                       
+                                       if (!BMBVH_EdgeVisible(btree, e2, ar, v3d, t->obedit))
+                                               continue;
+                                       
+                                       j = GET_INT_FROM_POINTER(BLI_smallhash_lookup(&table, (uintptr_t)v));
+
+                                       if (tempsv[j].down) {
+                                               ED_view3d_project_float_v3(ar, tempsv[j].down->co, vec1, projectMat);
+                                       } else {
+                                               add_v3_v3v3(vec1, v->co, tempsv[j].downvec);
+                                               ED_view3d_project_float_v3(ar, vec1, vec1, projectMat);
+                                       }
+                                       
+                                       if (tempsv[j].up) {
+                                               ED_view3d_project_float_v3(ar, tempsv[j].up->co, vec2, projectMat);
+                                       } else {
+                                               add_v3_v3v3(vec1, v->co, tempsv[j].upvec);
+                                               ED_view3d_project_float_v3(ar, vec2, vec2, projectMat);
+                                       }
 
-       /* Ensure minimum screen distance, when looking top down on edge loops */
-#define EDGE_SLIDE_MIN 30
-       if (len_squared_v2v2(start, end) < (EDGE_SLIDE_MIN * EDGE_SLIDE_MIN)) {
-               if(ABS(start[0]-end[0]) + ABS(start[1]-end[1]) < 4.0f) {
-                       /* even more exceptional case, points are ontop of eachother */
-                       end[0]= start[0];
-                       end[1]= start[1] + EDGE_SLIDE_MIN;
-               }
-               else {
-                       sub_v2_v2(end, start);
-                       normalize_v2(end);
-                       mul_v2_fl(end, EDGE_SLIDE_MIN);
-                       add_v2_v2(end, start);
+                                       d = dist_to_line_segment_v2(mval, vec1, vec2);
+                                       if (dis2 == -1.0f || d < dis2) {
+                                               dis2 = d;
+                                               ee = e2;
+                                               size = len_v3v3(vec1, vec2);
+                                               sub_v3_v3v3(dir, vec1, vec2);
+                                       }
+                               }
+                       }
                }
        }
-#undef EDGE_SLIDE_MIN
+       
+       em->bm->ob = t->obedit;
+       bmesh_begin_edit(em->bm, BMOP_UNTAN_MULTIRES);
 
+       /*create copies of faces for customdata projection*/
+       tempsv = sld->sv;
+       for (i=0; i<sld->totsv; i++, tempsv++) {
+               BMIter fiter, liter;
+               BMFace *f;
+               BMLoop *l;
+               
+               BM_ITER(f, &fiter, em->bm, BM_FACES_OF_VERT, tempsv->v) {
+                       
+                       if (!BLI_smallhash_haskey(&sld->origfaces, (uintptr_t)f)) {
+                               BMFace *copyf = BM_Copy_Face(em->bm, f, 1, 1);
+                               
+                               BM_Select(em->bm, copyf, 0);
+                               BM_SetHFlag(copyf, BM_HIDDEN);
+                               BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, copyf) {
+                                       BM_Select(em->bm, l->v, 0);
+                                       BM_SetHFlag(l->v, BM_HIDDEN);
+                                       BM_Select(em->bm, l->e, 0);
+                                       BM_SetHFlag(l->e, BM_HIDDEN);
+                               }
 
-       sld->start[0] = (int) start[0];
-       sld->start[1] = (int) start[1];
-       sld->end[0] = (int) end[0];
-       sld->end[1] = (int) end[1];
+                               BLI_smallhash_insert(&sld->origfaces, (uintptr_t)f, copyf);
+                       }
+               }
+
+               BLI_smallhash_insert(&sld->vhash, (uintptr_t)tempsv->v, tempsv);
+       }
+       
+       sld->em = em;
        
-       if (uvlay_tot) { // XXX && (scene->toolsettings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT)) {
-               int maxnum = 0;
+       /*zero out start*/
+       zero_v3(start);
+       
+       /*dir holds a vector along edge loop*/
+       copy_v3_v3(end, dir);
+       mul_v3_fl(end, 0.5);
+       
+       sld->start[0] = t->mval[0] + start[0];
+       sld->start[1] = t->mval[1] + start[1];
 
-               uvarray = MEM_callocN( uvlay_tot * sizeof(GHash *), "SlideUVs Array");
-               sld->totuv = uvlay_tot;
-               suv_last = slideuvs = MEM_callocN( uvlay_tot * (numadded+1) * sizeof(TransDataSlideUv), "SlideUVs"); /* uvLayers * verts */
-               suv = NULL;
+       sld->end[0] = t->mval[0] + end[0];
+       sld->end[1] = t->mval[1] + end[1];
+       
+       sld->perc = 0.0f;
+       
+       t->customData = sld;
+       
+       BLI_smallhash_release(&table);
+       BMBVH_FreeBVH(btree);
+       
+       return 1;
+}
 
-               for (uvlay_idx=0; uvlay_idx<uvlay_tot; uvlay_idx++) {
+void projectSVData(TransInfo *t, int final)
+{
+       SlideData *sld = t->customData;
+       TransDataSlideVert *tempsv;
+       BMEditMesh *em = sld->em;
+       SmallHash visit;
+       int i;
+       
+       if (!em)
+               return;
+       
+       /* BMESH_TODO, (t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT)
+        * currently all vertex data is interpolated which is nice mostly
+        * except for shape keys where you dont want to modify UVs for eg.
+        * current BMesh code doesnt make it easy to pick which data we interpolate
+        * - campbell */
 
-                       uvarray[uvlay_idx] = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "createSlideVerts2 gh");
+       BLI_smallhash_init(&visit);
+       
+               for (i=0, tempsv=sld->sv; i<sld->totsv; i++, tempsv++) {
+               BMIter fiter;
+               BMFace *f;
+               
+               BM_ITER(f, &fiter, em->bm, BM_FACES_OF_VERT, tempsv->v) {
+                       BMIter liter2;
+                       BMFace *copyf, *copyf2;
+                       BMLoop *l2;
+                       int sel, do_vdata;
+                       
+                       if (BLI_smallhash_haskey(&visit, (uintptr_t)f))
+                               continue;
+                       
+                       BLI_smallhash_insert(&visit, (uintptr_t)f, NULL);
+                       
+                       /*the face attributes of the copied face will get
+                         copied over, so its necessary to save the selection state*/
+                       sel = BM_TestHFlag(f, BM_SELECT);
+                       
+                       copyf2 = BLI_smallhash_lookup(&sld->origfaces, (uintptr_t)f);
+                       
+                       /*project onto copied projection face*/
+                       BM_ITER(l2, &liter2, em->bm, BM_LOOPS_OF_FACE, f) {
+                               copyf = copyf2;
+                               do_vdata = l2->v==tempsv->v;
+                               
+                               if (BM_TestHFlag(l2->e, BM_SELECT) || BM_TestHFlag(l2->prev->e, BM_SELECT)) {
+                                       BMLoop *l3 = l2;
+                                       
+                                       do_vdata = 1;
+                                       
+                                       if (!BM_TestHFlag(l2->e, BM_SELECT))
+                                               l3 = l3->prev;
+                                       
+                                       if (sld->perc < 0.0 && BM_Vert_In_Face(l3->radial_next->f, tempsv->down)) {
+                                               copyf = BLI_smallhash_lookup(&sld->origfaces, (uintptr_t)l3->radial_next->f);
+                                       } else if (sld->perc > 0.0 && BM_Vert_In_Face(l3->radial_next->f, tempsv->up)) {
+                                               copyf = BLI_smallhash_lookup(&sld->origfaces, (uintptr_t)l3->radial_next->f);
+                                       }
+                               }
+                               
+                               BM_loop_interp_from_face(em->bm, l2, copyf, do_vdata, 0);
 
-                       for(ev=em->verts.first;ev;ev=ev->next) {
-                               ev->tmp.l = 0;
-                       }
-                       look = vertlist;
-                       while(look) {
-                               float *uv_new;
-                               tempsv  = BLI_ghash_lookup(vertgh,(EditVert*)look->link);
-
-                               ev = look->link;
-                               suv = NULL;
-                               for(efa = em->faces.first;efa;efa=efa->next) {
-                                       if (ev->tmp.l != -1) { /* test for self, in this case its invalid */
-                                               int k=-1; /* face corner */
-
-                                               /* Is this vert in the faces corner? */
-                                               if              (efa->v1==ev)                           k=0;
-                                               else if (efa->v2==ev)                           k=1;
-                                               else if (efa->v3==ev)                           k=2;
-                                               else if (efa->v4 && efa->v4==ev)        k=3;
-
-                                               if (k != -1) {
-                                                       MTFace *tf = CustomData_em_get_n(&em->fdata, efa->data, CD_MTFACE, uvlay_idx);
-                                                       EditVert *ev_up, *ev_down;
-
-                                                       uv_new = tf->uv[k];
-
-                                                       if (ev->tmp.l) {
-                                                               if (fabs(suv->origuv[0]-uv_new[0]) > 0.0001f || fabs(suv->origuv[1]-uv_new[1]) > 0.0001f) {
-                                                                       ev->tmp.l = -1; /* Tag as invalid */
-                                                                       BLI_linklist_free(suv->fuv_list,NULL);
-                                                                       suv->fuv_list = NULL;
-                                                                       BLI_ghash_remove(uvarray[uvlay_idx],ev, NULL, NULL);
-                                                                       suv = NULL;
-                                                                       break;
-                                                               }
-                                                       } else {
-                                                               ev->tmp.l = 1;
-                                                               suv = suv_last;
-
-                                                               suv->fuv_list = NULL;
-                                                               suv->uv_up = suv->uv_down = NULL;
-                                                               suv->origuv[0] = uv_new[0];
-                                                               suv->origuv[1] = uv_new[1];
-
-                                                               BLI_linklist_prepend(&suv->fuv_list, uv_new);
-                                                               BLI_ghash_insert(uvarray[uvlay_idx],ev,suv);
-
-                                                               suv_last++; /* advance to next slide UV */
-                                                               maxnum++;
-                                                       }
-
-                                                       /* Now get the uvs along the up or down edge if we can */
-                                                       if (suv) {
-                                                               if (!suv->uv_up) {
-                                                                       ev_up = editedge_getOtherVert(tempsv->up,ev);
-                                                                       if              (efa->v1==ev_up)                                suv->uv_up = tf->uv[0];
-                                                                       else if (efa->v2==ev_up)                                suv->uv_up = tf->uv[1];
-                                                                       else if (efa->v3==ev_up)                                suv->uv_up = tf->uv[2];
-                                                                       else if (efa->v4 && efa->v4==ev_up)             suv->uv_up = tf->uv[3];
-                                                               }
-                                                               if (!suv->uv_down) { /* if the first face was apart of the up edge, it cant be apart of the down edge */
-                                                                       ev_down = editedge_getOtherVert(tempsv->down,ev);
-                                                                       if              (efa->v1==ev_down)                              suv->uv_down = tf->uv[0];
-                                                                       else if (efa->v2==ev_down)                              suv->uv_down = tf->uv[1];
-                                                                       else if (efa->v3==ev_down)                              suv->uv_down = tf->uv[2];
-                                                                       else if (efa->v4 && efa->v4==ev_down)   suv->uv_down = tf->uv[3];
-                                                               }
-
-                                                               /* Copy the pointers to the face UV's */
-                                                               BLI_linklist_prepend(&suv->fuv_list, uv_new);
-                                                       }
-                                               }
+                               if (final) {
+                                       BM_loop_interp_multires(em->bm, l2, copyf);     
+                                       if (copyf2 != copyf) {
+                                               BM_loop_interp_multires(em->bm, l2, copyf2);
                                        }
                                }
-                               look = look->next;
                        }
-               } /* end uv layer loop */
-       } /* end uvlay_tot */
-
-       sld->uvhash = uvarray;
-       sld->slideuv = slideuvs;
-       sld->vhash = vertgh;
-       sld->nearest = nearest;
-       sld->vertlist = vertlist;
-       sld->edgelist = edgelist;
-       sld->suv_last = suv_last;
-       sld->uvlay_tot = uvlay_tot;
-
-       // we should have enough info now to slide
-
-       t->customData = sld;
-
-       return 1;
+                       
+                       /*make sure face-attributes are correct (e.g. MTexPoly)*/
+                       BM_Copy_Attributes(em->bm, em->bm, copyf2, f);
+                       
+                       /*restore selection, and undo hidden flag*/
+                       BM_ClearHFlag(f, BM_HIDDEN);
+                       if (sel)
+                               BM_Select(em->bm, f, sel);
+               }
+       }
+       
+       BLI_smallhash_release(&visit);
 }
 
 void freeSlideVerts(TransInfo *t)
 {
-       TransDataSlideUv *suv;
        SlideData *sld = t->customData;
-       Mesh *me = t->obedit->data;
-       int uvlay_idx;
-
+       SmallHashIter hiter;
+       BMFace *copyf;
+       
+#if 0 /*BMESH_TODO*/
        if(me->drawflag & ME_DRAWEXTRA_EDGELEN) {
                TransDataSlideVert *tempsv;
                LinkNode *look = sld->vertlist;
@@ -4805,31 +4701,38 @@ void freeSlideVerts(TransInfo *t)
                        look = look->next;
                }
        }
-
-       //BLI_ghash_free(edgesgh, freeGHash, NULL);
-       BLI_ghash_free(sld->vhash, NULL, (GHashValFreeFP)MEM_freeN);
-       BLI_linklist_free(sld->vertlist, NULL);
-       BLI_linklist_free(sld->edgelist, NULL);
-
-       if (sld->uvlay_tot) {
-               for (uvlay_idx=0; uvlay_idx<sld->uvlay_tot; uvlay_idx++) {
-                       BLI_ghash_free(sld->uvhash[uvlay_idx], NULL, NULL);
-               }
-
-               suv = sld->suv_last-1;
-               while (suv >= sld->slideuv) {
-                       if (suv->fuv_list) {
-                               BLI_linklist_free(suv->fuv_list,NULL);
-                       }
-                       suv--;
-               }
-
-               MEM_freeN(sld->slideuv);
-               MEM_freeN(sld->uvhash);
+#endif
+       
+       if (!sld)
+               return;
+       
+       /*handle multires reprojection, done
+      on transform completion since it's
+      really slow -joeedh*/
+       if (t->state != TRANS_CANCEL) {
+               projectSVData(t, 1);
+       } else {
+               sld->perc = 0.0;
+               projectSVData(t, 0);
+       }
+       
+       copyf = BLI_smallhash_iternew(&sld->origfaces, &hiter, NULL);
+       for (; copyf; copyf=BLI_smallhash_iternext(&hiter, NULL)) {
+               BM_Kill_Face_Verts(sld->em->bm, copyf);
        }
+       
+       sld->em->bm->ob = t->obedit;
+       bmesh_end_edit(sld->em->bm, BMOP_UNTAN_MULTIRES);
 
+       BLI_smallhash_release(&sld->vhash);
+       BLI_smallhash_release(&sld->origfaces);
+       
+       MEM_freeN(sld->sv);
        MEM_freeN(sld);
+       
        t->customData = NULL;
+       
+       recalcData(t);
 }
 
 void initEdgeSlide(TransInfo *t)
@@ -4868,111 +4771,28 @@ void initEdgeSlide(TransInfo *t)
 
 int doEdgeSlide(TransInfo *t, float perc)
 {
-       Mesh *me= t->obedit->data;
-       EditMesh *em = me->edit_mesh;
        SlideData *sld = t->customData;
-       EditVert *ev, *nearest = sld->nearest;
-       EditVert *centerVert, *upVert, *downVert;
-       LinkNode *vertlist=sld->vertlist, *look;
-       GHash *vertgh = sld->vhash;
-       TransDataSlideVert *tempsv;
-       float len;
-       int prop=1, flip=0;
-       /* UV correction vars */
-       GHash **uvarray= sld->uvhash;
-       int  uvlay_tot= CustomData_number_of_layers(&em->fdata, CD_MTFACE);
-       int uvlay_idx;
-       TransDataSlideUv *suv;
-       float uv_tmp[2];
-       LinkNode *fuv_link;
-
-       tempsv = BLI_ghash_lookup(vertgh,nearest);
-
-       centerVert = editedge_getSharedVert(tempsv->up, tempsv->down);
-       upVert = editedge_getOtherVert(tempsv->up, centerVert);
-       downVert = editedge_getOtherVert(tempsv->down, centerVert);
-
-       len = MIN2(perc, len_v3v3(upVert->co,downVert->co));
-       len = MAX2(len, 0);
-
-       //Adjust Edgeloop
-       if(prop) {
-               look = vertlist;
-               while(look) {
-                       EditVert *tempev;
-                       ev = look->link;
-                       tempsv = BLI_ghash_lookup(vertgh,ev);
-
-                       tempev = editedge_getOtherVert((perc>=0)?tempsv->up:tempsv->down, ev);
-                       interp_v3_v3v3(ev->co, tempsv->origvert.co, tempev->co, fabs(perc));
-
-                       if (uvlay_tot) { // XXX scene->toolsettings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) {
-                               for (uvlay_idx=0; uvlay_idx<uvlay_tot; uvlay_idx++) {
-                                       suv = BLI_ghash_lookup( uvarray[uvlay_idx], ev );
-                                       if (suv && suv->fuv_list && suv->uv_up && suv->uv_down) {
-                                               interp_v2_v2v2(uv_tmp, suv->origuv,  (perc>=0)?suv->uv_up:suv->uv_down, fabs(perc));
-                                               fuv_link = suv->fuv_list;
-                                               while (fuv_link) {
-                                                       VECCOPY2D(((float *)fuv_link->link), uv_tmp);
-                                                       fuv_link = fuv_link->next;
-                                               }
-                                       }
-                               }
-                       }
+       TransDataSlideVert *svlist = sld->sv, *sv;
+       float vec[3];
+       int i;
 
-                       look = look->next;
-               }
-       }
-       else {
-               //Non prop code
-               look = vertlist;
-               while(look) {
-                       float newlen, edgelen;
-                       ev = look->link;
-                       tempsv = BLI_ghash_lookup(vertgh,ev);
-                       edgelen = len_v3v3(editedge_getOtherVert(tempsv->up,ev)->co,editedge_getOtherVert(tempsv->down,ev)->co);
-                       newlen = (edgelen != 0.0f)? (len / edgelen): 0.0f;
-                       if(newlen > 1.0f) {newlen = 1.0;}
-                       if(newlen < 0.0f) {newlen = 0.0;}
-                       if(flip == 0) {
-                               interp_v3_v3v3(ev->co, editedge_getOtherVert(tempsv->down,ev)->co, editedge_getOtherVert(tempsv->up,ev)->co, fabs(newlen));
-                               if (uvlay_tot) { // XXX scene->toolsettings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) {
-                                       /* dont do anything if no UVs */
-                                       for (uvlay_idx=0; uvlay_idx<uvlay_tot; uvlay_idx++) {
-                                               suv = BLI_ghash_lookup( uvarray[uvlay_idx], ev );
-                                               if (suv && suv->fuv_list && suv->uv_up && suv->uv_down) {
-                                                       interp_v2_v2v2(uv_tmp, suv->uv_down, suv->uv_up, fabs(newlen));
-                                                       fuv_link = suv->fuv_list;
-                                                       while (fuv_link) {
-                                                               VECCOPY2D(((float *)fuv_link->link), uv_tmp);
-                                                               fuv_link = fuv_link->next;
-                                                       }
-                                               }
-                                       }
-                               }
-                       } else{
-                               interp_v3_v3v3(ev->co, editedge_getOtherVert(tempsv->up,ev)->co, editedge_getOtherVert(tempsv->down,ev)->co, fabs(newlen));
-
-                               if (uvlay_tot) { // XXX scene->toolsettings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) {
-                                       /* dont do anything if no UVs */
-                                       for (uvlay_idx=0; uvlay_idx<uvlay_tot; uvlay_idx++) {
-                                               suv = BLI_ghash_lookup( uvarray[uvlay_idx], ev );
-                                               if (suv && suv->fuv_list && suv->uv_up && suv->uv_down) {
-                                                       interp_v2_v2v2(uv_tmp, suv->uv_up, suv->uv_down, fabs(newlen));
-                                                       fuv_link = suv->fuv_list;
-                                                       while (fuv_link) {
-                                                               VECCOPY2D(((float *)fuv_link->link), uv_tmp);
-                                                               fuv_link = fuv_link->next;
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-                       look = look->next;
-               }
+       sld->perc = perc;
 
+       sv = svlist;
+       for (i=0; i<sld->totsv; i++, sv++) {
+               if (perc > 0.0f) {
+                       VECCOPY(vec, sv->upvec);
+                       mul_v3_fl(vec, perc);
+                       add_v3_v3v3(sv->v->co, sv->origvert.co, vec);
+               } else {
+                       VECCOPY(vec, sv->downvec);
+                       mul_v3_fl(vec, -perc);
+                       add_v3_v3v3(sv->v->co, sv->origvert.co, vec);
+               }
        }
-
+       
+       projectSVData(t, 0);
+       
        return 1;
 }
 
@@ -5309,8 +5129,6 @@ void initSeqSlide(TransInfo *t)
        t->num.flag = 0;
        t->num.idx_max = t->idx_max;
 
-       t->ndof.axis = 1|2;
-
        t->snap[0] = 0.0f;
        t->snap[1] = floor(t->scene->r.frs_sec / t->scene->r.frs_sec_base);
        t->snap[2] = 10.0f;
@@ -5365,7 +5183,6 @@ int SeqSlide(TransInfo *t, const int UNUSED(mval[2]))
                VECCOPY(t->values, tvec);
        }
        else {
-               applyNDofInput(&t->ndof, t->values);
                snapGrid(t, t->values);
                applyNumInput(&t->num, t->values);
        }
@@ -5530,7 +5347,7 @@ static void doAnimEdit_SnapFrame(TransInfo *t, TransData *td, TransData2D *td2d,
 void initTimeTranslate(TransInfo *t)
 {
        /* this tool is only really available in the Action Editor... */
-       if (t->spacetype != SPACE_ACTION) {
+       if (!ELEM(t->spacetype, SPACE_ACTION, SPACE_SEQ)) {
                t->state = TRANS_CANCEL;
        }
 
@@ -5925,54 +5742,3 @@ void BIF_TransformSetUndo(char *UNUSED(str))
        // TRANSFORM_FIX_ME
        //Trans.undostr= str;
 }
-
-
-#if 0 // TRANSFORM_FIX_ME
-static void NDofTransform(void)
-{
-       float fval[7];
-       float maxval = 50.0f; // also serves as threshold
-       int axis = -1;
-       int mode = 0;
-       int i;
-
-       getndof(fval);
-
-       for(i = 0; i < 6; i++)
-       {
-               float val = fabs(fval[i]);
-               if (val > maxval)
-               {
-                       axis = i;
-                       maxval = val;
-               }
-       }
-
-       switch(axis)
-       {
-               case -1:
-                       /* No proper axis found */
-                       break;
-               case 0:
-               case 1:
-               case 2:
-                       mode = TFM_TRANSLATION;
-                       break;
-               case 4:
-                       mode = TFM_ROTATION;
-                       break;
-               case 3:
-               case 5:
-                       mode = TFM_TRACKBALL;
-                       break;
-               default:
-                       printf("ndof: what we are doing here ?");
-       }
-
-       if (mode != 0)
-       {
-               initTransform(mode, CTX_NDOF);
-               Transform();
-       }
-}
-#endif