ok, apparently didn't commit this either. apparently includes a merge with trunk...
[blender-staging.git] / source / blender / editors / transform / transform.c
index 016400e0fa95295ce55d30067812e8ccdb61897d..66ced74e1a8108f10f78ccdc1c79474c173ccabe 100644 (file)
 #include "BKE_pointcache.h"
 #include "BKE_utildefines.h"
 #include "BKE_context.h"
+#include "BKE_unit.h"
 
 //#include "BSE_view.h"
 
 #include "ED_image.h"
+#include "ED_keyframing.h"
 #include "ED_screen.h"
 #include "ED_space_api.h"
 #include "ED_markers.h"
 #include "ED_util.h"
 #include "ED_view3d.h"
+#include "ED_mesh.h"
 
 #include "UI_view2d.h"
 #include "WM_types.h"
 #include "WM_api.h"
 
-#include "BLI_arithb.h"
+#include "BLI_math.h"
 #include "BLI_blenlib.h"
 #include "BLI_editVert.h"
+#include "BLI_ghash.h"
+#include "BLI_linklist.h"
 
 #include "PIL_time.h"                  /* sleep                                */
 
@@ -123,21 +128,21 @@ void setTransformViewMatrices(TransInfo *t)
 {
        if(t->spacetype==SPACE_VIEW3D && t->ar->regiontype == RGN_TYPE_WINDOW) {
                RegionView3D *rv3d = t->ar->regiondata;
-               
-               Mat4CpyMat4(t->viewmat, rv3d->viewmat);
-               Mat4CpyMat4(t->viewinv, rv3d->viewinv);
-               Mat4CpyMat4(t->persmat, rv3d->persmat);
-               Mat4CpyMat4(t->persinv, rv3d->persinv);
+
+               copy_m4_m4(t->viewmat, rv3d->viewmat);
+               copy_m4_m4(t->viewinv, rv3d->viewinv);
+               copy_m4_m4(t->persmat, rv3d->persmat);
+               copy_m4_m4(t->persinv, rv3d->persinv);
                t->persp = rv3d->persp;
        }
        else {
-               Mat4One(t->viewmat);
-               Mat4One(t->viewinv);
-               Mat4One(t->persmat);
-               Mat4One(t->persinv);
-               t->persp = V3D_ORTHO;
+               unit_m4(t->viewmat);
+               unit_m4(t->viewinv);
+               unit_m4(t->persmat);
+               unit_m4(t->persinv);
+               t->persp = RV3D_ORTHO;
        }
-       
+
        calculateCenter2D(t);
 }
 
@@ -152,12 +157,12 @@ void convertViewVec(TransInfo *t, float *vec, short dx, short dy)
        else if(t->spacetype==SPACE_IMAGE) {
                View2D *v2d = t->view;
                float divx, divy, aspx, aspy;
-               
+
                ED_space_image_uv_aspect(t->sa->spacedata.first, &aspx, &aspy);
-               
+
                divx= v2d->mask.xmax-v2d->mask.xmin;
                divy= v2d->mask.ymax-v2d->mask.ymin;
-               
+
                vec[0]= aspx*(v2d->cur.xmax-v2d->cur.xmin)*(dx)/divx;
                vec[1]= aspy*(v2d->cur.ymax-v2d->cur.ymin)*(dy)/divy;
                vec[2]= 0.0f;
@@ -165,10 +170,10 @@ void convertViewVec(TransInfo *t, float *vec, short dx, short dy)
        else if(ELEM(t->spacetype, SPACE_IPO, SPACE_NLA)) {
                View2D *v2d = t->view;
                float divx, divy;
-               
+
                divx= v2d->mask.xmax-v2d->mask.xmin;
                divy= v2d->mask.ymax-v2d->mask.ymin;
-               
+
                vec[0]= (v2d->cur.xmax-v2d->cur.xmin)*(dx) / (divx);
                vec[1]= (v2d->cur.ymax-v2d->cur.ymin)*(dy) / (divy);
                vec[2]= 0.0f;
@@ -176,10 +181,10 @@ void convertViewVec(TransInfo *t, float *vec, short dx, short dy)
        else if(t->spacetype==SPACE_NODE) {
                View2D *v2d = &t->ar->v2d;
                float divx, divy;
-               
+
                divx= v2d->mask.xmax-v2d->mask.xmin;
                divy= v2d->mask.ymax-v2d->mask.ymin;
-               
+
                vec[0]= (v2d->cur.xmax-v2d->cur.xmin)*(dx)/divx;
                vec[1]= (v2d->cur.ymax-v2d->cur.ymin)*(dy)/divy;
                vec[2]= 0.0f;
@@ -205,23 +210,23 @@ void projectIntView(TransInfo *t, float *vec, int *adr)
        }
        else if(t->spacetype==SPACE_IMAGE) {
                float aspx, aspy, v[2];
-               
+
                ED_space_image_uv_aspect(t->sa->spacedata.first, &aspx, &aspy);
                v[0]= vec[0]/aspx;
                v[1]= vec[1]/aspy;
-               
+
                UI_view2d_to_region_no_clip(t->view, v[0], v[1], adr, adr+1);
        }
        else if(ELEM(t->spacetype, SPACE_IPO, SPACE_NLA)) {
                int out[2] = {0, 0};
-               
-               UI_view2d_view_to_region((View2D *)t->view, vec[0], vec[1], out, out+1); 
+
+               UI_view2d_view_to_region((View2D *)t->view, vec[0], vec[1], out, out+1);
                adr[0]= out[0];
                adr[1]= out[1];
        }
        else if(t->spacetype==SPACE_SEQ) { /* XXX not tested yet, but should work */
                int out[2] = {0, 0};
-               
+
                UI_view2d_view_to_region((View2D *)t->view, vec[0], vec[1], out, out+1);
                adr[0]= out[0];
                adr[1]= out[1];
@@ -236,14 +241,14 @@ void projectFloatView(TransInfo *t, float *vec, float *adr)
        }
        else if(t->spacetype==SPACE_IMAGE) {
                int a[2];
-               
+
                projectIntView(t, vec, a);
                adr[0]= a[0];
                adr[1]= a[1];
        }
        else if(ELEM(t->spacetype, SPACE_IPO, SPACE_NLA)) {
                int a[2];
-               
+
                projectIntView(t, vec, a);
                adr[0]= a[0];
                adr[1]= a[1];
@@ -296,8 +301,12 @@ static void viewRedrawForce(bContext *C, TransInfo *t)
 {
        if (t->spacetype == SPACE_VIEW3D)
        {
-               /* Do we need more refined tags? */             
+               /* Do we need more refined tags? */
                WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
+               
+               /* for realtime animation record - send notifiers recognised by animation editors */
+               if ((t->animtimer) && IS_AUTOKEY_ON(t->scene))
+                       WM_event_add_notifier(C, NC_OBJECT|ND_KEYS, NULL);
        }
        else if (t->spacetype == SPACE_ACTION) {
                //SpaceAction *saction= (SpaceAction *)t->sa->spacedata.first;
@@ -308,12 +317,12 @@ static void viewRedrawForce(bContext *C, TransInfo *t)
                WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL);
        }
        else if (t->spacetype == SPACE_NLA) {
-               WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL);
+               WM_event_add_notifier(C, NC_ANIMATION|ND_NLA_EDIT, NULL);
        }
        else if(t->spacetype == SPACE_NODE)
        {
                //ED_area_tag_redraw(t->sa);
-               WM_event_add_notifier(C, NC_SCENE|ND_NODES, NULL);
+               WM_event_add_notifier(C, NC_SPACE|ND_SPACE_NODE_VIEW, NULL);
        }
        else if(t->spacetype == SPACE_SEQ)
        {
@@ -321,20 +330,16 @@ static void viewRedrawForce(bContext *C, TransInfo *t)
        }
        else if (t->spacetype==SPACE_IMAGE) {
                // XXX how to deal with lock?
-#if 0
                SpaceImage *sima= (SpaceImage*)t->sa->spacedata.first;
-               if(sima->lock) force_draw_plus(SPACE_VIEW3D, 0);
-               else force_draw(0);
-#endif
-
-               WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, t->obedit);
+               if(sima->lock) WM_event_add_notifier(C, NC_GEOM|ND_DATA, t->obedit->data);
+               else ED_area_tag_redraw(t->sa);
        }
 }
 
 static void viewRedrawPost(TransInfo *t)
 {
        ED_area_headerprint(t->sa, NULL);
-       
+
 #if 0 // TRANSFORM_FIX_ME
        if(t->spacetype==SPACE_VIEW3D) {
                allqueue(REDRAWBUTSOBJECT, 0);
@@ -365,7 +370,7 @@ void BIF_selectOrientation() {
        char *str_menu = BIF_menustringTransformOrientation("Orientation");
        val= pupmenu(str_menu);
        MEM_freeN(str_menu);
-       
+
        if(val >= 0) {
                G.vd->twmode = val;
        }
@@ -381,18 +386,18 @@ static void view_editmove(unsigned short event)
        /* Ctrl:      Scroll right */
        /* Alt-Shift: Rotate up */
        /* Alt-Ctrl:  Rotate right */
-       
+
        /* only work in 3D window for now
         * In the end, will have to send to event to a 2D window handler instead
         */
        if (Trans.flag & T_2D_EDIT)
                return;
-       
+
        switch(event) {
                case WHEELUPMOUSE:
-                       
+
                        if( G.qual & LR_SHIFTKEY ) {
-                               if( G.qual & LR_ALTKEY ) { 
+                               if( G.qual & LR_ALTKEY ) {
                                        G.qual &= ~LR_SHIFTKEY;
                                        persptoetsen(PAD2);
                                        G.qual |= LR_SHIFTKEY;
@@ -400,23 +405,23 @@ static void view_editmove(unsigned short event)
                                        persptoetsen(PAD2);
                                }
                        } else if( G.qual & LR_CTRLKEY ) {
-                               if( G.qual & LR_ALTKEY ) { 
+                               if( G.qual & LR_ALTKEY ) {
                                        G.qual &= ~LR_CTRLKEY;
                                        persptoetsen(PAD4);
                                        G.qual |= LR_CTRLKEY;
                                } else {
                                        persptoetsen(PAD4);
                                }
-                       } else if(U.uiflag & USER_WHEELZOOMDIR) 
+                       } else if(U.uiflag & USER_WHEELZOOMDIR)
                                persptoetsen(PADMINUS);
                        else
                                persptoetsen(PADPLUSKEY);
-                       
+
                        refresh = 1;
                        break;
                case WHEELDOWNMOUSE:
                        if( G.qual & LR_SHIFTKEY ) {
-                               if( G.qual & LR_ALTKEY ) { 
+                               if( G.qual & LR_ALTKEY ) {
                                        G.qual &= ~LR_SHIFTKEY;
                                        persptoetsen(PAD8);
                                        G.qual |= LR_SHIFTKEY;
@@ -424,18 +429,18 @@ static void view_editmove(unsigned short event)
                                        persptoetsen(PAD8);
                                }
                        } else if( G.qual & LR_CTRLKEY ) {
-                               if( G.qual & LR_ALTKEY ) { 
+                               if( G.qual & LR_ALTKEY ) {
                                        G.qual &= ~LR_CTRLKEY;
                                        persptoetsen(PAD6);
                                        G.qual |= LR_CTRLKEY;
                                } else {
                                        persptoetsen(PAD6);
                                }
-                       } else if(U.uiflag & USER_WHEELZOOMDIR) 
+                       } else if(U.uiflag & USER_WHEELZOOMDIR)
                                persptoetsen(PADPLUSKEY);
                        else
                                persptoetsen(PADMINUS);
-                       
+
                        refresh = 1;
                        break;
        }
@@ -496,32 +501,155 @@ static char *transform_to_undostr(TransInfo *t)
 
 /* ************************************************* */
 
+/* NOTE: these defines are saved in keymap files, do not change values but just add new ones */
+#define TFM_MODAL_CANCEL                       1
+#define TFM_MODAL_CONFIRM                      2
+#define TFM_MODAL_TRANSLATE                    3
+#define TFM_MODAL_ROTATE                       4
+#define TFM_MODAL_RESIZE                       5
+#define TFM_MODAL_SNAP_GEARS           6
+#define TFM_MODAL_SNAP_GEARS_OFF       7
+#define TFM_MODAL_SNAP_GEARS_TOGGLE    8
+
+/* called in transform_ops.c, on each regeneration of keymaps */
+void transform_modal_keymap(wmKeyConfig *keyconf)
+{
+       static EnumPropertyItem modal_items[] = {
+       {TFM_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""},
+       {TFM_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
+       {TFM_MODAL_TRANSLATE, "TRANSLATE", 0, "Translate", ""},
+       {TFM_MODAL_ROTATE, "ROTATE", 0, "Rotate", ""},
+       {TFM_MODAL_RESIZE, "RESIZE", 0, "Resize", ""},
+       {TFM_MODAL_SNAP_GEARS, "SNAP_GEARS", 0, "Snap On", ""},
+       {TFM_MODAL_SNAP_GEARS_OFF, "SNAP_GEARS_OFF", 0, "Snap Off", ""},
+       {TFM_MODAL_SNAP_GEARS_TOGGLE, "SNAP_GEARS_TOGGLE", 0, "Snap Toggle", ""},
+       {0, NULL, 0, NULL, NULL}};
+       
+       wmKeyMap *keymap= WM_modalkeymap_get(keyconf, "Transform Modal Map");
+       
+       /* this function is called for each spacetype, only needs to add map once */
+       if(keymap) return;
+       
+       keymap= WM_modalkeymap_add(keyconf, "Transform Modal Map", modal_items);
+       
+       /* items for modal map */
+       WM_modalkeymap_add_item(keymap, ESCKEY,    KM_PRESS, KM_ANY, 0, TFM_MODAL_CANCEL);
+       WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, KM_ANY, 0, TFM_MODAL_CONFIRM);
+       WM_modalkeymap_add_item(keymap, RETKEY, KM_PRESS, KM_ANY, 0, TFM_MODAL_CONFIRM);
+       WM_modalkeymap_add_item(keymap, PADENTER, KM_PRESS, KM_ANY, 0, TFM_MODAL_CONFIRM);
+
+       WM_modalkeymap_add_item(keymap, GKEY, KM_PRESS, 0, 0, TFM_MODAL_TRANSLATE);
+       WM_modalkeymap_add_item(keymap, RKEY, KM_PRESS, 0, 0, TFM_MODAL_ROTATE);
+       WM_modalkeymap_add_item(keymap, SKEY, KM_PRESS, 0, 0, TFM_MODAL_RESIZE);
+       
+       WM_modalkeymap_add_item(keymap, LEFTCTRLKEY, KM_PRESS, KM_ANY, 0, TFM_MODAL_SNAP_GEARS_TOGGLE);
+       
+       /* assign map to operators */
+       WM_modalkeymap_assign(keymap, "TFM_OT_transform");
+       WM_modalkeymap_assign(keymap, "TFM_OT_translate");
+       WM_modalkeymap_assign(keymap, "TFM_OT_rotate");
+       WM_modalkeymap_assign(keymap, "TFM_OT_tosphere");
+       WM_modalkeymap_assign(keymap, "TFM_OT_resize");
+       WM_modalkeymap_assign(keymap, "TFM_OT_shear");
+       WM_modalkeymap_assign(keymap, "TFM_OT_warp");
+       WM_modalkeymap_assign(keymap, "TFM_OT_shrink_fatten");
+       WM_modalkeymap_assign(keymap, "TFM_OT_tilt");
+       WM_modalkeymap_assign(keymap, "TFM_OT_trackball");
+       WM_modalkeymap_assign(keymap, "TFM_OT_mirror");
+       WM_modalkeymap_assign(keymap, "TFM_OT_edge_slide");
+}
+
+
 void transformEvent(TransInfo *t, wmEvent *event)
 {
        float mati[3][3] = {{1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}};
        char cmode = constraintModeToChar(t);
-       
+
        t->redraw |= handleMouseInput(t, &t->mouse, event);
 
        if (event->type == MOUSEMOVE)
        {
                t->mval[0] = event->x - t->ar->winrct.xmin;
                t->mval[1] = event->y - t->ar->winrct.ymin;
-               
+
                t->redraw = 1;
-               
+
+               if (t->state == TRANS_STARTING) {
+                   t->state = TRANS_RUNNING;
+               }
+
                applyMouseInput(t, &t->mouse, t->mval, t->values);
        }
-       
-       if (event->val) {
+
+       /* handle modal keymap first */
+       if (event->type == EVT_MODAL_MAP) {
+               switch (event->val) {
+                       case TFM_MODAL_CANCEL:
+                               t->state = TRANS_CANCEL;
+                               break;
+                       case TFM_MODAL_CONFIRM:
+                               t->state = TRANS_CONFIRM;
+                               break;
+                       case TFM_MODAL_TRANSLATE:
+                               /* only switch when... */
+                               if( ELEM3(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL) ) {
+                                       resetTransRestrictions(t);
+                                       restoreTransObjects(t);
+                                       initTranslation(t);
+                                       initSnapping(t, NULL); // need to reinit after mode change
+                                       t->redraw = 1;
+                               }
+                               break;
+                       case TFM_MODAL_ROTATE:
+                               /* only switch when... */
+                               if( ELEM4(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_TRANSLATION) ) {
+                                       
+                                       resetTransRestrictions(t);
+                                       
+                                       if (t->mode == TFM_ROTATION) {
+                                               restoreTransObjects(t);
+                                               initTrackball(t);
+                                       }
+                                       else {
+                                               restoreTransObjects(t);
+                                               initRotation(t);
+                                       }
+                                       initSnapping(t, NULL); // need to reinit after mode change
+                                       t->redraw = 1;
+                               }
+                               break;
+                       case TFM_MODAL_RESIZE:
+                               /* only switch when... */
+                               if( ELEM3(t->mode, TFM_ROTATION, TFM_TRANSLATION, TFM_TRACKBALL) ) {
+                                       resetTransRestrictions(t);
+                                       restoreTransObjects(t);
+                                       initResize(t);
+                                       initSnapping(t, NULL); // need to reinit after mode change
+                                       t->redraw = 1;
+                               }
+                               break;
+                               
+                       case TFM_MODAL_SNAP_GEARS:
+                               t->modifiers |= MOD_SNAP_GEARS;
+                               t->redraw = 1;
+                               break;
+                       case TFM_MODAL_SNAP_GEARS_OFF:
+                               t->modifiers &= ~MOD_SNAP_GEARS;
+                               t->redraw = 1;
+                               break;
+                       case TFM_MODAL_SNAP_GEARS_TOGGLE:
+                               t->modifiers ^= MOD_SNAP_GEARS;
+                               t->redraw = 1;
+                               break;
+               }
+       }
+       /* else do non-mapped events */
+       else if (event->val==KM_PRESS) {
                switch (event->type){
-               /* enforce redraw of transform when modifiers are used */
-               case LEFTCTRLKEY:
-               case RIGHTCTRLKEY:
-                       t->modifiers |= MOD_SNAP_GEARS;
-                       t->redraw = 1;
+               case RIGHTMOUSE:
+                       t->state = TRANS_CANCEL;
                        break;
-                       
+               /* enforce redraw of transform when modifiers are used */
                case LEFTSHIFTKEY:
                case RIGHTSHIFTKEY:
                        t->modifiers |= MOD_CONSTRAINT_PLANE;
@@ -532,11 +660,11 @@ void transformEvent(TransInfo *t, wmEvent *event)
                        if ((t->spacetype==SPACE_VIEW3D) && event->alt) {
 #if 0 // TRANSFORM_FIX_ME
                                short mval[2];
-                               
+
                                getmouseco_sc(mval);
                                BIF_selectOrientation();
                                calc_manipulator_stats(curarea);
-                               Mat3CpyMat4(t->spacemtx, G.vd->twmat);
+                               copy_m3_m4(t->spacemtx, G.vd->twmat);
                                warp_pointer(mval[0], mval[1]);
 #endif
                        }
@@ -544,7 +672,7 @@ void transformEvent(TransInfo *t, wmEvent *event)
                                t->state = TRANS_CONFIRM;
                        }
                        break;
-                       
+
                case MIDDLEMOUSE:
                        if ((t->flag & T_NO_CONSTRAINT)==0) {
                                /* exception for switching to dolly, or trackball, in camera view */
@@ -577,19 +705,16 @@ void transformEvent(TransInfo *t, wmEvent *event)
                        }
                        break;
                case ESCKEY:
-               case RIGHTMOUSE:
-                       printf("cancelled\n");
                        t->state = TRANS_CANCEL;
                        break;
-               case LEFTMOUSE:
                case PADENTER:
                case RETKEY:
                        t->state = TRANS_CONFIRM;
                        break;
                case GKEY:
                        /* only switch when... */
-                       if( ELEM3(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL) ) { 
-                               resetTransRestrictions(t); 
+                       if( ELEM3(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL) ) {
+                               resetTransRestrictions(t);
                                restoreTransObjects(t);
                                initTranslation(t);
                                initSnapping(t, NULL); // need to reinit after mode change
@@ -598,8 +723,8 @@ void transformEvent(TransInfo *t, wmEvent *event)
                        break;
                case SKEY:
                        /* only switch when... */
-                       if( ELEM3(t->mode, TFM_ROTATION, TFM_TRANSLATION, TFM_TRACKBALL) ) { 
-                               resetTransRestrictions(t); 
+                       if( ELEM3(t->mode, TFM_ROTATION, TFM_TRANSLATION, TFM_TRACKBALL) ) {
+                               resetTransRestrictions(t);
                                restoreTransObjects(t);
                                initResize(t);
                                initSnapping(t, NULL); // need to reinit after mode change
@@ -609,9 +734,9 @@ void transformEvent(TransInfo *t, wmEvent *event)
                case RKEY:
                        /* only switch when... */
                        if( ELEM4(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_TRANSLATION) ) {
-                               
-                               resetTransRestrictions(t); 
-                               
+
+                               resetTransRestrictions(t);
+
                                if (t->mode == TFM_ROTATION) {
                                        restoreTransObjects(t);
                                        initTrackball(t);
@@ -647,10 +772,11 @@ void transformEvent(TransInfo *t, wmEvent *event)
                                                        stopConstraint(t);
                                                }
                                                else {
+                                                       short orientation = t->current_orientation != V3D_MANIP_GLOBAL ? t->current_orientation : V3D_MANIP_LOCAL;
                                                        if ((t->modifiers & MOD_CONSTRAINT_PLANE) == 0)
-                                                               setUserConstraint(t, (CON_AXIS0), "along %s X");
+                                                               setUserConstraint(t, orientation, (CON_AXIS0), "along %s X");
                                                        else if (t->modifiers & MOD_CONSTRAINT_PLANE)
-                                                               setUserConstraint(t, (CON_AXIS1|CON_AXIS2), "locking %s X");
+                                                               setUserConstraint(t, orientation, (CON_AXIS1|CON_AXIS2), "locking %s X");
                                                }
                                        }
                                }
@@ -679,10 +805,11 @@ void transformEvent(TransInfo *t, wmEvent *event)
                                                        stopConstraint(t);
                                                }
                                                else {
+                                                       short orientation = t->current_orientation != V3D_MANIP_GLOBAL ? t->current_orientation : V3D_MANIP_LOCAL;
                                                        if ((t->modifiers & MOD_CONSTRAINT_PLANE) == 0)
-                                                               setUserConstraint(t, (CON_AXIS1), "along %s Y");
+                                                               setUserConstraint(t, orientation, (CON_AXIS1), "along %s Y");
                                                        else if (t->modifiers & MOD_CONSTRAINT_PLANE)
-                                                               setUserConstraint(t, (CON_AXIS0|CON_AXIS2), "locking %s Y");
+                                                               setUserConstraint(t, orientation, (CON_AXIS0|CON_AXIS2), "locking %s Y");
                                                }
                                        }
                                }
@@ -707,10 +834,11 @@ void transformEvent(TransInfo *t, wmEvent *event)
                                                stopConstraint(t);
                                        }
                                        else {
+                                               short orientation = t->current_orientation != V3D_MANIP_GLOBAL ? t->current_orientation : V3D_MANIP_LOCAL;
                                                if ((t->modifiers & MOD_CONSTRAINT_PLANE) == 0)
-                                                       setUserConstraint(t, (CON_AXIS2), "along %s Z");
+                                                       setUserConstraint(t, orientation, (CON_AXIS2), "along %s Z");
                                                else if ((t->modifiers & MOD_CONSTRAINT_PLANE) && ((t->flag & T_2D_EDIT)==0))
-                                                       setUserConstraint(t, (CON_AXIS0|CON_AXIS1), "locking %s Z");
+                                                       setUserConstraint(t, orientation, (CON_AXIS0|CON_AXIS1), "locking %s Z");
                                        }
                                }
                                else if ((t->flag & T_2D_EDIT)==0) {
@@ -771,10 +899,10 @@ void transformEvent(TransInfo *t, wmEvent *event)
 //            viewmoveNDOF(1);
   //         break;
                }
-               
+
                // Numerical input events
                t->redraw |= handleNumInput(&(t->num), event);
-               
+
                // NDof input events
                switch(handleNDofInput(&(t->ndof), event))
                {
@@ -789,7 +917,7 @@ void transformEvent(TransInfo *t, wmEvent *event)
                                if (t->options & CTX_NDOF)
                                {
                                        /* Cancel on pure NDOF transform */
-                                       t->state = TRANS_CANCEL; 
+                                       t->state = TRANS_CANCEL;
                                }
                                else
                                {
@@ -807,15 +935,15 @@ void transformEvent(TransInfo *t, wmEvent *event)
                        case NDOF_REFRESH:
                                t->redraw = 1;
                                break;
-                       
+
                }
-               
+
                // Snapping events
                t->redraw |= handleSnapping(t, event);
-               
+
                //arrows_move_cursor(event->type);
        }
-       else {
+       else if (event->val==KM_RELEASE) {
                switch (event->type){
                case LEFTSHIFTKEY:
                case RIGHTSHIFTKEY:
@@ -823,13 +951,6 @@ void transformEvent(TransInfo *t, wmEvent *event)
                        t->redraw = 1;
                        break;
 
-               case LEFTCTRLKEY:
-               case RIGHTCTRLKEY:
-                       t->modifiers &= ~MOD_SNAP_GEARS;
-                       /* no redraw on release modifier keys! this makes sure you can assign the 'grid' still 
-                          after releasing modifer key */
-                       //t->redraw = 1;
-                       break;
                case MIDDLEMOUSE:
                        if ((t->flag & T_NO_CONSTRAINT)==0) {
                                t->modifiers &= ~MOD_CONSTRAINT_SELECT;
@@ -837,15 +958,22 @@ void transformEvent(TransInfo *t, wmEvent *event)
                                t->redraw = 1;
                        }
                        break;
-               case LEFTMOUSE:
-               case RIGHTMOUSE:
-                       if(WM_modal_tweak_exit(event, t->event_type))
-//                     if (t->options & CTX_TWEAK)
-                               t->state = TRANS_CONFIRM;
-                       break;
+//             case LEFTMOUSE:
+//             case RIGHTMOUSE:
+//                     if(WM_modal_tweak_exit(event, t->event_type))
+////                   if (t->options & CTX_TWEAK)
+//                             t->state = TRANS_CONFIRM;
+//                     break;
+               }
+
+               /* confirm transform if launch key is released after mouse move */
+               /* XXX Keyrepeat bug in Xorg fucks this up, will test when fixed */
+               if (event->type == LEFTMOUSE /*t->launch_event*/ && t->state != TRANS_STARTING)
+               {
+                       t->state = TRANS_CONFIRM;
                }
        }
-       
+
        // Per transform event, if present
        if (t->handleEvent)
                t->redraw |= t->handleEvent(t, event);
@@ -859,7 +987,7 @@ int calculateTransformCenter(bContext *C, wmEvent *event, int centerMode, float
        t->state = TRANS_RUNNING;
 
        t->options = CTX_NONE;
-       
+
        t->mode = TFM_DUMMY;
 
        initTransInfo(C, t, NULL, event);                                       // internal data, mouse, vectors
@@ -873,20 +1001,21 @@ int calculateTransformCenter(bContext *C, wmEvent *event, int centerMode, float
        }
        else {
                success = 1;
-               
+
                calculateCenter(t);
-       
-               // Copy center from constraint center. Transform center can be local    
+
+               // Copy center from constraint center. Transform center can be local
                VECCOPY(vec, t->con.center);
        }
 
-       postTrans(t);
 
        /* aftertrans does insert ipos and action channels, and clears base flags, doesnt read transdata */
        special_aftertrans_update(t);
-       
+
+       postTrans(t);
+
        MEM_freeN(t);
-       
+
        return success;
 }
 
@@ -905,28 +1034,28 @@ static void drawArrow(ArrowDirection d, short offset, short length, short size)
                        length = -length;
                        size = -size;
                case RIGHT:
-                       glBegin(GL_LINES); 
-                       glVertex2s( offset, 0); 
-                       glVertex2s( offset + length, 0); 
-                       glVertex2s( offset + length, 0); 
-                       glVertex2s( offset + length - size, -size); 
-                       glVertex2s( offset + length, 0); 
+                       glBegin(GL_LINES);
+                       glVertex2s( offset, 0);
+                       glVertex2s( offset + length, 0);
+                       glVertex2s( offset + length, 0);
+                       glVertex2s( offset + length - size, -size);
+                       glVertex2s( offset + length, 0);
                        glVertex2s( offset + length - size,  size);
-                       glEnd(); 
+                       glEnd();
                        break;
                case DOWN:
                        offset = -offset;
                        length = -length;
                        size = -size;
                case UP:
-                       glBegin(GL_LINES); 
-                       glVertex2s( 0, offset); 
-                       glVertex2s( 0, offset + length); 
-                       glVertex2s( 0, offset + length); 
-                       glVertex2s(-size, offset + length - size); 
-                       glVertex2s( 0, offset + length); 
+                       glBegin(GL_LINES);
+                       glVertex2s( 0, offset);
+                       glVertex2s( 0, offset + length);
+                       glVertex2s( 0, offset + length);
+                       glVertex2s(-size, offset + length - size);
+                       glVertex2s( 0, offset + length);
                        glVertex2s( size, offset + length - size);
-                       glEnd(); 
+                       glEnd();
                        break;
        }
 }
@@ -938,22 +1067,22 @@ static void drawArrowHead(ArrowDirection d, short size)
                case LEFT:
                        size = -size;
                case RIGHT:
-                       glBegin(GL_LINES); 
-                       glVertex2s( 0, 0); 
-                       glVertex2s( -size, -size); 
-                       glVertex2s( 0, 0); 
+                       glBegin(GL_LINES);
+                       glVertex2s( 0, 0);
+                       glVertex2s( -size, -size);
+                       glVertex2s( 0, 0);
                        glVertex2s( -size,  size);
-                       glEnd(); 
+                       glEnd();
                        break;
                case DOWN:
                        size = -size;
                case UP:
-                       glBegin(GL_LINES); 
-                       glVertex2s( 0, 0); 
-                       glVertex2s(-size, -size); 
-                       glVertex2s( 0, 0); 
+                       glBegin(GL_LINES);
+                       glVertex2s( 0, 0);
+                       glVertex2s(-size, -size);
+                       glVertex2s( 0, 0);
                        glVertex2s( size, -size);
-                       glEnd(); 
+                       glEnd();
                        break;
        }
 }
@@ -962,15 +1091,15 @@ static void drawArc(float size, float angle_start, float angle_end, int segments
 {
        float delta = (angle_end - angle_start) / segments;
        float angle;
-       
+
        glBegin(GL_LINE_STRIP);
-       
+
        for( angle = angle_start; angle < angle_end; angle += delta)
        {
                glVertex2f( cosf(angle) * size, sinf(angle) * size);
        }
        glVertex2f( cosf(angle_end) * size, sinf(angle_end) * size);
-       
+
        glEnd();
 }
 
@@ -979,37 +1108,30 @@ void drawHelpline(const struct bContext *C, TransInfo *t)
        if (t->helpline != HLP_NONE && !(t->flag & T_USES_MANIPULATOR))
        {
                float vecrot[3], cent[2];
-               
+
                VECCOPY(vecrot, t->center);
                if(t->flag & T_EDIT) {
                        Object *ob= t->obedit;
-                       if(ob) Mat4MulVecfl(ob->obmat, vecrot);
+                       if(ob) mul_m4_v3(ob->obmat, vecrot);
                }
                else if(t->flag & T_POSE) {
                        Object *ob=t->poseobj;
-                       if(ob) Mat4MulVecfl(ob->obmat, vecrot);
+                       if(ob) mul_m4_v3(ob->obmat, vecrot);
                }
-               
+
                projectFloatView(t, vecrot, cent);      // no overflow in extreme cases
-       
-               glDisable(GL_DEPTH_TEST);
 
-               glMatrixMode(GL_PROJECTION);
-               glPushMatrix();
-               glMatrixMode(GL_MODELVIEW);
                glPushMatrix();
 
-               ED_region_pixelspace(t->ar);
-               
                switch(t->helpline)
                {
                        case HLP_SPRING:
                                UI_ThemeColor(TH_WIRE);
-                               
+
                                setlinestyle(3);
-                               glBegin(GL_LINE_STRIP); 
-                               glVertex2sv(t->mval); 
-                               glVertex2fv(cent); 
+                               glBegin(GL_LINE_STRIP);
+                               glVertex2sv(t->mval);
+                               glVertex2fv(cent);
                                glEnd();
 
                                glTranslatef(t->mval[0], t->mval[1], 0);
@@ -1037,7 +1159,7 @@ void drawHelpline(const struct bContext *C, TransInfo *t)
                                glTranslatef(t->mval[0], t->mval[1], 0);
 
                                glLineWidth(3.0);
-                               glBegin(GL_LINES); 
+                               glBegin(GL_LINES);
                                drawArrow(UP, 5, 10, 5);
                                drawArrow(DOWN, 5, 10, 5);
                                glLineWidth(1.0);
@@ -1050,27 +1172,27 @@ void drawHelpline(const struct bContext *C, TransInfo *t)
                                        float delta_angle = MIN2(15 / dist, M_PI/4);
                                        float spacing_angle = MIN2(5 / dist, M_PI/12);
                                        UI_ThemeColor(TH_WIRE);
-       
+
                                        setlinestyle(3);
-                                       glBegin(GL_LINE_STRIP); 
-                                       glVertex2sv(t->mval); 
-                                       glVertex2fv(cent); 
+                                       glBegin(GL_LINE_STRIP);
+                                       glVertex2sv(t->mval);
+                                       glVertex2fv(cent);
                                        glEnd();
-                                       
+
                                        glTranslatef(cent[0], cent[1], 0);
-       
+
                                        setlinestyle(0);
                                        glLineWidth(3.0);
                                        drawArc(dist, angle - delta_angle, angle - spacing_angle, 10);
                                        drawArc(dist, angle + spacing_angle, angle + delta_angle, 10);
-                                       
+
                                        glPushMatrix();
 
                                        glTranslatef(cosf(angle - delta_angle) * dist, sinf(angle - delta_angle) * dist, 0);
                                        glRotatef(180 / M_PI * (angle - delta_angle), 0, 0, 1);
-                                       
+
                                        drawArrowHead(DOWN, 5);
-                                       
+
                                        glPopMatrix();
 
                                        glTranslatef(cosf(angle + delta_angle) * dist, sinf(angle + delta_angle) * dist, 0);
@@ -1085,43 +1207,44 @@ void drawHelpline(const struct bContext *C, TransInfo *t)
                                {
                                        char col[3], col2[3];
                                        UI_GetThemeColor3ubv(TH_GRID, col);
-       
+
                                        glTranslatef(t->mval[0], t->mval[1], 0);
-       
+
                                        glLineWidth(3.0);
-       
+
                                        UI_make_axis_color(col, col2, 'x');
                                        glColor3ubv((GLubyte *)col2);
-       
+
                                        drawArrow(RIGHT, 5, 10, 5);
                                        drawArrow(LEFT, 5, 10, 5);
-       
+
                                        UI_make_axis_color(col, col2, 'y');
                                        glColor3ubv((GLubyte *)col2);
-       
+
                                        drawArrow(UP, 5, 10, 5);
                                        drawArrow(DOWN, 5, 10, 5);
                                        glLineWidth(1.0);
                                        break;
                                }
                }
-               
-               glMatrixMode(GL_PROJECTION);
-               glPopMatrix();
-               glMatrixMode(GL_MODELVIEW);
+
                glPopMatrix();
-               
-               glEnable(GL_DEPTH_TEST);
        }
 }
 
-void drawTransform(const struct bContext *C, struct ARegion *ar, void *arg)
+void drawTransformView(const struct bContext *C, struct ARegion *ar, void *arg)
 {
        TransInfo *t = arg;
-       
+
        drawConstraint(C, t);
        drawPropCircle(C, t);
        drawSnapping(C, t);
+}
+
+void drawTransformPixel(const struct bContext *C, struct ARegion *ar, void *arg)
+{
+       TransInfo *t = arg;
+
        drawHelpline(C, t);
 }
 
@@ -1131,13 +1254,16 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
        int constraint_axis[3] = {0, 0, 0};
        int proportional = 0;
 
-       if (t->flag & T_AUTOVALUES)
-       {
-               RNA_float_set_array(op->ptr, "value", t->auto_values);
-       }
-       else
+       if (RNA_struct_find_property(op->ptr, "value"))
        {
-               RNA_float_set_array(op->ptr, "value", t->values);
+               if (t->flag & T_AUTOVALUES)
+               {
+                       RNA_float_set_array(op->ptr, "value", t->auto_values);
+               }
+               else
+               {
+                       RNA_float_set_array(op->ptr, "value", t->values);
+               }
        }
 
        /* XXX convert stupid flag to enum */
@@ -1153,6 +1279,36 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
                proportional = 0;
        }
 
+       // If modal, save settings back in scene if not set as operator argument
+       if (t->flag & T_MODAL)
+       {
+               /* save settings if not set in operator */
+               if (RNA_struct_find_property(op->ptr, "proportional") && !RNA_property_is_set(op->ptr, "proportional"))
+               {
+                       ts->proportional = proportional;
+               }
+
+               if (RNA_struct_find_property(op->ptr, "proportional_size") && !RNA_property_is_set(op->ptr, "proportional_size"))
+               {
+                       ts->proportional_size = t->prop_size;
+               }
+                       
+               if (RNA_struct_find_property(op->ptr, "proportional_editing_falloff") && !RNA_property_is_set(op->ptr, "proportional_editing_falloff"))
+               {
+                       ts->prop_mode = t->prop_mode;
+               }
+               
+               if(t->spacetype == SPACE_VIEW3D)
+               {
+                       if (RNA_struct_find_property(op->ptr, "constraint_orientation") && !RNA_property_is_set(op->ptr, "constraint_orientation"))
+                       {
+                               View3D *v3d = t->view;
+       
+                               v3d->twmode = t->current_orientation;
+                       }
+               }
+       }
+       
        if (RNA_struct_find_property(op->ptr, "proportional"))
        {
                RNA_enum_set(op->ptr, "proportional", proportional);
@@ -1164,10 +1320,10 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
        {
                RNA_boolean_set(op->ptr, "mirror", t->flag & T_MIRROR);
        }
-       
+
        if (RNA_struct_find_property(op->ptr, "constraint_axis"))
        {
-               RNA_int_set(op->ptr, "constraint_orientation", t->current_orientation);
+               RNA_enum_set(op->ptr, "constraint_orientation", t->current_orientation);
 
                if (t->con.mode & CON_APPLY)
                {
@@ -1184,20 +1340,6 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
 
                RNA_boolean_set_array(op->ptr, "constraint_axis", constraint_axis);
        }
-
-       // XXX If modal, save settings back in scene
-       if (t->flag & T_MODAL)
-       {
-               ts->prop_mode = t->prop_mode;
-               ts->proportional = proportional;
-
-               if(t->spacetype == SPACE_VIEW3D)
-               {
-                       View3D *v3d = t->view;
-                       
-                       v3d->twmode = t->current_orientation;
-               }
-       }
 }
 
 int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int mode)
@@ -1206,12 +1348,14 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int
 
        /* added initialize, for external calls to set stuff in TransInfo, like undo string */
 
-       t->state = TRANS_RUNNING;
+       t->state = TRANS_STARTING;
 
        t->options = options;
-       
+
        t->mode = mode;
 
+       t->launch_event = event ? event->type : -1;
+
        if (!initTransInfo(C, t, op, event))                                    // internal data, mouse, vectors
        {
                return 0;
@@ -1221,15 +1365,17 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int
        {
                //calc_manipulator_stats(curarea);
                initTransformOrientation(C, t);
-       
-               t->draw_handle = ED_region_draw_cb_activate(t->ar->type, drawTransform, t, REGION_DRAW_POST);
+
+               t->draw_handle_view = ED_region_draw_cb_activate(t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW);
+               t->draw_handle_pixel = ED_region_draw_cb_activate(t->ar->type, drawTransformPixel, t, REGION_DRAW_POST_PIXEL);
        }
        else if(t->spacetype == SPACE_IMAGE) {
-               Mat3One(t->spacemtx);
-               t->draw_handle = ED_region_draw_cb_activate(t->ar->type, drawTransform, t, REGION_DRAW_POST);
+               unit_m3(t->spacemtx);
+               t->draw_handle_view = ED_region_draw_cb_activate(t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW);
+               t->draw_handle_pixel = ED_region_draw_cb_activate(t->ar->type, drawTransformPixel, t, REGION_DRAW_POST_PIXEL);
        }
        else
-               Mat3One(t->spacemtx);
+               unit_m3(t->spacemtx);
 
        createTransData(C, t);                  // make TransData structs from selection
 
@@ -1244,10 +1390,10 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int
        /* EVIL2: we gave as argument also texture space context bit... was cleared */
        /* EVIL3: extend mode for animation editors also switches modes... but is best way to avoid duplicate code */
        mode = t->mode;
-       
+
        calculatePropRatio(t);
        calculateCenter(t);
-       
+
        initMouseInput(t, &t->mouse, t->center2d, t->imval);
 
        switch (mode) {
@@ -1299,6 +1445,9 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int
        case TFM_BONE_ENVELOPE:
                initBoneEnvelope(t);
                break;
+       case TFM_EDGE_SLIDE:
+               initEdgeSlide(t);
+               break;
        case TFM_BONE_ROLL:
                initBoneRoll(t);
                break;
@@ -1311,11 +1460,11 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int
        case TFM_TIME_SCALE:
                initTimeScale(t);
                break;
-       case TFM_TIME_EXTEND: 
+       case TFM_TIME_EXTEND:
                /* now that transdata has been made, do like for TFM_TIME_TRANSLATE (for most Animation
                 * Editors because they have only 1D transforms for time values) or TFM_TRANSLATION
                 * (for Graph/NLA Editors only since they uses 'standard' transforms to get 2D movement)
-                * depending on which editor this was called from 
+                * depending on which editor this was called from
                 */
                if ELEM(t->spacetype, SPACE_IPO, SPACE_NLA)
                        initTranslation(t);
@@ -1369,11 +1518,11 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int
                        if (constraint_axis[2]) {
                                t->con.mode |= CON_AXIS2;
                        }
-                               
-                       setUserConstraint(t, t->con.mode, "%s");                
+
+                       setUserConstraint(t, t->current_orientation, t->con.mode, "%s");
                }
        }
-       
+
        return 1;
 }
 
@@ -1392,7 +1541,7 @@ void transformApply(bContext *C, TransInfo *t)
                t->redraw = 0;
        }
 
-       /* If auto confirm is on, break after one pass */               
+       /* If auto confirm is on, break after one pass */
        if (t->options & CTX_AUTOCONFIRM)
        {
                t->state = TRANS_CONFIRM;
@@ -1409,8 +1558,8 @@ void transformApply(bContext *C, TransInfo *t)
 int transformEnd(bContext *C, TransInfo *t)
 {
        int exit_code = OPERATOR_RUNNING_MODAL;
-       
-       if (t->state != TRANS_RUNNING)
+
+       if (t->state != TRANS_STARTING && t->state != TRANS_RUNNING)
        {
                /* handle restoring objects */
                if(t->state == TRANS_CANCEL)
@@ -1422,16 +1571,16 @@ int transformEnd(bContext *C, TransInfo *t)
                {
                        exit_code = OPERATOR_FINISHED;
                }
-               
-               /* free data */
-               postTrans(t);
-       
+
                /* aftertrans does insert keyframes, and clears base flags, doesnt read transdata */
                special_aftertrans_update(t);
-       
+
+               /* free data */
+               postTrans(t);
+
                /* send events out for redraws */
                viewRedrawPost(t);
-       
+
                /*  Undo as last, certainly after special_trans_update! */
 
                if(t->state == TRANS_CANCEL) {
@@ -1445,204 +1594,8 @@ int transformEnd(bContext *C, TransInfo *t)
 
                viewRedrawForce(C, t);
        }
-       
-       return exit_code;
-}
-
-/* ************************** Manipulator init and main **************************** */
-
-void initManipulator(int mode)
-{
-       printf("init manipulator mode %d\n", mode);
-       
-#if 0 // TRANSFORM_FIX_ME
-       Trans.state = TRANS_RUNNING;
-
-       Trans.options = CTX_NONE;
-       
-       Trans.mode = mode;
-       
-       /* automatic switch to scaling bone envelopes */
-       if(mode==TFM_RESIZE && t->obedit && t->obedit->type==OB_ARMATURE) {
-               bArmature *arm= t->obedit->data;
-               if(arm->drawtype==ARM_ENVELOPE)
-                       mode= TFM_BONE_ENVELOPE;
-       }
-
-       initTrans(&Trans);                                      // internal data, mouse, vectors
-
-       G.moving |= G_TRANSFORM_MANIP;          // signal to draw manipuls while transform
-       createTransData(&Trans);                        // make TransData structs from selection
-
-       if (Trans.total == 0)
-               return;
-
-       initSnapping(&Trans); // Initialize snapping data AFTER mode flags
-
-       /* EVIL! posemode code can switch translation to rotate when 1 bone is selected. will be removed (ton) */
-       /* EVIL2: we gave as argument also texture space context bit... was cleared */
-       mode = Trans.mode;
-       
-       calculatePropRatio(&Trans);
-       calculateCenter(&Trans);
-
-       switch (mode) {
-       case TFM_TRANSLATION:
-               initTranslation(&Trans);
-               break;
-       case TFM_ROTATION:
-               initRotation(&Trans);
-               break;
-       case TFM_RESIZE:
-               initResize(&Trans);
-               break;
-       case TFM_TRACKBALL:
-               initTrackball(&Trans);
-               break;
-       }
-
-       Trans.flag |= T_USES_MANIPULATOR;
-#endif
-}
-
-void ManipulatorTransform() 
-{
-#if 0 // TRANSFORM_FIX_ME
-       int mouse_moved = 0;
-       short pmval[2] = {0, 0}, mval[2], val;
-       unsigned short event;
-
-       if (Trans.total == 0)
-               return;
-
-       Trans.redraw = 1; /* initial draw */
-
-       while (Trans.state == TRANS_RUNNING) {
-               
-               getmouseco_areawin(mval);
-               
-               if (mval[0] != pmval[0] || mval[1] != pmval[1]) {
-                       Trans.redraw = 1;
-               }
-               if (Trans.redraw) {
-                       pmval[0] = mval[0];
-                       pmval[1] = mval[1];
-
-                       //selectConstraint(&Trans);  needed?
-                       if (Trans.transform) {
-                               Trans.transform(&Trans, mval);
-                       }
-                       Trans.redraw = 0;
-               }
-               
-               /* essential for idling subloop */
-               if( qtest()==0) PIL_sleep_ms(2);
-
-               while( qtest() ) {
-                       event= extern_qread(&val);
-
-                       switch (event){
-                       case MOUSEX:
-                       case MOUSEY:
-                               mouse_moved = 1;
-                               break;
-                       /* enforce redraw of transform when modifiers are used */
-                       case LEFTCTRLKEY:
-                       case RIGHTCTRLKEY:
-                               if(val) Trans.redraw = 1;
-                               break;
-                       case LEFTSHIFTKEY:
-                       case RIGHTSHIFTKEY:
-                               /* shift is modifier for higher resolution transform, works nice to store this mouse position */
-                               if(val) {
-                                       getmouseco_areawin(Trans.shiftmval);
-                                       Trans.flag |= T_SHIFT_MOD;
-                                       Trans.redraw = 1;
-                               }
-                               else Trans.flag &= ~T_SHIFT_MOD; 
-                               break;
-                               
-                       case ESCKEY:
-                       case RIGHTMOUSE:
-                               Trans.state = TRANS_CANCEL;
-                               break;
-                       case LEFTMOUSE:
-                               if(mouse_moved==0 && val==0) break;
-                               // else we pass on event to next, which cancels
-                       case SPACEKEY:
-                       case PADENTER:
-                       case RETKEY:
-                               Trans.state = TRANS_CONFIRM;
-                               break;
-   //         case NDOFMOTION:
-     //           viewmoveNDOF(1);
-     //           break;
-                       }
-                       if(val) {
-                               switch(event) {
-                               case PADPLUSKEY:
-                                       if(G.qual & LR_ALTKEY && Trans.flag & T_PROP_EDIT) {
-                                               Trans.propsize*= 1.1f;
-                                               calculatePropRatio(&Trans);
-                                       }
-                                       Trans.redraw= 1;
-                                       break;
-                               case PAGEUPKEY:
-                               case WHEELDOWNMOUSE:
-                                       if (Trans.flag & T_AUTOIK) {
-                                               transform_autoik_update(&Trans, 1);
-                                       }
-                                       else if(Trans.flag & T_PROP_EDIT) {
-                                               Trans.propsize*= 1.1f;
-                                               calculatePropRatio(&Trans);
-                                       }
-                                       else view_editmove(event);
-                                       Trans.redraw= 1;
-                                       break;
-                               case PADMINUS:
-                                       if(G.qual & LR_ALTKEY && Trans.flag & T_PROP_EDIT) {
-                                               Trans.propsize*= 0.90909090f;
-                                               calculatePropRatio(&Trans);
-                                       }
-                                       Trans.redraw= 1;
-                                       break;
-                               case PAGEDOWNKEY:
-                               case WHEELUPMOUSE:
-                                       if (Trans.flag & T_AUTOIK) {
-                                               transform_autoik_update(&Trans, -1);
-                                       }
-                                       else if (Trans.flag & T_PROP_EDIT) {
-                                               Trans.propsize*= 0.90909090f;
-                                               calculatePropRatio(&Trans);
-                                       }
-                                       else view_editmove(event);
-                                       Trans.redraw= 1;
-                                       break;
-                               }
-                                                       
-                               // Numerical input events
-                               Trans.redraw |= handleNumInput(&(Trans.num), event);
-                       }
-               }
-       }
-       
-       if(Trans.state == TRANS_CANCEL) {
-               restoreTransObjects(&Trans);
-       }
-       
-       /* free data, reset vars */
-       postTrans(&Trans);
-       
-       /* aftertrans does insert ipos and action channels, and clears base flags */
-       special_aftertrans_update(&Trans);
-       
-       /* send events out for redraws */
-       viewRedrawPost(&Trans);
 
-       if(Trans.state != TRANS_CANCEL) {
-               BIF_undo_push(transform_to_undostr(&Trans));
-       }
-#endif
+       return exit_code;
 }
 
 /* ************************** TRANSFORM LOCKS **************************** */
@@ -1677,29 +1630,88 @@ static void protectedRotateBits(short protectflag, float *eul, float *oldeul)
                eul[2]= oldeul[2];
 }
 
+
+/* this function only does the delta rotation */
+/* axis-angle is usually internally stored as quats... */
+static void protectedAxisAngleBits(short protectflag, float axis[3], float *angle, float oldAxis[3], float oldAngle)
+{
+       /* check that protection flags are set */
+       if ((protectflag & (OB_LOCK_ROTX|OB_LOCK_ROTY|OB_LOCK_ROTZ|OB_LOCK_ROTW)) == 0)
+               return;
+       
+       if (protectflag & OB_LOCK_ROT4D) {
+               /* axis-angle getting limited as 4D entities that they are... */
+               if (protectflag & OB_LOCK_ROTW)
+                       *angle= oldAngle;
+               if (protectflag & OB_LOCK_ROTX)
+                       axis[0]= oldAxis[0];
+               if (protectflag & OB_LOCK_ROTY)
+                       axis[1]= oldAxis[1];
+               if (protectflag & OB_LOCK_ROTZ)
+                       axis[2]= oldAxis[2];
+       }
+       else {
+               /* axis-angle get limited with euler... */
+               float eul[3], oldeul[3];
+               
+               axis_angle_to_eulO( eul, EULER_ORDER_DEFAULT,axis, *angle);
+               axis_angle_to_eulO( oldeul, EULER_ORDER_DEFAULT,oldAxis, oldAngle);
+               
+               if (protectflag & OB_LOCK_ROTX)
+                       eul[0]= oldeul[0];
+               if (protectflag & OB_LOCK_ROTY)
+                       eul[1]= oldeul[1];
+               if (protectflag & OB_LOCK_ROTZ)
+                       eul[2]= oldeul[2];
+               
+               eulO_to_axis_angle( axis, angle,eul, EULER_ORDER_DEFAULT);
+               
+               /* when converting to axis-angle, we need a special exception for the case when there is no axis */
+               if (IS_EQ(axis[0], axis[1]) && IS_EQ(axis[1], axis[2])) {
+                       /* for now, rotate around y-axis then (so that it simply becomes the roll) */
+                       axis[1]= 1.0f;
+               }
+       }
+}
+
+/* this function only does the delta rotation */
 static void protectedQuaternionBits(short protectflag, float *quat, float *oldquat)
 {
-       /* quaternions get limited with euler... */
-       /* this function only does the delta rotation */
+       /* check that protection flags are set */
+       if ((protectflag & (OB_LOCK_ROTX|OB_LOCK_ROTY|OB_LOCK_ROTZ|OB_LOCK_ROTW)) == 0)
+               return;
        
-       if(protectflag) {
+       if (protectflag & OB_LOCK_ROT4D) {
+               /* quaternions getting limited as 4D entities that they are... */
+               if (protectflag & OB_LOCK_ROTW)
+                       quat[0]= oldquat[0];
+               if (protectflag & OB_LOCK_ROTX)
+                       quat[1]= oldquat[1];
+               if (protectflag & OB_LOCK_ROTY)
+                       quat[2]= oldquat[2];
+               if (protectflag & OB_LOCK_ROTZ)
+                       quat[3]= oldquat[3];
+       }
+       else {
+               /* quaternions get limited with euler... (compatability mode) */
                float eul[3], oldeul[3], quat1[4];
                
                QUATCOPY(quat1, quat);
-               QuatToEul(quat, eul);
-               QuatToEul(oldquat, oldeul);
+               quat_to_eul( eul,quat);
+               quat_to_eul( oldeul,oldquat);
                
-               if(protectflag & OB_LOCK_ROTX)
+               if (protectflag & OB_LOCK_ROTX)
                        eul[0]= oldeul[0];
-               if(protectflag & OB_LOCK_ROTY)
+               if (protectflag & OB_LOCK_ROTY)
                        eul[1]= oldeul[1];
-               if(protectflag & OB_LOCK_ROTZ)
+               if (protectflag & OB_LOCK_ROTZ)
                        eul[2]= oldeul[2];
                
-               EulToQuat(eul, quat);
+               eul_to_quat( quat,eul);
+               
                /* quaternions flip w sign to accumulate rotations correctly */
-               if( (quat1[0]<0.0f && quat[0]>0.0f) || (quat1[0]>0.0f && quat[0]<0.0f) ) {
-                       QuatMulf(quat, -1.0f);
+               if ( (quat1[0]<0.0f && quat[0]>0.0f) || (quat1[0]>0.0f && quat[0]<0.0f) ) {
+                       mul_qt_fl(quat, -1.0f);
                }
        }
 }
@@ -1713,21 +1725,13 @@ static void constraintTransLim(TransInfo *t, TransData *td)
                bConstraintOb cob;
                bConstraint *con;
                
-               /* Make a temporary bConstraintOb for using these limit constraints 
+               /* Make a temporary bConstraintOb for using these limit constraints
                 *      - they only care that cob->matrix is correctly set ;-)
                 *      - current space should be local
                 */
                memset(&cob, 0, sizeof(bConstraintOb));
-               Mat4One(cob.matrix);
-               if (td->tdi) {
-                       TransDataIpokey *tdi= td->tdi;
-                       cob.matrix[3][0]= tdi->locx[0];
-                       cob.matrix[3][1]= tdi->locy[0];
-                       cob.matrix[3][2]= tdi->locz[0];
-               }
-               else {
-                       VECCOPY(cob.matrix[3], td->loc);
-               }
+               unit_m4(cob.matrix);
+               VECCOPY(cob.matrix[3], td->loc);
                
                /* Evaluate valid constraints */
                for (con= td->con; con; con= con->next) {
@@ -1741,14 +1745,14 @@ static void constraintTransLim(TransInfo *t, TransData *td)
                        if (con->type == CONSTRAINT_TYPE_LOCLIMIT) {
                                bLocLimitConstraint *data= con->data;
                                
-                               if ((data->flag2 & LIMIT_TRANSFORM)==0) 
+                               if ((data->flag2 & LIMIT_TRANSFORM)==0)
                                        continue;
                                
                                /* do space conversions */
                                if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
                                        /* just multiply by td->mtx (this should be ok) */
-                                       Mat4CpyMat4(tmat, cob.matrix);
-                                       Mat4MulMat34(cob.matrix, td->mtx, tmat);
+                                       copy_m4_m4(tmat, cob.matrix);
+                                       mul_m4_m3m4(cob.matrix, td->mtx, tmat);
                                }
                                else if (con->ownspace != CONSTRAINT_SPACE_LOCAL) {
                                        /* skip... incompatable spacetype */
@@ -1761,22 +1765,14 @@ static void constraintTransLim(TransInfo *t, TransData *td)
                                /* convert spaces again */
                                if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
                                        /* just multiply by td->mtx (this should be ok) */
-                                       Mat4CpyMat4(tmat, cob.matrix);
-                                       Mat4MulMat34(cob.matrix, td->smtx, tmat);
+                                       copy_m4_m4(tmat, cob.matrix);
+                                       mul_m4_m3m4(cob.matrix, td->smtx, tmat);
                                }
                        }
                }
                
                /* copy results from cob->matrix */
-               if (td->tdi) {
-                       TransDataIpokey *tdi= td->tdi;
-                       tdi->locx[0]= cob.matrix[3][0];
-                       tdi->locy[0]= cob.matrix[3][1];
-                       tdi->locz[0]= cob.matrix[3][2];
-               }
-               else {
-                       VECCOPY(td->loc, cob.matrix[3]);
-               }
+               VECCOPY(td->loc, cob.matrix[3]);
        }
 }
 
@@ -1786,38 +1782,34 @@ static void constraintRotLim(TransInfo *t, TransData *td)
                bConstraintTypeInfo *cti= get_constraint_typeinfo(CONSTRAINT_TYPE_ROTLIMIT);
                bConstraintOb cob;
                bConstraint *con;
-               
-               /* Make a temporary bConstraintOb for using these limit constraints 
+
+               /* Make a temporary bConstraintOb for using these limit constraints
                 *      - they only care that cob->matrix is correctly set ;-)
                 *      - current space should be local
                 */
                memset(&cob, 0, sizeof(bConstraintOb));
-               if (td->flag & TD_USEQUAT) {
+               if (td->rotOrder == ROT_MODE_QUAT) {
                        /* quats */
                        if (td->ext)
-                               QuatToMat4(td->ext->quat, cob.matrix);
+                               quat_to_mat4( cob.matrix,td->ext->quat);
                        else
                                return;
                }
-               else if (td->tdi) {
-                       /* ipo-keys eulers */
-                       TransDataIpokey *tdi= td->tdi;
-                       float eul[3];
-                       
-                       eul[0]= tdi->rotx[0];
-                       eul[1]= tdi->roty[0];
-                       eul[2]= tdi->rotz[0];
-                       
-                       EulToMat4(eul, cob.matrix);
+               else if (td->rotOrder == ROT_MODE_AXISANGLE) {
+                       /* axis angle */
+                       if (td->ext)
+                               axis_angle_to_mat4( cob.matrix,&td->ext->quat[1], td->ext->quat[0]);
+                       else
+                               return;
                }
                else {
                        /* eulers */
                        if (td->ext)
-                               EulToMat4(td->ext->rot, cob.matrix);
+                               eulO_to_mat4( cob.matrix,td->ext->rot, td->rotOrder);
                        else
                                return;
                }
-                       
+               
                /* Evaluate valid constraints */
                for (con= td->con; con; con= con->next) {
                        /* only consider constraint if enabled */
@@ -1830,14 +1822,14 @@ static void constraintRotLim(TransInfo *t, TransData *td)
                                float tmat[4][4];
                                
                                /* only use it if it's tagged for this purpose */
-                               if ((data->flag2 & LIMIT_TRANSFORM)==0) 
+                               if ((data->flag2 & LIMIT_TRANSFORM)==0)
                                        continue;
-                                       
+                               
                                /* do space conversions */
                                if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
                                        /* just multiply by td->mtx (this should be ok) */
-                                       Mat4CpyMat4(tmat, cob.matrix);
-                                       Mat4MulMat34(cob.matrix, td->mtx, tmat);
+                                       copy_m4_m4(tmat, cob.matrix);
+                                       mul_m4_m3m4(cob.matrix, td->mtx, tmat);
                                }
                                else if (con->ownspace != CONSTRAINT_SPACE_LOCAL) {
                                        /* skip... incompatable spacetype */
@@ -1850,31 +1842,24 @@ static void constraintRotLim(TransInfo *t, TransData *td)
                                /* convert spaces again */
                                if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
                                        /* just multiply by td->mtx (this should be ok) */
-                                       Mat4CpyMat4(tmat, cob.matrix);
-                                       Mat4MulMat34(cob.matrix, td->smtx, tmat);
+                                       copy_m4_m4(tmat, cob.matrix);
+                                       mul_m4_m3m4(cob.matrix, td->smtx, tmat);
                                }
                        }
                }
                
                /* copy results from cob->matrix */
-               if (td->flag & TD_USEQUAT) {
+               if (td->rotOrder == ROT_MODE_QUAT) {
                        /* quats */
-                       Mat4ToQuat(cob.matrix, td->ext->quat);
+                       mat4_to_quat( td->ext->quat,cob.matrix);
                }
-               else if (td->tdi) {
-                       /* ipo-keys eulers */
-                       TransDataIpokey *tdi= td->tdi;
-                       float eul[3];
-                       
-                       Mat4ToEul(cob.matrix, eul);
-                       
-                       tdi->rotx[0]= eul[0];
-                       tdi->roty[0]= eul[1];
-                       tdi->rotz[0]= eul[2];
+               else if (td->rotOrder == ROT_MODE_AXISANGLE) {
+                       /* axis angle */
+                       mat4_to_axis_angle( &td->ext->quat[1], &td->ext->quat[0],cob.matrix);
                }
                else {
                        /* eulers */
-                       Mat4ToEul(cob.matrix, td->ext->rot);
+                       mat4_to_eulO( td->ext->rot, td->rotOrder,cob.matrix);
                }
        }
 }
@@ -1886,21 +1871,12 @@ static void constraintSizeLim(TransInfo *t, TransData *td)
                bConstraintOb cob;
                bConstraint *con;
                
-               /* Make a temporary bConstraintOb for using these limit constraints 
+               /* Make a temporary bConstraintOb for using these limit constraints
                 *      - they only care that cob->matrix is correctly set ;-)
                 *      - current space should be local
                 */
                memset(&cob, 0, sizeof(bConstraintOb));
-               if (td->tdi) {
-                       TransDataIpokey *tdi= td->tdi;
-                       float size[3];
-                       
-                       size[0]= tdi->sizex[0];
-                       size[1]= tdi->sizey[0];
-                       size[2]= tdi->sizez[0];
-                       SizeToMat4(size, cob.matrix);
-               } 
-               else if ((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)) {
+               if ((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)) {
                        /* scale val and reset size */
                        return; // TODO: fix this case
                }
@@ -1909,9 +1885,9 @@ static void constraintSizeLim(TransInfo *t, TransData *td)
                        if (td->flag & TD_SINGLESIZE)
                                return;
                        
-                       SizeToMat4(td->ext->size, cob.matrix);
+                       size_to_mat4( cob.matrix,td->ext->size);
                }
-                       
+               
                /* Evaluate valid constraints */
                for (con= td->con; con; con= con->next) {
                        /* only consider constraint if enabled */
@@ -1924,14 +1900,14 @@ static void constraintSizeLim(TransInfo *t, TransData *td)
                                float tmat[4][4];
                                
                                /* only use it if it's tagged for this purpose */
-                               if ((data->flag2 & LIMIT_TRANSFORM)==0) 
+                               if ((data->flag2 & LIMIT_TRANSFORM)==0)
                                        continue;
-                                       
+                               
                                /* do space conversions */
                                if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
                                        /* just multiply by td->mtx (this should be ok) */
-                                       Mat4CpyMat4(tmat, cob.matrix);
-                                       Mat4MulMat34(cob.matrix, td->mtx, tmat);
+                                       copy_m4_m4(tmat, cob.matrix);
+                                       mul_m4_m3m4(cob.matrix, td->mtx, tmat);
                                }
                                else if (con->ownspace != CONSTRAINT_SPACE_LOCAL) {
                                        /* skip... incompatable spacetype */
@@ -1944,24 +1920,14 @@ static void constraintSizeLim(TransInfo *t, TransData *td)
                                /* convert spaces again */
                                if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
                                        /* just multiply by td->mtx (this should be ok) */
-                                       Mat4CpyMat4(tmat, cob.matrix);
-                                       Mat4MulMat34(cob.matrix, td->smtx, tmat);
+                                       copy_m4_m4(tmat, cob.matrix);
+                                       mul_m4_m3m4(cob.matrix, td->smtx, tmat);
                                }
                        }
                }
                
                /* copy results from cob->matrix */
-               if (td->tdi) {
-                       TransDataIpokey *tdi= td->tdi;
-                       float size[3];
-                       
-                       Mat4ToSize(cob.matrix, size);
-                       
-                       tdi->sizex[0]= size[0];
-                       tdi->sizey[0]= size[1];
-                       tdi->sizez[0]= size[2];
-               } 
-               else if ((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)) {
+               if ((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)) {
                        /* scale val and reset size */
                        return; // TODO: fix this case
                }
@@ -1969,15 +1935,15 @@ static void constraintSizeLim(TransInfo *t, TransData *td)
                        /* Reset val if SINGLESIZE but using a constraint */
                        if (td->flag & TD_SINGLESIZE)
                                return;
-                               
-                       Mat4ToSize(cob.matrix, td->ext->size);
+                       
+                       mat4_to_size( td->ext->size,cob.matrix);
                }
        }
 }
 
 /* ************************** WARP *************************** */
 
-void initWarp(TransInfo *t) 
+void initWarp(TransInfo *t)
 {
        float max[3], min[3];
        int i;
@@ -1987,7 +1953,7 @@ void initWarp(TransInfo *t)
        t->handleEvent = handleEventWarp;
        
        initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_RATIO);
-
+       
        t->idx_max = 0;
        t->num.idx_max = 0;
        t->snap[0] = 0.0f;
@@ -2000,11 +1966,11 @@ void initWarp(TransInfo *t)
        for(i = 0; i < t->total; i++) {
                float center[3];
                VECCOPY(center, t->data[i].center);
-               Mat3MulVecfl(t->data[i].mtx, center);
-               Mat4MulVecfl(t->viewmat, center);
-               VecSubf(center, center, t->viewmat[3]);
+               mul_m3_v3(t->data[i].mtx, center);
+               mul_m4_v3(t->viewmat, center);
+               sub_v3_v3v3(center, center, t->viewmat[3]);
                if (i)
-                       MinMax3(min, max, center);
+                       minmax_v3_v3v3(min, max, center);
                else {
                        VECCOPY(max, center);
                        VECCOPY(min, center);
@@ -2014,7 +1980,7 @@ void initWarp(TransInfo *t)
        t->center[0]= (min[0]+max[0])/2.0f;
        t->center[1]= (min[1]+max[1])/2.0f;
        t->center[2]= (min[2]+max[2])/2.0f;
-       
+
        if (max[0] == min[0]) max[0] += 0.1; /* not optimal, but flipping is better than invalid garbage (i.e. division by zero!) */
        t->val= (max[0]-min[0])/2.0f; /* t->val is X dimension projected boundbox */
 }
@@ -2023,14 +1989,14 @@ int handleEventWarp(TransInfo *t, wmEvent *event)
 {
        int status = 0;
        
-       if (event->type == MIDDLEMOUSE && event->val)
+       if (event->type == MIDDLEMOUSE && event->val==KM_PRESS)
        {
                // Use customData pointer to signal warp direction
                if      (t->customData == 0)
                        t->customData = (void*)1;
                else
                        t->customData = 0;
-                       
+               
                status = 1;
        }
        
@@ -2056,15 +2022,15 @@ int Warp(TransInfo *t, short mval[2])
         * into account if in Edit mode.
         */
        VECCOPY(cursor, curs);
-       VECCOPY(gcursor, cursor);       
+       VECCOPY(gcursor, cursor);
        if (t->flag & T_EDIT) {
-               VecSubf(cursor, cursor, t->obedit->obmat[3]);
-               VecSubf(gcursor, gcursor, t->obedit->obmat[3]);
-               Mat3MulVecfl(t->data->smtx, gcursor);
+               sub_v3_v3v3(cursor, cursor, t->obedit->obmat[3]);
+               sub_v3_v3v3(gcursor, gcursor, t->obedit->obmat[3]);
+               mul_m3_v3(t->data->smtx, gcursor);
        }
-       Mat4MulVecfl(t->viewmat, cursor);
-       VecSubf(cursor, cursor, t->viewmat[3]);
-
+       mul_m4_v3(t->viewmat, cursor);
+       sub_v3_v3v3(cursor, cursor, t->viewmat[3]);
+       
        /* amount of degrees for warp */
        circumfac = 360.0f * t->values[0];
        
@@ -2072,7 +2038,7 @@ int Warp(TransInfo *t, short mval[2])
        {
                circumfac *= -1;
        }
-
+       
        snapGrid(t, &circumfac);
        applyNumInput(&t->num, &circumfac);
        
@@ -2095,20 +2061,20 @@ int Warp(TransInfo *t, short mval[2])
                float loc[3];
                if (td->flag & TD_NOACTION)
                        break;
-
+               
                if (td->flag & TD_SKIP)
                        continue;
                
                /* translate point to center, rotate in such a way that outline==distance */
                VECCOPY(vec, td->iloc);
-               Mat3MulVecfl(td->mtx, vec);
-               Mat4MulVecfl(t->viewmat, vec);
-               VecSubf(vec, vec, t->viewmat[3]);
+               mul_m3_v3(td->mtx, vec);
+               mul_m4_v3(t->viewmat, vec);
+               sub_v3_v3v3(vec, vec, t->viewmat[3]);
                
                dist= vec[0]-cursor[0];
                
                /* t->val is X dimension projected boundbox */
-               phi0= (circumfac*dist/t->val);  
+               phi0= (circumfac*dist/t->val);
                
                vec[1]= (vec[1]-cursor[1]);
                
@@ -2118,15 +2084,15 @@ int Warp(TransInfo *t, short mval[2])
                loc[1]= co*vec[1]+cursor[1];
                loc[2]= vec[2];
                
-               Mat4MulVecfl(t->viewinv, loc);
-               VecSubf(loc, loc, t->viewinv[3]);
-               Mat3MulVecfl(td->smtx, loc);
+               mul_m4_v3(t->viewinv, loc);
+               sub_v3_v3v3(loc, loc, t->viewinv[3]);
+               mul_m3_v3(td->smtx, loc);
                
-               VecSubf(loc, loc, td->iloc);
-               VecMulf(loc, td->factor);
-               VecAddf(td->loc, td->iloc, loc);
+               sub_v3_v3v3(loc, loc, td->iloc);
+               mul_v3_fl(loc, td->factor);
+               add_v3_v3v3(td->loc, td->iloc, loc);
        }
-
+       
        recalcData(t);
        
        ED_area_headerprint(t->sa, str);
@@ -2136,7 +2102,7 @@ int Warp(TransInfo *t, short mval[2])
 
 /* ************************** SHEAR *************************** */
 
-void initShear(TransInfo *t) 
+void initShear(TransInfo *t)
 {
        t->mode = TFM_SHEAR;
        t->transform = Shear;
@@ -2157,7 +2123,7 @@ int handleEventShear(TransInfo *t, wmEvent *event)
 {
        int status = 0;
        
-       if (event->type == MIDDLEMOUSE && event->val)
+       if (event->type == MIDDLEMOUSE && event->val==KM_PRESS)
        {
                // Use customData pointer to signal Shear direction
                if      (t->customData == 0)
@@ -2170,7 +2136,7 @@ int handleEventShear(TransInfo *t, wmEvent *event)
                        initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_ABSOLUTE);
                        t->customData = 0;
                }
-                       
+               
                status = 1;
        }
        
@@ -2178,7 +2144,7 @@ int handleEventShear(TransInfo *t, wmEvent *event)
 }
 
 
-int Shear(TransInfo *t, short mval[2]) 
+int Shear(TransInfo *t, short mval[2])
 {
        TransData *td = t->data;
        float vec[3];
@@ -2186,22 +2152,22 @@ int Shear(TransInfo *t, short mval[2])
        float value;
        int i;
        char str[50];
-
-       Mat3CpyMat4(persmat, t->viewmat);
-       Mat3Inv(persinv, persmat);
-
+       
+       copy_m3_m4(persmat, t->viewmat);
+       invert_m3_m3(persinv, persmat);
+       
        value = 0.05f * t->values[0];
-
+       
        snapGrid(t, &value);
-
+       
        applyNumInput(&t->num, &value);
-
+       
        /* header print for NumInput */
        if (hasNumInput(&t->num)) {
                char c[20];
-
+               
                outputNumInput(&(t->num), c);
-
+               
                sprintf(str, "Shear: %s %s", c, t->proptext);
        }
        else {
@@ -2209,7 +2175,7 @@ int Shear(TransInfo *t, short mval[2])
                sprintf(str, "Shear: %.3f %s", value, t->proptext);
        }
        
-       Mat3One(smat);
+       unit_m3(smat);
        
        // Custom data signals shear direction
        if (t->customData == 0)
@@ -2217,38 +2183,38 @@ int Shear(TransInfo *t, short mval[2])
        else
                smat[0][1] = value;
        
-       Mat3MulMat3(tmat, smat, persmat);
-       Mat3MulMat3(totmat, persinv, tmat);
+       mul_m3_m3m3(tmat, smat, persmat);
+       mul_m3_m3m3(totmat, persinv, tmat);
        
        for(i = 0 ; i < t->total; i++, td++) {
                if (td->flag & TD_NOACTION)
                        break;
-
+               
                if (td->flag & TD_SKIP)
                        continue;
-
+               
                if (t->obedit) {
                        float mat3[3][3];
-                       Mat3MulMat3(mat3, totmat, td->mtx);
-                       Mat3MulMat3(tmat, td->smtx, mat3);
+                       mul_m3_m3m3(mat3, totmat, td->mtx);
+                       mul_m3_m3m3(tmat, td->smtx, mat3);
                }
                else {
-                       Mat3CpyMat3(tmat, totmat);
+                       copy_m3_m3(tmat, totmat);
                }
-               VecSubf(vec, td->center, t->center);
-
-               Mat3MulVecfl(tmat, vec);
-
-               VecAddf(vec, vec, t->center);
-               VecSubf(vec, vec, td->center);
-
-               VecMulf(vec, td->factor);
-
-               VecAddf(td->loc, td->iloc, vec);
+               sub_v3_v3v3(vec, td->center, t->center);
+               
+               mul_m3_v3(tmat, vec);
+               
+               add_v3_v3v3(vec, vec, t->center);
+               sub_v3_v3v3(vec, vec, td->center);
+               
+               mul_v3_fl(vec, td->factor);
+               
+               add_v3_v3v3(td->loc, td->iloc, vec);
        }
-
+       
        recalcData(t);
-
+       
        ED_area_headerprint(t->sa, str);
 
        return 1;
@@ -2256,7 +2222,7 @@ int Shear(TransInfo *t, short mval[2])
 
 /* ************************** RESIZE *************************** */
 
-void initResize(TransInfo *t) 
+void initResize(TransInfo *t)
 {
        t->mode = TFM_RESIZE;
        t->transform = Resize;
@@ -2288,7 +2254,7 @@ static void headerResize(TransInfo *t, float vec[3], char *str) {
                sprintf(&tvec[20], "%.4f", vec[1]);
                sprintf(&tvec[40], "%.4f", vec[2]);
        }
-
+       
        if (t->con.mode & CON_APPLY) {
                switch(t->num.idx_max) {
                case 0:
@@ -2317,36 +2283,36 @@ static void TransMat3ToSize( float mat[][3], float smat[][3], float *size)
 {
        float vec[3];
        
-       VecCopyf(vec, mat[0]);
-       size[0]= Normalize(vec);
-       VecCopyf(vec, mat[1]);
-       size[1]= Normalize(vec);
-       VecCopyf(vec, mat[2]);
-       size[2]= Normalize(vec);
+       copy_v3_v3(vec, mat[0]);
+       size[0]= normalize_v3(vec);
+       copy_v3_v3(vec, mat[1]);
+       size[1]= normalize_v3(vec);
+       copy_v3_v3(vec, mat[2]);
+       size[2]= normalize_v3(vec);
        
        /* first tried with dotproduct... but the sign flip is crucial */
-       if( VECSIGNFLIP(mat[0], smat[0]) ) size[0]= -size[0]; 
-       if( VECSIGNFLIP(mat[1], smat[1]) ) size[1]= -size[1]; 
-       if( VECSIGNFLIP(mat[2], smat[2]) ) size[2]= -size[2]; 
+       if( VECSIGNFLIP(mat[0], smat[0]) ) size[0]= -size[0];
+       if( VECSIGNFLIP(mat[1], smat[1]) ) size[1]= -size[1];
+       if( VECSIGNFLIP(mat[2], smat[2]) ) size[2]= -size[2];
 }
 
 
 static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) {
        float tmat[3][3], smat[3][3], center[3];
        float vec[3];
-
+       
        if (t->flag & T_EDIT) {
-               Mat3MulMat3(smat, mat, td->mtx);
-               Mat3MulMat3(tmat, td->smtx, smat);
+               mul_m3_m3m3(smat, mat, td->mtx);
+               mul_m3_m3m3(tmat, td->smtx, smat);
        }
        else {
-               Mat3CpyMat3(tmat, mat);
+               copy_m3_m3(tmat, mat);
        }
-
+       
        if (t->con.applySize) {
                t->con.applySize(t, td, tmat);
        }
-
+       
        /* local constraint shouldn't alter center */
        if (t->around == V3D_LOCAL) {
                if (t->flag & T_OBJECT) {
@@ -2368,42 +2334,28 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) {
        else {
                VECCOPY(center, t->center);
        }
-
+       
        if (td->ext) {
                float fsize[3];
                
                if (t->flag & (T_OBJECT|T_TEXTURE|T_POSE)) {
                        float obsizemat[3][3];
                        // Reorient the size mat to fit the oriented object.
-                       Mat3MulMat3(obsizemat, tmat, td->axismtx);
-                       //printmatrix3("obsizemat", obsizemat);
+                       mul_m3_m3m3(obsizemat, tmat, td->axismtx);
+                       //print_m3("obsizemat", obsizemat);
                        TransMat3ToSize(obsizemat, td->axismtx, fsize);
-                       //printvecf("fsize", fsize);
+                       //print_v3("fsize", fsize);
                }
                else {
-                       Mat3ToSize(tmat, fsize);
+                       mat3_to_size( fsize,tmat);
                }
                
                protectedSizeBits(td->protectflag, fsize);
                
                if ((t->flag & T_V3D_ALIGN)==0) {       // align mode doesn't resize objects itself
-                       /* handle ipokeys? */
-                       if(td->tdi) {
-                               TransDataIpokey *tdi= td->tdi;
-                               /* calculate delta size (equal for size and dsize) */
-                               
-                               vec[0]= (tdi->oldsize[0])*(fsize[0] -1.0f) * td->factor;
-                               vec[1]= (tdi->oldsize[1])*(fsize[1] -1.0f) * td->factor;
-                               vec[2]= (tdi->oldsize[2])*(fsize[2] -1.0f) * td->factor;
-                               
-                               add_tdi_poin(tdi->sizex, tdi->oldsize,   vec[0]);
-                               add_tdi_poin(tdi->sizey, tdi->oldsize+1, vec[1]);
-                               add_tdi_poin(tdi->sizez, tdi->oldsize+2, vec[2]);
-                               
-                       } 
-                       else if((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)){
+                       if((td->flag & TD_SINGLESIZE) && !(t->con.mode & CON_APPLY)){
                                /* scale val and reset size */
-                               *td->val = td->ival * fsize[0] * td->factor;
+                               *td->val = td->ival * (1 + (fsize[0] - 1) * td->factor);
                                
                                td->ext->size[0] = td->ext->isize[0];
                                td->ext->size[1] = td->ext->isize[1];
@@ -2414,9 +2366,9 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) {
                                if (td->flag & TD_SINGLESIZE)
                                        *td->val = td->ival;
                                
-                               td->ext->size[0] = td->ext->isize[0] * (fsize[0]) * td->factor;
-                               td->ext->size[1] = td->ext->isize[1] * (fsize[1]) * td->factor;
-                               td->ext->size[2] = td->ext->isize[2] * (fsize[2]) * td->factor;
+                               td->ext->size[0] = td->ext->isize[0] * (1 + (fsize[0] - 1) * td->factor);
+                               td->ext->size[1] = td->ext->isize[1] * (1 + (fsize[1] - 1) * td->factor);
+                               td->ext->size[2] = td->ext->isize[2] * (1 + (fsize[2] - 1) * td->factor);
                        }
                }
                
@@ -2425,45 +2377,38 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) {
        
        /* For individual element center, Editmode need to use iloc */
        if (t->flag & T_POINTS)
-               VecSubf(vec, td->iloc, center);
+               sub_v3_v3v3(vec, td->iloc, center);
        else
-               VecSubf(vec, td->center, center);
-
-       Mat3MulVecfl(tmat, vec);
-
-       VecAddf(vec, vec, center);
+               sub_v3_v3v3(vec, td->center, center);
+       
+       mul_m3_v3(tmat, vec);
+       
+       add_v3_v3v3(vec, vec, center);
        if (t->flag & T_POINTS)
-               VecSubf(vec, vec, td->iloc);
+               sub_v3_v3v3(vec, vec, td->iloc);
        else
-               VecSubf(vec, vec, td->center);
-
-       VecMulf(vec, td->factor);
-
+               sub_v3_v3v3(vec, vec, td->center);
+       
+       mul_v3_fl(vec, td->factor);
+       
        if (t->flag & (T_OBJECT|T_POSE)) {
-               Mat3MulVecfl(td->smtx, vec);
+               mul_m3_v3(td->smtx, vec);
        }
-
+       
        protectedTransBits(td->protectflag, vec);
-
-       if(td->tdi) {
-               TransDataIpokey *tdi= td->tdi;
-               add_tdi_poin(tdi->locx, tdi->oldloc, vec[0]);
-               add_tdi_poin(tdi->locy, tdi->oldloc+1, vec[1]);
-               add_tdi_poin(tdi->locz, tdi->oldloc+2, vec[2]);
-       }
-       else VecAddf(td->loc, td->iloc, vec);
+       add_v3_v3v3(td->loc, td->iloc, vec);
        
        constraintTransLim(t, td);
 }
 
-int Resize(TransInfo *t, short mval[2]) 
+int Resize(TransInfo *t, short mval[2])
 {
        TransData *td;
        float size[3], mat[3][3];
        float ratio;
        int i;
        char str[200];
-
+       
        /* for manipulator, center handle, the scaling can't be done relative to center */
        if( (t->flag & T_USES_MANIPULATOR) && t->con.mode==0)
        {
@@ -2475,73 +2420,73 @@ int Resize(TransInfo *t, short mval[2])
        }
        
        size[0] = size[1] = size[2] = ratio;
-
+       
        snapGrid(t, size);
-
+       
        if (hasNumInput(&t->num)) {
                applyNumInput(&t->num, size);
                constraintNumInput(t, size);
        }
-
+       
        applySnapping(t, size);
-
+       
        if (t->flag & T_AUTOVALUES)
        {
                VECCOPY(size, t->auto_values);
        }
-
+       
        VECCOPY(t->values, size);
-
-       SizeToMat3(size, mat);
-
+       
+       size_to_mat3( mat,size);
+       
        if (t->con.applySize) {
                t->con.applySize(t, NULL, mat);
        }
-
-       Mat3CpyMat3(t->mat, mat);       // used in manipulator
+       
+       copy_m3_m3(t->mat, mat);        // used in manipulator
        
        headerResize(t, size, str);
-
+       
        for(i = 0, td=t->data; i < t->total; i++, td++) {
                if (td->flag & TD_NOACTION)
                        break;
-
+               
                if (td->flag & TD_SKIP)
                        continue;
                
                ElementResize(t, td, mat);
        }
-
+       
        /* evil hack - redo resize if cliping needed */
        if (t->flag & T_CLIP_UV && clipUVTransform(t, size, 1)) {
-               SizeToMat3(size, mat);
-
+               size_to_mat3( mat,size);
+               
                if (t->con.applySize)
                        t->con.applySize(t, NULL, mat);
-
+               
                for(i = 0, td=t->data; i < t->total; i++, td++)
                        ElementResize(t, td, mat);
        }
-
+       
        recalcData(t);
-
+       
        ED_area_headerprint(t->sa, str);
-
+       
        return 1;
 }
 
 /* ************************** TOSPHERE *************************** */
 
-void initToSphere(TransInfo *t) 
+void initToSphere(TransInfo *t)
 {
        TransData *td = t->data;
        int i;
-
+       
        t->mode = TFM_TOSPHERE;
        t->transform = ToSphere;
        
        initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_RATIO);
-
+       
        t->idx_max = 0;
        t->num.idx_max = 0;
        t->snap[0] = 0.0f;
@@ -2553,37 +2498,37 @@ void initToSphere(TransInfo *t)
        
        // Calculate average radius
        for(i = 0 ; i < t->total; i++, td++) {
-               t->val += VecLenf(t->center, td->iloc);
+               t->val += len_v3v3(t->center, td->iloc);
        }
-
+       
        t->val /= (float)t->total;
 }
 
-int ToSphere(TransInfo *t, short mval[2]) 
+int ToSphere(TransInfo *t, short mval[2])
 {
        float vec[3];
        float ratio, radius;
        int i;
        char str[64];
        TransData *td = t->data;
-
+       
        ratio = t->values[0];
-
+       
        snapGrid(t, &ratio);
-
+       
        applyNumInput(&t->num, &ratio);
-
+       
        if (ratio < 0)
                ratio = 0.0f;
        else if (ratio > 1)
                ratio = 1.0f;
-
+       
        /* header print for NumInput */
        if (hasNumInput(&t->num)) {
                char c[20];
-
+               
                outputNumInput(&(t->num), c);
-
+               
                sprintf(str, "To Sphere: %s %s", c, t->proptext);
        }
        else {
@@ -2596,33 +2541,33 @@ int ToSphere(TransInfo *t, short mval[2])
                float tratio;
                if (td->flag & TD_NOACTION)
                        break;
-
+               
                if (td->flag & TD_SKIP)
                        continue;
-
-               VecSubf(vec, td->iloc, t->center);
-
-               radius = Normalize(vec);
-
+               
+               sub_v3_v3v3(vec, td->iloc, t->center);
+               
+               radius = normalize_v3(vec);
+               
                tratio = ratio * td->factor;
-
-               VecMulf(vec, radius * (1.0f - tratio) + t->val * tratio);
-
-               VecAddf(td->loc, t->center, vec);
+               
+               mul_v3_fl(vec, radius * (1.0f - tratio) + t->val * tratio);
+               
+               add_v3_v3v3(td->loc, t->center, vec);
        }
        
-
+       
        recalcData(t);
-
+       
        ED_area_headerprint(t->sa, str);
-
+       
        return 1;
 }
 
 /* ************************** ROTATION *************************** */
 
 
-void initRotation(TransInfo *t) 
+void initRotation(TransInfo *t)
 {
        t->mode = TFM_ROTATION;
        t->transform = Rotation;
@@ -2654,32 +2599,32 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short
                        center = td->center;
                }
                else {
-                       /* !TODO! Make this if not rely on G */
                        if(around==V3D_LOCAL && (t->settings->selectmode & SCE_SELECT_FACE)) {
                                center = td->center;
                        }
                }
        }
-               
+       
        if (t->flag & T_POINTS) {
-               Mat3MulMat3(totmat, mat, td->mtx);
-               Mat3MulMat3(smat, td->smtx, totmat);
+               mul_m3_m3m3(totmat, mat, td->mtx);
+               mul_m3_m3m3(smat, td->smtx, totmat);
                
-               VecSubf(vec, td->iloc, center);
-               Mat3MulVecfl(smat, vec);
+               sub_v3_v3v3(vec, td->iloc, center);
+               mul_m3_v3(smat, vec);
                
-               VecAddf(td->loc, vec, center);
-
-               VecSubf(vec,td->loc,td->iloc);
+               add_v3_v3v3(td->loc, vec, center);
+               
+               sub_v3_v3v3(vec,td->loc,td->iloc);
                protectedTransBits(td->protectflag, vec);
-               VecAddf(td->loc, td->iloc, vec);
-
+               add_v3_v3v3(td->loc, td->iloc, vec);
+               
+               
                if(td->flag & TD_USEQUAT) {
-                       Mat3MulSerie(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0);
-                       Mat3ToQuat(fmat, quat); // Actual transform
+                       mul_serie_m3(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0);
+                       mat3_to_quat( quat,fmat);       // Actual transform
                        
                        if(td->ext->quat){
-                               QuatMul(td->ext->quat, quat, td->ext->iquat);
+                               mul_qt_qtqt(td->ext->quat, quat, td->ext->iquat);
                                
                                /* is there a reason not to have this here? -jahka */
                                protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat);
@@ -2688,11 +2633,11 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short
        }
        /**
         * HACK WARNING
-        * 
+        *
         * This is some VERY ugly special case to deal with pose mode.
-        * 
+        *
         * The problem is that mtx and smtx include each bone orientation.
-        * 
+        *
         * That is needed to rotate each bone properly, HOWEVER, to calculate
         * the translation component, we only need the actual armature object's
         * matrix (and inverse). That is not all though. Once the proper translation
@@ -2700,60 +2645,76 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short
         */
        else if (t->flag & T_POSE) {
                float pmtx[3][3], imtx[3][3];
-
-               // Extract and invert armature object matrix            
-               Mat3CpyMat4(pmtx, t->poseobj->obmat);
-               Mat3Inv(imtx, pmtx);
+               
+               // Extract and invert armature object matrix
+               copy_m3_m4(pmtx, t->poseobj->obmat);
+               invert_m3_m3(imtx, pmtx);
                
                if ((td->flag & TD_NO_LOC) == 0)
                {
-                       VecSubf(vec, td->center, center);
+                       sub_v3_v3v3(vec, td->center, center);
                        
-                       Mat3MulVecfl(pmtx, vec);        // To Global space
-                       Mat3MulVecfl(mat, vec);         // Applying rotation
-                       Mat3MulVecfl(imtx, vec);        // To Local space
+                       mul_m3_v3(pmtx, vec);   // To Global space
+                       mul_m3_v3(mat, vec);            // Applying rotation
+                       mul_m3_v3(imtx, vec);   // To Local space
                        
-                       VecAddf(vec, vec, center);
+                       add_v3_v3v3(vec, vec, center);
                        /* vec now is the location where the object has to be */
                        
-                       VecSubf(vec, vec, td->center); // Translation needed from the initial location
+                       sub_v3_v3v3(vec, vec, td->center); // Translation needed from the initial location
+                       
+                       mul_m3_v3(pmtx, vec);   // To Global space
+                       mul_m3_v3(td->smtx, vec);// To Pose space
                        
-                       Mat3MulVecfl(pmtx, vec);        // To Global space
-                       Mat3MulVecfl(td->smtx, vec);// To Pose space
-                               
                        protectedTransBits(td->protectflag, vec);
                        
-                       VecAddf(td->loc, td->iloc, vec);
+                       add_v3_v3v3(td->loc, td->iloc, vec);
                        
                        constraintTransLim(t, td);
                }
                
                /* rotation */
                if ((t->flag & T_V3D_ALIGN)==0) { // align mode doesn't rotate objects itself
-                       /* euler or quaternion? */
-                       if (td->flag & TD_USEQUAT) {
-                               Mat3MulSerie(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0);
+                       /* euler or quaternion/axis-angle? */
+                       if (td->rotOrder == ROT_MODE_QUAT) {
+                               mul_serie_m3(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0);
                                
-                               Mat3ToQuat(fmat, quat); // Actual transform
+                               mat3_to_quat( quat,fmat);       // Actual transform
                                
-                               QuatMul(td->ext->quat, quat, td->ext->iquat);
+                               mul_qt_qtqt(td->ext->quat, quat, td->ext->iquat);
                                /* this function works on end result */
                                protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat);
+                               
                        }
-                       else {
+                       else if (td->rotOrder == ROT_MODE_AXISANGLE) {
+                               /* calculate effect based on quats */
+                               float iquat[4], tquat[4];
+                               
+                               axis_angle_to_quat(iquat, td->ext->irotAxis, td->ext->irotAngle);
+                               
+                               mul_serie_m3(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0);
+                               mat3_to_quat( quat,fmat);       // Actual transform
+                               mul_qt_qtqt(tquat, quat, iquat);
+                               
+                               quat_to_axis_angle( td->ext->rotAxis, td->ext->rotAngle,tquat); 
+                               
+                               /* this function works on end result */
+                               protectedAxisAngleBits(td->protectflag, td->ext->rotAxis, td->ext->rotAngle, td->ext->irotAxis, td->ext->irotAngle);
+                       }
+                       else { 
                                float eulmat[3][3];
                                
-                               Mat3MulMat3(totmat, mat, td->mtx);
-                               Mat3MulMat3(smat, td->smtx, totmat);
+                               mul_m3_m3m3(totmat, mat, td->mtx);
+                               mul_m3_m3m3(smat, td->smtx, totmat);
                                
                                /* calculate the total rotatation in eulers */
                                VECCOPY(eul, td->ext->irot);
-                               EulToMat3(eul, eulmat);
+                               eulO_to_mat3( eulmat,eul, td->rotOrder);
                                
                                /* mat = transform, obmat = bone rotation */
-                               Mat3MulMat3(fmat, smat, eulmat);
+                               mul_m3_m3m3(fmat, smat, eulmat);
                                
-                               Mat3ToCompatibleEul(fmat, eul, td->ext->rot);
+                               mat3_to_compatible_eulO( eul, td->ext->rot, td->rotOrder,fmat);
                                
                                /* and apply (to end result only) */
                                protectedRotateBits(td->protectflag, eul, td->ext->irot);
@@ -2767,97 +2728,67 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short
                if ((td->flag & TD_NO_LOC) == 0)
                {
                        /* translation */
-                       VecSubf(vec, td->center, center);
-                       Mat3MulVecfl(mat, vec);
-                       VecAddf(vec, vec, center);
+                       sub_v3_v3v3(vec, td->center, center);
+                       mul_m3_v3(mat, vec);
+                       add_v3_v3v3(vec, vec, center);
                        /* vec now is the location where the object has to be */
-                       VecSubf(vec, vec, td->center);
-                       Mat3MulVecfl(td->smtx, vec);
+                       sub_v3_v3v3(vec, vec, td->center);
+                       mul_m3_v3(td->smtx, vec);
                        
                        protectedTransBits(td->protectflag, vec);
                        
-                       if(td->tdi) {
-                               TransDataIpokey *tdi= td->tdi;
-                               add_tdi_poin(tdi->locx, tdi->oldloc, vec[0]);
-                               add_tdi_poin(tdi->locy, tdi->oldloc+1, vec[1]);
-                               add_tdi_poin(tdi->locz, tdi->oldloc+2, vec[2]);
-                       }
-                       else VecAddf(td->loc, td->iloc, vec);
+                       add_v3_v3v3(td->loc, td->iloc, vec);
                }
                
                
                constraintTransLim(t, td);
-
+               
                /* rotation */
                if ((t->flag & T_V3D_ALIGN)==0) { // align mode doesn't rotate objects itself
                        /* euler or quaternion? */
-                   if (td->flag & TD_USEQUAT) {
-                               Mat3MulSerie(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0);
-                               Mat3ToQuat(fmat, quat); // Actual transform
+                   if ((td->rotOrder == ROT_MODE_QUAT) || (td->flag & TD_USEQUAT)) {
+                               mul_serie_m3(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0);
+                               mat3_to_quat( quat,fmat);       // Actual transform
                                
-                               QuatMul(td->ext->quat, quat, td->ext->iquat);
+                               mul_qt_qtqt(td->ext->quat, quat, td->ext->iquat);
                                /* this function works on end result */
                                protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat);
                        }
+                       else if (td->rotOrder == ROT_MODE_AXISANGLE) {
+                               /* calculate effect based on quats */
+                               float iquat[4], tquat[4];
+                               
+                               axis_angle_to_quat(iquat, td->ext->irotAxis, td->ext->irotAngle);
+                               
+                               mul_serie_m3(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0);
+                               mat3_to_quat( quat,fmat);       // Actual transform
+                               mul_qt_qtqt(tquat, quat, iquat);
+                               
+                               quat_to_axis_angle( td->ext->rotAxis, td->ext->rotAngle,quat); 
+                               
+                               /* this function works on end result */
+                               protectedAxisAngleBits(td->protectflag, td->ext->rotAxis, td->ext->rotAngle, td->ext->irotAxis, td->ext->irotAngle);
+                       }
                        else {
                                float obmat[3][3];
                                
-                               /* are there ipo keys? */
-                               if(td->tdi) {
-                                       TransDataIpokey *tdi= td->tdi;
-                                       float current_rot[3];
-                                       float rot[3];
-                                       
-                                       /* current IPO value for compatible euler */
-                                       current_rot[0] = (tdi->rotx) ? tdi->rotx[0] : 0.0f;
-                                       current_rot[1] = (tdi->roty) ? tdi->roty[0] : 0.0f;
-                                       current_rot[2] = (tdi->rotz) ? tdi->rotz[0] : 0.0f;
-                                       VecMulf(current_rot, (float)(M_PI_2 / 9.0));
-                                       
-                                       /* calculate the total rotatation in eulers */
-                                       VecAddf(eul, td->ext->irot, td->ext->drot);
-                                       EulToMat3(eul, obmat);
-                                       /* mat = transform, obmat = object rotation */
-                                       Mat3MulMat3(fmat, mat, obmat);
-                                       
-                                       Mat3ToCompatibleEul(fmat, eul, current_rot);
-                                       
-                                       /* correct back for delta rot */
-                                       if(tdi->flag & TOB_IPODROT) {
-                                               VecSubf(rot, eul, td->ext->irot);
-                                       }
-                                       else {
-                                               VecSubf(rot, eul, td->ext->drot);
-                                       }
-                                       
-                                       VecMulf(rot, (float)(9.0/M_PI_2));
-                                       VecSubf(rot, rot, tdi->oldrot);
-                                       
-                                       protectedRotateBits(td->protectflag, rot, tdi->oldrot);
-                                       
-                                       add_tdi_poin(tdi->rotx, tdi->oldrot, rot[0]);
-                                       add_tdi_poin(tdi->roty, tdi->oldrot+1, rot[1]);
-                                       add_tdi_poin(tdi->rotz, tdi->oldrot+2, rot[2]);
-                               }
-                               else {
-                                       Mat3MulMat3(totmat, mat, td->mtx);
-                                       Mat3MulMat3(smat, td->smtx, totmat);
-                                       
-                                       /* calculate the total rotatation in eulers */
-                                       VecAddf(eul, td->ext->irot, td->ext->drot); /* we have to correct for delta rot */
-                                       EulToMat3(eul, obmat);
-                                       /* mat = transform, obmat = object rotation */
-                                       Mat3MulMat3(fmat, smat, obmat);
-                                       
-                                       Mat3ToCompatibleEul(fmat, eul, td->ext->rot);
-                                       
-                                       /* correct back for delta rot */
-                                       VecSubf(eul, eul, td->ext->drot);
-                                       
-                                       /* and apply */
-                                       protectedRotateBits(td->protectflag, eul, td->ext->irot);
-                                       VECCOPY(td->ext->rot, eul);
-                               }
+                               mul_m3_m3m3(totmat, mat, td->mtx);
+                               mul_m3_m3m3(smat, td->smtx, totmat);
+                               
+                               /* calculate the total rotatation in eulers */
+                               add_v3_v3v3(eul, td->ext->irot, td->ext->drot); /* we have to correct for delta rot */
+                               eulO_to_mat3( obmat,eul, td->rotOrder);
+                               /* mat = transform, obmat = object rotation */
+                               mul_m3_m3m3(fmat, smat, obmat);
+                               
+                               mat3_to_compatible_eulO( eul, td->ext->rot, td->rotOrder,fmat);
+                               
+                               /* correct back for delta rot */
+                               sub_v3_v3v3(eul, eul, td->ext->drot);
+                               
+                               /* and apply */
+                               protectedRotateBits(td->protectflag, eul, td->ext->irot);
+                               VECCOPY(td->ext->rot, eul);
                        }
                        
                        constraintRotLim(t, td);
@@ -2865,106 +2796,106 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short
        }
 }
 
-static void applyRotation(TransInfo *t, float angle, float axis[3]) 
+static void applyRotation(TransInfo *t, float angle, float axis[3])
 {
        TransData *td = t->data;
        float mat[3][3];
        int i;
-
-       VecRotToMat3(axis, angle, mat);
+       
+       vec_rot_to_mat3( mat,axis, angle);
        
        for(i = 0 ; i < t->total; i++, td++) {
-
+               
                if (td->flag & TD_NOACTION)
                        break;
-
+               
                if (td->flag & TD_SKIP)
                        continue;
                
                if (t->con.applyRot) {
                        t->con.applyRot(t, td, axis, NULL);
-                       VecRotToMat3(axis, angle * td->factor, mat);
+                       vec_rot_to_mat3( mat,axis, angle * td->factor);
                }
                else if (t->flag & T_PROP_EDIT) {
-                       VecRotToMat3(axis, angle * td->factor, mat);
+                       vec_rot_to_mat3( mat,axis, angle * td->factor);
                }
-
+               
                ElementRotation(t, td, mat, t->around);
        }
 }
 
-int Rotation(TransInfo *t, short mval[2]) 
+int Rotation(TransInfo *t, short mval[2])
 {
        char str[64];
-
+       
        float final;
-
+       
        float axis[3];
        float mat[3][3];
-
+       
        VECCOPY(axis, t->viewinv[2]);
-       VecMulf(axis, -1.0f);
-       Normalize(axis);
-
+       mul_v3_fl(axis, -1.0f);
+       normalize_v3(axis);
+       
        final = t->values[0];
-
+       
        applyNDofInput(&t->ndof, &final);
        
        snapGrid(t, &final);
-
+       
        if (t->con.applyRot) {
                t->con.applyRot(t, NULL, axis, &final);
        }
        
        applySnapping(t, &final);
-
+       
        if (hasNumInput(&t->num)) {
                char c[20];
-
+               
                applyNumInput(&t->num, &final);
-
+               
                outputNumInput(&(t->num), c);
-
+               
                sprintf(str, "Rot: %s %s %s", &c[0], t->con.text, t->proptext);
-
+               
                /* Clamp between -180 and 180 */
                while (final >= 180.0)
                        final -= 360.0;
                
                while (final <= -180.0)
                        final += 360.0;
-
+               
                final *= (float)(M_PI / 180.0);
        }
        else {
                sprintf(str, "Rot: %.2f%s %s", 180.0*final/M_PI, t->con.text, t->proptext);
        }
-
-       VecRotToMat3(axis, final, mat);
-
+       
+       vec_rot_to_mat3( mat,axis, final);
+       
        // TRANSFORM_FIX_ME
 //     t->values[0] = final;           // used in manipulator
-//     Mat3CpyMat3(t->mat, mat);       // used in manipulator
+//     copy_m3_m3(t->mat, mat);        // used in manipulator
        
        applyRotation(t, final, axis);
        
        recalcData(t);
-
+       
        ED_area_headerprint(t->sa, str);
-
+       
        return 1;
 }
 
 
 /* ************************** TRACKBALL *************************** */
 
-void initTrackball(TransInfo *t) 
+void initTrackball(TransInfo *t)
 {
        t->mode = TFM_TRACKBALL;
        t->transform = Trackball;
-       
+
        initMouseInputMode(t, &t->mouse, INPUT_TRACKBALL);
-       
+
        t->ndof.axis = 40;
        /* Scale down input for rotation */
        t->ndof.factor[0] = 0.2f;
@@ -2975,7 +2906,7 @@ void initTrackball(TransInfo *t)
        t->snap[0] = 0.0f;
        t->snap[1] = (float)((5.0/180)*M_PI);
        t->snap[2] = t->snap[1] * 0.2f;
-       
+
        t->flag |= T_NO_CONSTRAINT;
 }
 
@@ -2985,10 +2916,10 @@ static void applyTrackball(TransInfo *t, float axis1[3], float axis2[3], float a
        float mat[3][3], smat[3][3], totmat[3][3];
        int i;
 
-       VecRotToMat3(axis1, angles[0], smat);
-       VecRotToMat3(axis2, angles[1], totmat);
-       
-       Mat3MulMat3(mat, smat, totmat);
+       vec_rot_to_mat3( smat,axis1, angles[0]);
+       vec_rot_to_mat3( totmat,axis2, angles[1]);
+
+       mul_m3_m3m3(mat, smat, totmat);
 
        for(i = 0 ; i < t->total; i++, td++) {
                if (td->flag & TD_NOACTION)
@@ -2996,46 +2927,46 @@ static void applyTrackball(TransInfo *t, float axis1[3], float axis2[3], float a
 
                if (td->flag & TD_SKIP)
                        continue;
-               
+
                if (t->flag & T_PROP_EDIT) {
-                       VecRotToMat3(axis1, td->factor * angles[0], smat);
-                       VecRotToMat3(axis2, td->factor * angles[1], totmat);
-                       
-                       Mat3MulMat3(mat, smat, totmat);
+                       vec_rot_to_mat3( smat,axis1, td->factor * angles[0]);
+                       vec_rot_to_mat3( totmat,axis2, td->factor * angles[1]);
+
+                       mul_m3_m3m3(mat, smat, totmat);
                }
-               
+
                ElementRotation(t, td, mat, t->around);
        }
 }
 
-int Trackball(TransInfo *t, short mval[2]) 
+int Trackball(TransInfo *t, short mval[2])
 {
        char str[128];
        float axis1[3], axis2[3];
        float mat[3][3], totmat[3][3], smat[3][3];
        float phi[2];
-       
+
        VECCOPY(axis1, t->persinv[0]);
        VECCOPY(axis2, t->persinv[1]);
-       Normalize(axis1);
-       Normalize(axis2);
-       
+       normalize_v3(axis1);
+       normalize_v3(axis2);
+
        phi[0] = t->values[0];
        phi[1] = t->values[1];
-               
+
        applyNDofInput(&t->ndof, phi);
-       
+
        snapGrid(t, phi);
-       
+
        if (hasNumInput(&t->num)) {
                char c[40];
-               
+
                applyNumInput(&t->num, phi);
-               
+
                outputNumInput(&(t->num), c);
-               
+
                sprintf(str, "Trackball: %s %s %s", &c[0], &c[20], t->proptext);
-               
+
                phi[0] *= (float)(M_PI / 180.0);
                phi[1] *= (float)(M_PI / 180.0);
        }
@@ -3043,36 +2974,36 @@ int Trackball(TransInfo *t, short mval[2])
                sprintf(str, "Trackball: %.2f %.2f %s", 180.0*phi[0]/M_PI, 180.0*phi[1]/M_PI, t->proptext);
        }
 
-       VecRotToMat3(axis1, phi[0], smat);
-       VecRotToMat3(axis2, phi[1], totmat);
-       
-       Mat3MulMat3(mat, smat, totmat);
-       
+       vec_rot_to_mat3( smat,axis1, phi[0]);
+       vec_rot_to_mat3( totmat,axis2, phi[1]);
+
+       mul_m3_m3m3(mat, smat, totmat);
+
        // TRANSFORM_FIX_ME
-       //Mat3CpyMat3(t->mat, mat);     // used in manipulator
-       
+       //copy_m3_m3(t->mat, mat);      // used in manipulator
+
        applyTrackball(t, axis1, axis2, phi);
-       
+
        recalcData(t);
-       
+
        ED_area_headerprint(t->sa, str);
-       
+
        return 1;
 }
 
 /* ************************** TRANSLATION *************************** */
-       
-void initTranslation(TransInfo *t) 
+
+void initTranslation(TransInfo *t)
 {
        t->mode = TFM_TRANSLATION;
        t->transform = Translation;
-       
+
        initMouseInputMode(t, &t->mouse, INPUT_VECTOR);
 
        t->idx_max = (t->flag & T_2D_EDIT)? 1: 2;
        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) {
@@ -3098,10 +3029,10 @@ static void headerTranslation(TransInfo *t, float vec[3], char *str) {
        char distvec[20];
        char autoik[20];
        float dist;
-       
+
        if (hasNumInput(&t->num)) {
                outputNumInput(&(t->num), tvec);
-               dist = VecLength(t->num.val);
+               dist = len_v3(t->num.val);
        }
        else {
                float dvec[3];
@@ -3109,20 +3040,30 @@ static void headerTranslation(TransInfo *t, float vec[3], char *str) {
                VECCOPY(dvec, vec);
                applyAspectRatio(t, dvec);
 
-               dist = VecLength(vec);
-               sprintf(&tvec[0], "%.4f", dvec[0]);
-               sprintf(&tvec[20], "%.4f", dvec[1]);
-               sprintf(&tvec[40], "%.4f", dvec[2]);
+               dist = len_v3(vec);
+               if(t->scene->unit.system) {
+                       int i, do_split= t->scene->unit.flag & USER_UNIT_OPT_SPLIT ? 1:0;
+
+                       for(i=0; i<3; i++)
+                               bUnit_AsString(&tvec[i*20], 20, dvec[i]*t->scene->unit.scale_length, 4, t->scene->unit.system, B_UNIT_LENGTH, do_split, 1);
+               }
+               else {
+                       sprintf(&tvec[0], "%.4f", dvec[0]);
+                       sprintf(&tvec[20], "%.4f", dvec[1]);
+                       sprintf(&tvec[40], "%.4f", dvec[2]);
+               }
        }
 
-       if( dist > 1e10 || dist < -1e10 )       /* prevent string buffer overflow */
+       if(t->scene->unit.system)
+               bUnit_AsString(distvec, sizeof(distvec), dist*t->scene->unit.scale_length, 4, t->scene->unit.system, B_UNIT_LENGTH, t->scene->unit.flag & USER_UNIT_OPT_SPLIT, 0);
+       else if( dist > 1e10 || dist < -1e10 )  /* prevent string buffer overflow */
                sprintf(distvec, "%.4e", dist);
        else
                sprintf(distvec, "%.4f", dist);
-               
+
        if(t->flag & T_AUTOIK) {
                short chainlen= t->settings->autoik_chainlen;
-               
+
                if(chainlen)
                        sprintf(autoik, "AutoIK-Len: %d", chainlen);
                else
@@ -3174,12 +3115,12 @@ static void applyTranslation(TransInfo *t, float vec[3]) {
                                float mat[3][3];
                                float angle;
                                
-                               Crossf(axis, original_normal, t->tsnap.snapNormal);
-                               angle = saacos(Inpf(original_normal, t->tsnap.snapNormal));
+                               cross_v3_v3v3(axis, original_normal, t->tsnap.snapNormal);
+                               angle = saacos(dot_v3v3(original_normal, t->tsnap.snapNormal));
                                
-                               AxisAngleToQuat(quat, axis, angle);
-       
-                               QuatToMat3(quat, mat);
+                               axis_angle_to_quat(quat, axis, angle);
+                               
+                               quat_to_mat3( mat,quat);
                                
                                ElementRotation(t, td, mat, V3D_LOCAL);
                        }
@@ -3187,12 +3128,12 @@ static void applyTranslation(TransInfo *t, float vec[3]) {
                        {
                                float mat[3][3];
                                
-                               Mat3One(mat);
+                               unit_m3(mat);
                                
                                ElementRotation(t, td, mat, V3D_LOCAL);
                        }
                }
-
+               
                if (t->con.applyVec) {
                        float pvec[3];
                        t->con.applyVec(t, td, vec, tvec, pvec);
@@ -3201,30 +3142,23 @@ static void applyTranslation(TransInfo *t, float vec[3]) {
                        VECCOPY(tvec, vec);
                }
                
-               Mat3MulVecfl(td->smtx, tvec);
-               VecMulf(tvec, td->factor);
+               mul_m3_v3(td->smtx, tvec);
+               mul_v3_fl(tvec, td->factor);
                
                protectedTransBits(td->protectflag, tvec);
                
-               /* transdata ipokey */
-               if(td->tdi) {
-                       TransDataIpokey *tdi= td->tdi;
-                       add_tdi_poin(tdi->locx, tdi->oldloc, tvec[0]);
-                       add_tdi_poin(tdi->locy, tdi->oldloc+1, tvec[1]);
-                       add_tdi_poin(tdi->locz, tdi->oldloc+2, tvec[2]);
-               }
-               else VecAddf(td->loc, td->iloc, tvec);
+               add_v3_v3v3(td->loc, td->iloc, tvec);
                
                constraintTransLim(t, td);
        }
 }
 
 /* uses t->vec to store actual translation in */
-int Translation(TransInfo *t, short mval[2]) 
+int Translation(TransInfo *t, short mval[2])
 {
        float tvec[3];
        char str[250];
-       
+
        if (t->con.mode & CON_APPLY) {
                float pvec[3] = {0.0f, 0.0f, 0.0f};
                applySnapping(t, t->values);
@@ -3240,11 +3174,11 @@ int Translation(TransInfo *t, short mval[2])
                {
                        removeAspectRatio(t, t->values);
                }
-               
+
                applySnapping(t, t->values);
                headerTranslation(t, t->values, str);
        }
-       
+
        applyTranslation(t, t->values);
 
        /* evil hack - redo translation if clipping needed */
@@ -3260,7 +3194,7 @@ int Translation(TransInfo *t, short mval[2])
 
 /* ************************** SHRINK/FATTEN *************************** */
 
-void initShrinkFatten(TransInfo *t) 
+void initShrinkFatten(TransInfo *t)
 {
        // If not in mesh edit mode, fallback to Resize
        if (t->obedit==NULL || t->obedit->type != OB_MESH) {
@@ -3269,22 +3203,22 @@ void initShrinkFatten(TransInfo *t)
        else {
                t->mode = TFM_SHRINKFATTEN;
                t->transform = ShrinkFatten;
-               
+
                initMouseInputMode(t, &t->mouse, INPUT_VERTICAL_ABSOLUTE);
-       
+
                t->idx_max = 0;
                t->num.idx_max = 0;
                t->snap[0] = 0.0f;
                t->snap[1] = 1.0f;
                t->snap[2] = t->snap[1] * 0.1f;
-               
+
                t->flag |= T_NO_CONSTRAINT;
        }
 }
 
 
 
-int ShrinkFatten(TransInfo *t, short mval[2]) 
+int ShrinkFatten(TransInfo *t, short mval[2])
 {
        float vec[3];
        float distance;
@@ -3310,8 +3244,8 @@ int ShrinkFatten(TransInfo *t, short mval[2])
                /* default header print */
                sprintf(str, "Shrink/Fatten: %.4f %s", distance, t->proptext);
        }
-       
-       
+
+
        for(i = 0 ; i < t->total; i++, td++) {
                if (td->flag & TD_NOACTION)
                        break;
@@ -3320,10 +3254,10 @@ int ShrinkFatten(TransInfo *t, short mval[2])
                        continue;
 
                VECCOPY(vec, td->axismtx[2]);
-               VecMulf(vec, distance);
-               VecMulf(vec, td->factor);
+               mul_v3_fl(vec, distance);
+               mul_v3_fl(vec, td->factor);
 
-               VecAddf(td->loc, td->iloc, vec);
+               add_v3_v3v3(td->loc, td->iloc, vec);
        }
 
        recalcData(t);
@@ -3335,11 +3269,11 @@ int ShrinkFatten(TransInfo *t, short mval[2])
 
 /* ************************** TILT *************************** */
 
-void initTilt(TransInfo *t) 
+void initTilt(TransInfo *t)
 {
        t->mode = TFM_TILT;
        t->transform = Tilt;
-       
+
        initMouseInputMode(t, &t->mouse, INPUT_ANGLE);
 
        t->ndof.axis = 16;
@@ -3351,13 +3285,13 @@ void initTilt(TransInfo *t)
        t->snap[0] = 0.0f;
        t->snap[1] = (float)((5.0/180)*M_PI);
        t->snap[2] = t->snap[1] * 0.2f;
-       
+
        t->flag |= T_NO_CONSTRAINT;
 }
 
 
 
-int Tilt(TransInfo *t, short mval[2]) 
+int Tilt(TransInfo *t, short mval[2])
 {
        TransData *td = t->data;
        int i;
@@ -3366,7 +3300,7 @@ int Tilt(TransInfo *t, short mval[2])
        float final;
 
        final = t->values[0];
-       
+
        applyNDofInput(&t->ndof, &final);
 
        snapGrid(t, &final);
@@ -3412,72 +3346,72 @@ void initCurveShrinkFatten(TransInfo *t)
 {
        t->mode = TFM_CURVE_SHRINKFATTEN;
        t->transform = CurveShrinkFatten;
-       
+
        initMouseInputMode(t, &t->mouse, INPUT_SPRING);
-       
+
        t->idx_max = 0;
        t->num.idx_max = 0;
        t->snap[0] = 0.0f;
        t->snap[1] = 0.1f;
        t->snap[2] = t->snap[1] * 0.1f;
-       
+
        t->flag |= T_NO_CONSTRAINT;
 }
 
-int CurveShrinkFatten(TransInfo *t, short mval[2]) 
+int CurveShrinkFatten(TransInfo *t, short mval[2])
 {
        TransData *td = t->data;
        float ratio;
        int i;
        char str[50];
-       
+
        ratio = t->values[0];
-       
+
        snapGrid(t, &ratio);
-       
+
        applyNumInput(&t->num, &ratio);
-       
+
        /* header print for NumInput */
        if (hasNumInput(&t->num)) {
                char c[20];
-               
+
                outputNumInput(&(t->num), c);
                sprintf(str, "Shrink/Fatten: %s", c);
        }
        else {
                sprintf(str, "Shrink/Fatten: %3f", ratio);
        }
-       
+
        for(i = 0 ; i < t->total; i++, td++) {
                if (td->flag & TD_NOACTION)
                        break;
 
                if (td->flag & TD_SKIP)
                        continue;
-               
+
                if(td->val) {
                        //*td->val= ratio;
                        *td->val= td->ival*ratio;
                        if (*td->val <= 0.0f) *td->val = 0.0001f;
                }
        }
-       
+
        recalcData(t);
-       
+
        ED_area_headerprint(t->sa, str);
-       
+
        return 1;
 }
 
 /* ************************** PUSH/PULL *************************** */
 
-void initPushPull(TransInfo *t) 
+void initPushPull(TransInfo *t)
 {
        t->mode = TFM_PUSHPULL;
        t->transform = PushPull;
-       
+
        initMouseInputMode(t, &t->mouse, INPUT_VERTICAL_ABSOLUTE);
-       
+
        t->ndof.axis = 4;
        /* Flip direction */
        t->ndof.factor[0] = -1.0f;
@@ -3490,7 +3424,7 @@ void initPushPull(TransInfo *t)
 }
 
 
-int PushPull(TransInfo *t, short mval[2]) 
+int PushPull(TransInfo *t, short mval[2])
 {
        float vec[3], axis[3];
        float distance;
@@ -3499,7 +3433,7 @@ int PushPull(TransInfo *t, short mval[2])
        TransData *td = t->data;
 
        distance = t->values[0];
-       
+
        applyNDofInput(&t->ndof, &distance);
 
        snapGrid(t, &distance);
@@ -3518,11 +3452,11 @@ int PushPull(TransInfo *t, short mval[2])
                /* default header print */
                sprintf(str, "Push/Pull: %.4f%s %s", distance, t->con.text, t->proptext);
        }
-       
+
        if (t->con.applyRot && t->con.mode & CON_APPLY) {
                t->con.applyRot(t, NULL, axis, NULL);
        }
-       
+
        for(i = 0 ; i < t->total; i++, td++) {
                if (td->flag & TD_NOACTION)
                        break;
@@ -3530,23 +3464,23 @@ int PushPull(TransInfo *t, short mval[2])
                if (td->flag & TD_SKIP)
                        continue;
 
-               VecSubf(vec, t->center, td->center);
+               sub_v3_v3v3(vec, t->center, td->center);
                if (t->con.applyRot && t->con.mode & CON_APPLY) {
                        t->con.applyRot(t, td, axis, NULL);
                        if (isLockConstraint(t)) {
                                float dvec[3];
-                               Projf(dvec, vec, axis);
-                               VecSubf(vec, vec, dvec);
+                               project_v3_v3v3(dvec, vec, axis);
+                               sub_v3_v3v3(vec, vec, dvec);
                        }
                        else {
-                               Projf(vec, vec, axis);
+                               project_v3_v3v3(vec, vec, axis);
                        }
                }
-               Normalize(vec);
-               VecMulf(vec, distance);
-               VecMulf(vec, td->factor);
+               normalize_v3(vec);
+               mul_v3_fl(vec, distance);
+               mul_v3_fl(vec, td->factor);
 
-               VecAddf(td->loc, td->iloc, vec);
+               add_v3_v3v3(td->loc, td->iloc, vec);
        }
 
        recalcData(t);
@@ -3558,11 +3492,11 @@ int PushPull(TransInfo *t, short mval[2])
 
 /* ************************** BEVEL **************************** */
 
-void initBevel(TransInfo *t) 
+void initBevel(TransInfo *t)
 {
        t->transform = Bevel;
        t->handleEvent = handleEventBevel;
-       
+
        initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_ABSOLUTE);
 
        t->mode = TFM_BEVEL;
@@ -3590,7 +3524,7 @@ void initBevel(TransInfo *t)
 
 int handleEventBevel(TransInfo *t, wmEvent *event)
 {
-       if (event->val) {
+       if (event->val==KM_PRESS) {
                if(!G.editBMesh) return 0;
 
                switch (event->type) {
@@ -3631,7 +3565,7 @@ int Bevel(TransInfo *t, short mval[2])
 
        mode = (G.editBMesh->options & BME_BEVEL_VERT) ? "verts only" : "normal";
        distance = t->values[0] / 4; /* 4 just seemed a nice value to me, nothing special */
-       
+
        distance = fabs(distance);
 
        snapGrid(t, &distance);
@@ -3650,7 +3584,7 @@ int Bevel(TransInfo *t, short mval[2])
                /* default header print */
                sprintf(str, "Bevel - Dist: %.4f, Mode: %s (MMB to toggle))", distance, mode);
        }
-       
+
        if (distance < 0) distance = -distance;
        for(i = 0 ; i < t->total; i++, td++) {
                if (td->axismtx[1][0] > 0 && distance > td->axismtx[1][0]) {
@@ -3671,23 +3605,23 @@ int Bevel(TransInfo *t, short mval[2])
 
 /* ************************** BEVEL WEIGHT *************************** */
 
-void initBevelWeight(TransInfo *t) 
+void initBevelWeight(TransInfo *t)
 {
        t->mode = TFM_BWEIGHT;
        t->transform = BevelWeight;
-       
+
        initMouseInputMode(t, &t->mouse, INPUT_SPRING);
-       
+
        t->idx_max = 0;
        t->num.idx_max = 0;
        t->snap[0] = 0.0f;
        t->snap[1] = 0.1f;
        t->snap[2] = t->snap[1] * 0.1f;
-       
+
        t->flag |= T_NO_CONSTRAINT;
 }
 
-int BevelWeight(TransInfo *t, short mval[2]) 
+int BevelWeight(TransInfo *t, short mval[2])
 {
        TransData *td = t->data;
        float weight;
@@ -3721,7 +3655,7 @@ int BevelWeight(TransInfo *t, short mval[2])
                else
                        sprintf(str, "Bevel Weight: %.3f %s", weight, t->proptext);
        }
-       
+
        for(i = 0 ; i < t->total; i++, td++) {
                if (td->flag & TD_NOACTION)
                        break;
@@ -3742,23 +3676,23 @@ int BevelWeight(TransInfo *t, short mval[2])
 
 /* ************************** CREASE *************************** */
 
-void initCrease(TransInfo *t) 
+void initCrease(TransInfo *t)
 {
        t->mode = TFM_CREASE;
        t->transform = Crease;
-       
+
        initMouseInputMode(t, &t->mouse, INPUT_SPRING);
-       
+
        t->idx_max = 0;
        t->num.idx_max = 0;
        t->snap[0] = 0.0f;
        t->snap[1] = 0.1f;
        t->snap[2] = t->snap[1] * 0.1f;
-       
+
        t->flag |= T_NO_CONSTRAINT;
 }
 
-int Crease(TransInfo *t, short mval[2]) 
+int Crease(TransInfo *t, short mval[2])
 {
        TransData *td = t->data;
        float crease;
@@ -3792,7 +3726,7 @@ int Crease(TransInfo *t, short mval[2])
                else
                        sprintf(str, "Crease: %.3f %s", crease, t->proptext);
        }
-       
+
        for(i = 0 ; i < t->total; i++, td++) {
                if (td->flag & TD_NOACTION)
                        break;
@@ -3820,9 +3754,9 @@ void initBoneSize(TransInfo *t)
 {
        t->mode = TFM_BONESIZE;
        t->transform = BoneSize;
-       
+
        initMouseInputMode(t, &t->mouse, INPUT_SPRING_FLIP);
-       
+
        t->idx_max = 2;
        t->num.idx_max = 2;
        t->num.flag |= NUM_NULL_ONE;
@@ -3846,7 +3780,7 @@ static void headerBoneSize(TransInfo *t, float vec[3], char *str) {
        if (t->con.mode & CON_APPLY) {
                if (t->num.idx_max == 0)
                        sprintf(str, "ScaleB: %s%s %s", &tvec[0], t->con.text, t->proptext);
-               else 
+               else
                        sprintf(str, "ScaleB: %s : %s : %s%s %s", &tvec[0], &tvec[20], &tvec[40], t->con.text, t->proptext);
        }
        else {
@@ -3854,27 +3788,27 @@ static void headerBoneSize(TransInfo *t, float vec[3], char *str) {
        }
 }
 
-static void ElementBoneSize(TransInfo *t, TransData *td, float mat[3][3]) 
+static void ElementBoneSize(TransInfo *t, TransData *td, float mat[3][3])
 {
        float tmat[3][3], smat[3][3], oldy;
        float sizemat[3][3];
-       
-       Mat3MulMat3(smat, mat, td->mtx);
-       Mat3MulMat3(tmat, td->smtx, smat);
-       
+
+       mul_m3_m3m3(smat, mat, td->mtx);
+       mul_m3_m3m3(tmat, td->smtx, smat);
+
        if (t->con.applySize) {
                t->con.applySize(t, td, tmat);
        }
-       
+
        /* we've tucked the scale in loc */
        oldy= td->iloc[1];
-       SizeToMat3(td->iloc, sizemat);
-       Mat3MulMat3(tmat, tmat, sizemat);
-       Mat3ToSize(tmat, td->loc);
+       size_to_mat3( sizemat,td->iloc);
+       mul_m3_m3m3(tmat, tmat, sizemat);
+       mat3_to_size( td->loc,tmat);
        td->loc[1]= oldy;
 }
 
-int BoneSize(TransInfo *t, short mval[2]) 
+int BoneSize(TransInfo *t, short mval[2])
 {
        TransData *td = t->data;
        float size[3], mat[3][3];
@@ -3902,20 +3836,20 @@ int BoneSize(TransInfo *t, short mval[2])
                constraintNumInput(t, size);
        }
        
-       SizeToMat3(size, mat);
+       size_to_mat3( mat,size);
        
        if (t->con.applySize) {
                t->con.applySize(t, NULL, mat);
        }
        
-       Mat3CpyMat3(t->mat, mat);       // used in manipulator
+       copy_m3_m3(t->mat, mat);        // used in manipulator
        
        headerBoneSize(t, size, str);
        
        for(i = 0 ; i < t->total; i++, td++) {
                if (td->flag & TD_NOACTION)
                        break;
-
+               
                if (td->flag & TD_SKIP)
                        continue;
                
@@ -3944,11 +3878,11 @@ void initBoneEnvelope(TransInfo *t)
        t->snap[0] = 0.0f;
        t->snap[1] = 0.1f;
        t->snap[2] = t->snap[1] * 0.1f;
-
+       
        t->flag |= T_NO_CONSTRAINT;
 }
 
-int BoneEnvelope(TransInfo *t, short mval[2]) 
+int BoneEnvelope(TransInfo *t, short mval[2])
 {
        TransData *td = t->data;
        float ratio;
@@ -3975,7 +3909,7 @@ int BoneEnvelope(TransInfo *t, short mval[2])
        for(i = 0 ; i < t->total; i++, td++) {
                if (td->flag & TD_NOACTION)
                        break;
-
+               
                if (td->flag & TD_SKIP)
                        continue;
                
@@ -3995,6 +3929,857 @@ int BoneEnvelope(TransInfo *t, short mval[2])
        return 1;
 }
 
+/* ********************  Edge Slide   *************** */
+#if 1
+static int createSlideVerts(TransInfo *t) {
+#else
+static BMEdge *get_other_edge(BMesh *bm, BMVert *v, BMEdge *e)
+{
+       BMIter iter;
+       BMEdge *e2;
+
+       BM_ITER(e, &iter, bm, BM_EDGES_OF_VERT, v) {
+               if (BM_TestHFlag(e2, BM_SELECT) && e2 != e)
+                       return e;
+       }
+
+       return NULL;
+}
+
+static BMLoop *get_next_loop(BMesh *bm, BMVert *v, BMFace *f, 
+                             BMEdge *olde, BMEdge *nexte)
+{
+       BMIter iter;
+       BMLoop *l, firstl;
+
+       BM_ITER(l, &iter, bm, BM_LOOPS_OF_FACE, f) {
+               if (l->e == olde)
+                       break;
+       }
+
+       firstl = l;
+       do {
+               l = BM_OtherFaceLoop(l->e, l->f, v);
+               if (l->radial.next->data == l)
+                       return NULL;
+               
+               if (BM_OtherFaceLoop(l->e, l->f, v)->e == nexte)
+                       return BM_OtherFaceLoop(l->e, l->f, v);
+               
+               if (l->e == nexte)
+                       return l;
+
+               l = l->radial.next->data;
+       } while (l != firstl); 
+
+       return NULL;
+}
+
+static int createSlideVerts(TransInfo *t)
+{
+       Mesh *me = t->obedit->data;
+       BMEditMesh *em = me->edit_btmesh;
+       BMIter iter, iter2;
+       BMEdge *e, *e1, *e2;
+       BMVert *v, *first;
+       BMLoop *l, *l1, *l2;
+       TransDataSlideVert *tempsv;
+       GHash **uvarray= NULL;
+       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->regiondata;
+       float projectMat[4][4];
+       float start[3] = {0.0f, 0.0f, 0.0f}, end[3] = {0.0f, 0.0f, 0.0f};
+       float vec[3], i, j;
+       float totvec=0.0;
+
+       if (!v3d) {
+               /*ok, let's try to survive this*/
+               unit_m4(projectMat);
+       } else {
+               view3d_get_object_project_mat(v3d, t->obedit, projectMat);
+       }
+       
+       /*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->edge to a selected edge*/
+                                       v->edge = e;
+
+                                       numsel++;
+                               }
+                       }
+
+                       if (numsel > 2) {
+                               return 0; //invalid edge selection
+                       }
+               }
+       }
+
+       BM_ITER(e, &iter, em->bm, BM_EDGES_OF_MESH, NULL) {
+               if (BM_TestHFlag(e, BM_SELECT)) {
+                       if (BM_Edge_FaceCount(e) > 2)
+                               return 0; //can't handle more then 2 faces around an edge
+               }
+       }
+
+       j = 0;
+       BM_ITER(v, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
+               if (BM_TestHFlag(v, BM_SELECT)) {
+                       BMINDEX_SET(v, 1);
+                       j += 1;
+               } else BMINDEX_SET(v, 0);
+       }
+
+       if (!j)
+               return 0;
+
+       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 (BMINDEX_GET(v))
+                               break;
+
+               }
+
+               if (!v)
+                       break;
+
+               BMINDX_SET(v, 0);
+
+               if (!v->edge)
+                       continue
+               
+               first = v;
+
+               /*walk along the edge loop*/
+               e = v->edge;
+
+               /*first, rewind*/
+               numsel = 0;
+               do {
+                       e = get_other_edge(bm, v, e);
+                       if (!e) {
+                               e = v->edge;
+                               break;
+                       }
+
+                       v = BM_OtherEdgeVert(e, v);
+                       numsel += 1;
+               } while (e != v->edge);
+
+               l1 = l2 = l = NULL;
+
+               /*iterate over the loop*/
+               first = v;
+               do {
+                       TransDataSlideVert *sv = tempsv + j;
+
+                       sv->v = v;
+                       sv->origvert = *v;
+
+                       e = get_other_edge(bm, v, e);
+                       if (!e) {
+                               e = v->edge;
+                               break;
+                       }
+
+                       v = BM_OtherEdgeVert(e, v);
+                       j += 1
+               } while (e != v->edge);
+       }
+
+       MEM_freeN(tempsv);
+#endif
+#if 0
+       Mesh *me = t->obedit->data;
+       BMEditMesh *em = me->edit_btmesh;
+       EditFace *efa;
+       EditEdge *eed,*first=NULL,*last=NULL, *temp = NULL;
+       EditVert *ev, *nearest = NULL;
+       LinkNode *edgelist = NULL, *vertlist=NULL, *look;
+       GHash *vertgh;
+       TransDataSlideVert *tempsv;
+       float vertdist; // XXX, projectMat[4][4];
+       int i, j, numsel, numadded=0, timesthrough = 0, vertsel=0;
+       /* UV correction vars */
+       GHash **uvarray= NULL;
+       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->regiondata;
+       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;
+
+       if (!v3d) {
+               /*ok, let's try to survive this*/
+               unit_m4(projectMat);
+       } else {
+               view3d_get_object_project_mat(v3d, 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;
+       }
+
+       //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");
+                               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");
+                               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");
+                               return 0;
+                       }
+               }
+               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");
+                               return 0;
+                       }
+               }
+               // Make sure loop is not 2 edges of same face
+               if(ct > 1) {
+                  //BKE_report(op->reports, RPT_ERROR, "Loop crosses itself");
+                  return 0;
+               }
+       }
+
+       // Get # of selected verts
+       for(ev=em->verts.first;ev;ev=ev->next) {
+               if(ev->f & SELECT) vertsel++;
+       }
+
+       // Test for multiple segments
+       if(vertsel > numsel+1) {
+               //BKE_report(op->reports, RPT_ERROR, "Please choose a single edge loop");
+               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++;
+               }
+
+               // 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");
+                       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;
+
+                               //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);
+       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(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;
+       }
+
+       // make sure the UPs nad DOWNs are 'faceloops'
+       // Also find the nearest slidevert to the cursor
+
+       look = vertlist;
+       nearest = NULL;
+       vertdist = -1;
+       while(look) {
+               tempsv  = BLI_ghash_lookup(vertgh,(EditVert*)look->link);
+
+               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;
+               }
+
+               if(me->drawflag & ME_DRAW_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;
+                       }
+               }
+
+               if(look->next != NULL) {
+                       TransDataSlideVert *sv;
+                       
+                       ev = (EditVert*)look->next->link;
+                       sv = BLI_ghash_lookup(vertgh, ev);
+
+                       if(sv) {
+                               float co[3], co2[3], vec[3];
+
+                               ev = (EditVert*)look->link;
+
+                               if(!sharesFace(em, tempsv->up,sv->up)) {
+                                       EditEdge *swap;
+                                       swap = sv->up;
+                                       sv->up = sv->down;
+                                       sv->down = swap;
+                               }
+                               
+                               if (v3d) {
+                                       view3d_project_float(t->ar, tempsv->up->v1->co, co, projectMat);
+                                       view3d_project_float(t->ar, tempsv->up->v2->co, co2, projectMat);
+                               }
+
+                               if (ev == tempsv->up->v1) {
+                                       sub_v3_v3v3(vec, co, co2);
+                               } else {
+                                       sub_v3_v3v3(vec, co2, co);
+                               }
+
+                               add_v3_v3v3(start, start, vec);
+
+                               if (v3d) {
+                                       view3d_project_float(t->ar, tempsv->down->v1->co, co, projectMat);
+                                       view3d_project_float(t->ar, tempsv->down->v2->co, co2, projectMat);
+                               }
+
+                               if (ev == tempsv->down->v1) {
+                                       sub_v3_v3v3(vec, co2, co);
+                               } else {
+                                       sub_v3_v3v3(vec, co, co2);
+                               }
+
+                               add_v3_v3v3(end, end, vec);
+
+                               totvec += 1.0f;
+                               nearest = (EditVert*)look->link;
+                       }
+               }
+
+
+
+               look = look->next;
+       }
+
+       add_v3_v3v3(start, start, end);
+       mul_v3_fl(start, 0.5*(1.0/totvec));
+       VECCOPY(vec, start);
+       start[0] = t->mval[0];
+       start[1] = t->mval[1];
+       add_v3_v3v3(end, start, vec);
+       
+       sld->start[0] = (short) start[0];
+       sld->start[1] = (short) start[1];
+       sld->end[0] = (short) end[0];
+       sld->end[1] = (short) end[1];
+       
+       if (uvlay_tot) { // XXX && (scene->toolsettings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT)) {
+               int maxnum = 0;
+
+               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;
+
+               for (uvlay_idx=0; uvlay_idx<uvlay_tot; uvlay_idx++) {
+
+                       uvarray[uvlay_idx] = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
+
+                       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.0001 || fabs(suv->origuv[1]-uv_new[1])) {
+                                                                       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);
+                                                       }
+                                               }
+                                       }
+                               }
+                               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;
+#endif
+}
+
+void freeSlideVerts(TransInfo *t)
+{
+#if 0
+       TransDataSlideUv *suv;
+       SlideData *sld = t->customData;
+       int uvlay_idx;
+
+       //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);
+       }
+
+       MEM_freeN(sld);
+       t->customData = NULL;
+#endif
+}
+
+void initEdgeSlide(TransInfo *t)
+{
+       SlideData *sld;
+
+       t->mode = TFM_EDGE_SLIDE;
+       t->transform = EdgeSlide;
+       
+       createSlideVerts(t);
+       sld = t->customData;
+
+       if (!sld)
+               return;
+
+       t->customFree = freeSlideVerts;
+
+       /* set custom point first if you want value to be initialized by init */
+       setCustomPoints(t, &t->mouse, sld->end, sld->start);
+       initMouseInputMode(t, &t->mouse, INPUT_CUSTOM_RATIO);
+       
+       t->idx_max = 0;
+       t->num.idx_max = 0;
+       t->snap[0] = 0.0f;
+       t->snap[1] = (float)((5.0/180)*M_PI);
+       t->snap[2] = t->snap[1] * 0.2f;
+
+       t->flag |= T_NO_CONSTRAINT;
+}
+
+int doEdgeSlide(TransInfo *t, float perc)
+{
+#if 0
+       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 = 0.0f;
+       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=sld->slideuv;
+       float uv_tmp[2];
+       LinkNode *fuv_link;
+
+       len = 0.0f;
+
+       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;
+                                               }
+                                       }
+                               }
+                       }
+
+                       look = look->next;
+               }
+       }
+       else {
+               //Non prop code
+               look = vertlist;
+               while(look) {
+                       float newlen;
+                       ev = look->link;
+                       tempsv = BLI_ghash_lookup(vertgh,ev);
+                       newlen = (len / len_v3v3(editedge_getOtherVert(tempsv->up,ev)->co,editedge_getOtherVert(tempsv->down,ev)->co));
+                       if(newlen > 1.0) {newlen = 1.0;}
+                       if(newlen < 0.0) {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;
+               }
+
+       }
+#endif
+       return 1;
+}
+
+int EdgeSlide(TransInfo *t, short mval[2])
+{
+       char str[50];
+       float final;
+
+       final = t->values[0];
+
+       snapGrid(t, &final);
+
+       if (hasNumInput(&t->num)) {
+               char c[20];
+
+               applyNumInput(&t->num, &final);
+
+               outputNumInput(&(t->num), c);
+
+               sprintf(str, "Edge Slide Percent: %s", &c[0]);
+       }
+       else {
+               sprintf(str, "Edge Slide Percent: %.2f", final);
+       }
+
+       CLAMP(final, -1.0f, 1.0f);
+
+       /*do stuff here*/
+       if (t->customData)
+               doEdgeSlide(t, final);
+       else {
+               strcpy(str, "Invalid Edge Selection");
+               t->state = TRANS_CANCEL;
+       }
+
+       recalcData(t);
+
+       ED_area_headerprint(t->sa, str);
+
+       return 1;
+}
 
 /* ******************** EditBone roll *************** */
 
@@ -4002,7 +4787,7 @@ void initBoneRoll(TransInfo *t)
 {
        t->mode = TFM_BONE_ROLL;
        t->transform = BoneRoll;
-       
+
        initMouseInputMode(t, &t->mouse, INPUT_ANGLE);
 
        t->idx_max = 0;
@@ -4010,11 +4795,11 @@ void initBoneRoll(TransInfo *t)
        t->snap[0] = 0.0f;
        t->snap[1] = (float)((5.0/180)*M_PI);
        t->snap[2] = t->snap[1] * 0.2f;
-       
+
        t->flag |= T_NO_CONSTRAINT;
 }
 
-int BoneRoll(TransInfo *t, short mval[2]) 
+int BoneRoll(TransInfo *t, short mval[2])
 {
        TransData *td = t->data;
        int i;
@@ -4040,18 +4825,18 @@ int BoneRoll(TransInfo *t, short mval[2])
        else {
                sprintf(str, "Roll: %.2f", 180.0*final/M_PI);
        }
-       
+
        /* set roll values */
-       for (i = 0; i < t->total; i++, td++) {  
+       for (i = 0; i < t->total; i++, td++) {
                if (td->flag & TD_NOACTION)
                        break;
 
                if (td->flag & TD_SKIP)
                        continue;
-               
+
                *(td->val) = td->ival - final;
        }
-               
+
        recalcData(t);
 
        ED_area_headerprint(t->sa, str);
@@ -4061,11 +4846,11 @@ int BoneRoll(TransInfo *t, short mval[2])
 
 /* ************************** BAKE TIME ******************* */
 
-void initBakeTime(TransInfo *t) 
+void initBakeTime(TransInfo *t)
 {
        t->transform = BakeTime;
        initMouseInputMode(t, &t->mouse, INPUT_NONE);
-       
+
        t->idx_max = 0;
        t->num.idx_max = 0;
        t->snap[0] = 0.0f;
@@ -4073,15 +4858,15 @@ void initBakeTime(TransInfo *t)
        t->snap[2] = t->snap[1] * 0.1f;
 }
 
-int BakeTime(TransInfo *t, short mval[2]) 
+int BakeTime(TransInfo *t, short mval[2])
 {
        TransData *td = t->data;
        float time;
        int i;
        char str[50];
-       
+
        float fac = 0.1f;
-               
+
        if(t->mouse.precision) {
                /* calculate ratio for shiftkey pos, and for total, and blend these for precision */
                time= (float)(t->center2d[0] - t->mouse.precision_mval[0]) * fac;
@@ -4113,7 +4898,7 @@ int BakeTime(TransInfo *t, short mval[2])
                else
                        sprintf(str, "Time: %.3f %s", time, t->proptext);
        }
-       
+
        for(i = 0 ; i < t->total; i++, td++) {
                if (td->flag & TD_NOACTION)
                        break;
@@ -4137,7 +4922,7 @@ int BakeTime(TransInfo *t, short mval[2])
 
 /* ************************** MIRROR *************************** */
 
-void initMirror(TransInfo *t) 
+void initMirror(TransInfo *t)
 {
        t->transform = Mirror;
        initMouseInputMode(t, &t->mouse, INPUT_NONE);
@@ -4148,7 +4933,7 @@ void initMirror(TransInfo *t)
        }
 }
 
-int Mirror(TransInfo *t, short mval[2]) 
+int Mirror(TransInfo *t, short mval[2])
 {
        TransData *td;
        float size[3], mat[3][3];
@@ -4164,48 +4949,51 @@ int Mirror(TransInfo *t, short mval[2])
        /* if an axis has been selected */
        if (t->con.mode & CON_APPLY) {
                size[0] = size[1] = size[2] = -1;
-       
-               SizeToMat3(size, mat);
-               
+
+               size_to_mat3( mat,size);
+
                if (t->con.applySize) {
                        t->con.applySize(t, NULL, mat);
                }
-               
+
                sprintf(str, "Mirror%s", t->con.text);
-       
+
                for(i = 0, td=t->data; i < t->total; i++, td++) {
                        if (td->flag & TD_NOACTION)
                                break;
-       
+
                        if (td->flag & TD_SKIP)
                                continue;
-                       
+
                        ElementResize(t, td, mat);
                }
-       
+
                recalcData(t);
-       
+
                ED_area_headerprint(t->sa, str);
        }
        else
        {
                size[0] = size[1] = size[2] = 1;
-       
-               SizeToMat3(size, mat);
-               
+
+               size_to_mat3( mat,size);
+
                for(i = 0, td=t->data; i < t->total; i++, td++) {
                        if (td->flag & TD_NOACTION)
                                break;
-       
+
                        if (td->flag & TD_SKIP)
                                continue;
-                       
+
                        ElementResize(t, td, mat);
                }
-       
+
                recalcData(t);
-       
-               ED_area_headerprint(t->sa, "Select a mirror axis (X, Y, Z)");
+
+               if(t->flag & T_2D_EDIT)
+                       ED_area_headerprint(t->sa, "Select a mirror axis (X, Y)");
+               else
+                       ED_area_headerprint(t->sa, "Select a mirror axis (X, Y, Z)");
        }
 
        return 1;
@@ -4213,12 +5001,12 @@ int Mirror(TransInfo *t, short mval[2])
 
 /* ************************** ALIGN *************************** */
 
-void initAlign(TransInfo *t) 
+void initAlign(TransInfo *t)
 {
        t->flag |= T_NO_CONSTRAINT;
-       
+
        t->transform = Align;
-       
+
        initMouseInputMode(t, &t->mouse, INPUT_NONE);
 }
 
@@ -4234,13 +5022,13 @@ int Align(TransInfo *t, short mval[2])
        for(i = 0 ; i < t->total; i++, td++)
        {
                float mat[3][3], invmat[3][3];
-               
+
                if (td->flag & TD_NOACTION)
                        break;
 
                if (td->flag & TD_SKIP)
                        continue;
-               
+
                /* around local centers */
                if (t->flag & (T_OBJECT|T_POSE)) {
                        VECCOPY(t->center, td->center);
@@ -4251,20 +5039,20 @@ int Align(TransInfo *t, short mval[2])
                        }
                }
 
-               Mat3Inv(invmat, td->axismtx);
-               
-               Mat3MulMat3(mat, t->spacemtx, invmat);  
+               invert_m3_m3(invmat, td->axismtx);
+
+               mul_m3_m3m3(mat, t->spacemtx, invmat);
 
                ElementRotation(t, td, mat, t->around);
        }
 
        /* restoring original center */
        VECCOPY(t->center, center);
-               
+
        recalcData(t);
 
        ED_area_headerprint(t->sa, "Align");
-       
+
        return 1;
 }
 
@@ -4273,37 +5061,37 @@ int Align(TransInfo *t, short mval[2])
 /* ---------------- Special Helpers for Various Settings ------------- */
 
 
-/* This function returns the snapping 'mode' for Animation Editors only 
+/* This function returns the snapping 'mode' for Animation Editors only
  * We cannot use the standard snapping due to NLA-strip scaling complexities.
  */
 // XXX these modifier checks should be keymappable
 static short getAnimEdit_SnapMode(TransInfo *t)
 {
        short autosnap= SACTSNAP_OFF;
-       
+
        /* currently, some of these are only for the action editor */
        if (t->spacetype == SPACE_ACTION) {
                SpaceAction *saction= (SpaceAction *)t->sa->spacedata.first;
-               
+
                if (saction)
                        autosnap= saction->autosnap;
        }
        else if (t->spacetype == SPACE_IPO) {
                SpaceIpo *sipo= (SpaceIpo *)t->sa->spacedata.first;
-               
+
                if (sipo)
                        autosnap= sipo->autosnap;
        }
        else if (t->spacetype == SPACE_NLA) {
                SpaceNla *snla= (SpaceNla *)t->sa->spacedata.first;
-               
+
                if (snla)
                        autosnap= snla->autosnap;
        }
        else {
                // TRANSFORM_FIX_ME This needs to use proper defines for t->modifiers
 //             // FIXME: this still toggles the modes...
-//             if (ctrl) 
+//             if (ctrl)
 //                     autosnap= SACTSNAP_STEP;
 //             else if (shift)
 //                     autosnap= SACTSNAP_FRAME;
@@ -4312,38 +5100,38 @@ static short getAnimEdit_SnapMode(TransInfo *t)
 //             else
                        autosnap= SACTSNAP_OFF;
        }
-       
+
        return autosnap;
 }
 
 /* This function is used for testing if an Animation Editor is displaying
  * its data in frames or seconds (and the data needing to be edited as such).
- * Returns 1 if in seconds, 0 if in frames 
+ * Returns 1 if in seconds, 0 if in frames
  */
 static short getAnimEdit_DrawTime(TransInfo *t)
 {
        short drawtime;
-       
+
        /* currently, some of these are only for the action editor */
        if (t->spacetype == SPACE_ACTION) {
                SpaceAction *saction= (SpaceAction *)t->sa->spacedata.first;
-               
+
                drawtime = (saction->flag & SACTION_DRAWTIME)? 1 : 0;
        }
        else if (t->spacetype == SPACE_NLA) {
                SpaceNla *snla= (SpaceNla *)t->sa->spacedata.first;
-               
+
                drawtime = (snla->flag & SNLA_DRAWTIME)? 1 : 0;
        }
        else {
                drawtime = 0;
        }
-       
+
        return drawtime;
-}      
+}
 
 
-/* This function is used by Animation Editor specific transform functions to do 
+/* This function is used by Animation Editor specific transform functions to do
  * the Snap Keyframe to Nearest Frame/Marker
  */
 static void doAnimEdit_SnapFrame(TransInfo *t, TransData *td, AnimData *adt, short autosnap)
@@ -4354,19 +5142,19 @@ static void doAnimEdit_SnapFrame(TransInfo *t, TransData *td, AnimData *adt, sho
                const short doTime= getAnimEdit_DrawTime(t);
                const double secf= FPS;
                double val;
-               
+
                /* convert frame to nla-action time (if needed) */
-               if (adt) 
+               if (adt)
                        val= BKE_nla_tweakedit_remap(adt, *(td->val), NLATIME_CONVERT_MAP);
                else
                        val= *(td->val);
-               
+
                /* do the snapping to nearest frame/second */
                if (doTime)
                        val= (float)( floor((val/secf) + 0.5f) * secf );
                else
                        val= (float)( floor(val+0.5f) );
-                       
+
                /* convert frame out of nla-action time */
                if (adt)
                        *(td->val)= BKE_nla_tweakedit_remap(adt, val, NLATIME_CONVERT_UNMAP);
@@ -4376,17 +5164,17 @@ static void doAnimEdit_SnapFrame(TransInfo *t, TransData *td, AnimData *adt, sho
        /* snap key to nearest marker? */
        else if (autosnap == SACTSNAP_MARKER) {
                float val;
-               
+
                /* convert frame to nla-action time (if needed) */
-               if (adt) 
+               if (adt)
                        val= BKE_nla_tweakedit_remap(adt, *(td->val), NLATIME_CONVERT_MAP);
                else
                        val= *(td->val);
-               
+
                /* snap to nearest marker */
                // TODO: need some more careful checks for where data comes from
                val= (float)ED_markers_find_nearest_marker_time(&t->scene->markers, val);
-               
+
                /* convert frame out of nla-action time */
                if (adt)
                        *(td->val)= BKE_nla_tweakedit_remap(adt, val, NLATIME_CONVERT_UNMAP);
@@ -4397,27 +5185,27 @@ static void doAnimEdit_SnapFrame(TransInfo *t, TransData *td, AnimData *adt, sho
 
 /* ----------------- Translation ----------------------- */
 
-void initTimeTranslate(TransInfo *t) 
+void initTimeTranslate(TransInfo *t)
 {
        t->mode = TFM_TIME_TRANSLATE;
        t->transform = TimeTranslate;
-       
+
        initMouseInputMode(t, &t->mouse, INPUT_NONE);
 
        /* num-input has max of (n-1) */
        t->idx_max = 0;
        t->num.flag = 0;
        t->num.idx_max = t->idx_max;
-       
+
        /* initialise snap like for everything else */
-       t->snap[0] = 0.0f; 
+       t->snap[0] = 0.0f;
        t->snap[1] = t->snap[2] = 1.0f;
 }
 
-static void headerTimeTranslate(TransInfo *t, char *str) 
+static void headerTimeTranslate(TransInfo *t, char *str)
 {
        char tvec[60];
-       
+
        /* if numeric input is active, use results from that, otherwise apply snapping to result */
        if (hasNumInput(&t->num)) {
                outputNumInput(&(t->num), tvec);
@@ -4428,7 +5216,7 @@ static void headerTimeTranslate(TransInfo *t, char *str)
                const short doTime = getAnimEdit_DrawTime(t);
                const double secf= FPS;
                float val = t->values[0];
-               
+
                /* apply snapping + frame->seconds conversions */
                if (autosnap == SACTSNAP_STEP) {
                        if (doTime)
@@ -4440,86 +5228,86 @@ static void headerTimeTranslate(TransInfo *t, char *str)
                        if (doTime)
                                val= val / secf;
                }
-               
+
                sprintf(&tvec[0], "%.4f", val);
        }
-               
+
        sprintf(str, "DeltaX: %s", &tvec[0]);
 }
 
-static void applyTimeTranslate(TransInfo *t, float sval) 
+static void applyTimeTranslate(TransInfo *t, float sval)
 {
        TransData *td = t->data;
        Scene *scene = t->scene;
        int i;
-       
+
        const short doTime= getAnimEdit_DrawTime(t);
        const double secf= FPS;
-       
+
        const short autosnap= getAnimEdit_SnapMode(t);
-       
+
        float deltax, val;
-       
+
        /* it doesn't matter whether we apply to t->data or t->data2d, but t->data2d is more convenient */
        for (i = 0 ; i < t->total; i++, td++) {
                /* it is assumed that td->extra is a pointer to the AnimData,
-                * whose active action is where this keyframe comes from 
+                * whose active action is where this keyframe comes from
                 * (this is only valid when not in NLA)
                 */
                AnimData *adt= (t->spacetype != SPACE_NLA) ? td->extra : NULL;
-               
+
                /* check if any need to apply nla-mapping */
                if (adt) {
                        deltax = t->values[0];
-                       
+
                        if (autosnap == SACTSNAP_STEP) {
-                               if (doTime) 
+                               if (doTime)
                                        deltax= (float)( floor((deltax/secf) + 0.5f) * secf );
                                else
                                        deltax= (float)( floor(deltax + 0.5f) );
                        }
-                       
+
                        val = BKE_nla_tweakedit_remap(adt, td->ival, NLATIME_CONVERT_MAP);
                        val += deltax;
                        *(td->val) = BKE_nla_tweakedit_remap(adt, val, NLATIME_CONVERT_UNMAP);
                }
                else {
                        deltax = val = t->values[0];
-                       
+
                        if (autosnap == SACTSNAP_STEP) {
                                if (doTime)
                                        val= (float)( floor((deltax/secf) + 0.5f) * secf );
                                else
                                        val= (float)( floor(val + 0.5f) );
                        }
-                       
+
                        *(td->val) = td->ival + val;
                }
-               
+
                /* apply nearest snapping */
                doAnimEdit_SnapFrame(t, td, adt, autosnap);
        }
 }
 
-int TimeTranslate(TransInfo *t, short mval[2]) 
+int TimeTranslate(TransInfo *t, short mval[2])
 {
        View2D *v2d = (View2D *)t->view;
        float cval[2], sval[2];
        char str[200];
-       
+
        /* calculate translation amount from mouse movement - in 'time-grid space' */
        UI_view2d_region_to_view(v2d, mval[0], mval[0], &cval[0], &cval[1]);
        UI_view2d_region_to_view(v2d, t->imval[0], t->imval[0], &sval[0], &sval[1]);
-       
+
        /* we only need to calculate effect for time (applyTimeTranslate only needs that) */
        t->values[0] = cval[0] - sval[0];
-       
+
        /* handle numeric-input stuff */
        t->vec[0] = t->values[0];
        applyNumInput(&t->num, &t->vec[0]);
        t->values[0] = t->vec[0];
        headerTimeTranslate(t, str);
-       
+
        applyTimeTranslate(t, sval[0]);
 
        recalcData(t);
@@ -4531,36 +5319,36 @@ int TimeTranslate(TransInfo *t, short mval[2])
 
 /* ----------------- Time Slide ----------------------- */
 
-void initTimeSlide(TransInfo *t) 
+void initTimeSlide(TransInfo *t)
 {
        /* this tool is only really available in the Action Editor... */
        if (t->spacetype == SPACE_ACTION) {
                SpaceAction *saction= (SpaceAction *)t->sa->spacedata.first;
-               
+
                /* set flag for drawing stuff */
                saction->flag |= SACTION_MOVING;
        }
-       
+
        t->mode = TFM_TIME_SLIDE;
        t->transform = TimeSlide;
        t->flag |= T_FREE_CUSTOMDATA;
-       
+
        initMouseInputMode(t, &t->mouse, INPUT_NONE);
 
        /* num-input has max of (n-1) */
        t->idx_max = 0;
        t->num.flag = 0;
        t->num.idx_max = t->idx_max;
-       
+
        /* initialise snap like for everything else */
-       t->snap[0] = 0.0f; 
+       t->snap[0] = 0.0f;
        t->snap[1] = t->snap[2] = 1.0f;
 }
 
-static void headerTimeSlide(TransInfo *t, float sval, char *str) 
+static void headerTimeSlide(TransInfo *t, float sval, char *str)
 {
        char tvec[60];
-       
+
        if (hasNumInput(&t->num)) {
                outputNumInput(&(t->num), tvec);
        }
@@ -4569,50 +5357,50 @@ static void headerTimeSlide(TransInfo *t, float sval, char *str)
                float maxx= *((float *)(t->customData) + 1);
                float cval= t->values[0];
                float val;
-                       
+
                val= 2.0f*(cval-sval) / (maxx-minx);
                CLAMP(val, -1.0f, 1.0f);
-               
+
                sprintf(&tvec[0], "%.4f", val);
        }
-               
+
        sprintf(str, "TimeSlide: %s", &tvec[0]);
 }
 
-static void applyTimeSlide(TransInfo *t, float sval) 
+static void applyTimeSlide(TransInfo *t, float sval)
 {
        TransData *td = t->data;
        int i;
-       
+
        float minx= *((float *)(t->customData));
        float maxx= *((float *)(t->customData) + 1);
-       
+
        /* set value for drawing black line */
        if (t->spacetype == SPACE_ACTION) {
                SpaceAction *saction= (SpaceAction *)t->sa->spacedata.first;
                float cvalf = t->values[0];
-               
+
                saction->timeslide= cvalf;
        }
-       
+
        /* it doesn't matter whether we apply to t->data or t->data2d, but t->data2d is more convenient */
        for (i = 0 ; i < t->total; i++, td++) {
                /* it is assumed that td->extra is a pointer to the AnimData,
-                * whose active action is where this keyframe comes from 
+                * whose active action is where this keyframe comes from
                 * (this is only valid when not in NLA)
                 */
                AnimData *adt= (t->spacetype != SPACE_NLA) ? td->extra : NULL;
                float cval = t->values[0];
-               
+
                /* apply NLA-mapping to necessary values */
                if (adt)
                        cval= BKE_nla_tweakedit_remap(adt, cval, NLATIME_CONVERT_UNMAP);
-               
+
                /* only apply to data if in range */
                if ((sval > minx) && (sval < maxx)) {
                        float cvalc= CLAMPIS(cval, minx, maxx);
                        float timefac;
-                       
+
                        /* left half? */
                        if (td->ival < sval) {
                                timefac= (sval - td->ival) / (sval - minx);
@@ -4626,26 +5414,26 @@ static void applyTimeSlide(TransInfo *t, float sval)
        }
 }
 
-int TimeSlide(TransInfo *t, short mval[2]) 
+int TimeSlide(TransInfo *t, short mval[2])
 {
        View2D *v2d = (View2D *)t->view;
        float cval[2], sval[2];
        float minx= *((float *)(t->customData));
        float maxx= *((float *)(t->customData) + 1);
        char str[200];
-       
+
        /* calculate mouse co-ordinates */
        UI_view2d_region_to_view(v2d, mval[0], mval[0], &cval[0], &cval[1]);
        UI_view2d_region_to_view(v2d, t->imval[0], t->imval[0], &sval[0], &sval[1]);
-       
+
        /* t->values[0] stores cval[0], which is the current mouse-pointer location (in frames) */
        t->values[0] = cval[0];
-       
+
        /* handle numeric-input stuff */
        t->vec[0] = 2.0f*(cval[0]-sval[0]) / (maxx-minx);
        applyNumInput(&t->num, &t->vec[0]);
        t->values[0] = (maxx-minx) * t->vec[0] / 2.0 + sval[0];
-       
+
        headerTimeSlide(t, sval[0], str);
        applyTimeSlide(t, sval[0]);
 
@@ -4658,35 +5446,35 @@ int TimeSlide(TransInfo *t, short mval[2])
 
 /* ----------------- Scaling ----------------------- */
 
-void initTimeScale(TransInfo *t) 
+void initTimeScale(TransInfo *t)
 {
        t->mode = TFM_TIME_SCALE;
        t->transform = TimeScale;
-       
+
        initMouseInputMode(t, &t->mouse, INPUT_NONE);
        t->helpline = HLP_SPRING; /* set manually because we don't use a predefined input */
 
        t->flag |= T_NULL_ONE;
        t->num.flag |= NUM_NULL_ONE;
-       
+
        /* num-input has max of (n-1) */
        t->idx_max = 0;
        t->num.flag = 0;
        t->num.idx_max = t->idx_max;
-       
+
        /* initialise snap like for everything else */
-       t->snap[0] = 0.0f; 
+       t->snap[0] = 0.0f;
        t->snap[1] = t->snap[2] = 1.0f;
 }
 
 static void headerTimeScale(TransInfo *t, char *str) {
        char tvec[60];
-       
+
        if (hasNumInput(&t->num))
                outputNumInput(&(t->num), tvec);
        else
                sprintf(&tvec[0], "%.4f", t->values[0]);
-               
+
        sprintf(str, "ScaleX: %s", &tvec[0]);
 }
 
@@ -4694,63 +5482,63 @@ static void applyTimeScale(TransInfo *t) {
        Scene *scene = t->scene;
        TransData *td = t->data;
        int i;
-       
+
        const short autosnap= getAnimEdit_SnapMode(t);
        const short doTime= getAnimEdit_DrawTime(t);
        const double secf= FPS;
-       
-       
+
+
        for (i = 0 ; i < t->total; i++, td++) {
                /* it is assumed that td->extra is a pointer to the AnimData,
-                * whose active action is where this keyframe comes from 
+                * whose active action is where this keyframe comes from
                 * (this is only valid when not in NLA)
                 */
                AnimData *adt= (t->spacetype != SPACE_NLA) ? td->extra : NULL;
                float startx= CFRA;
                float fac= t->values[0];
-               
+
                if (autosnap == SACTSNAP_STEP) {
                        if (doTime)
                                fac= (float)( floor(fac/secf + 0.5f) * secf );
                        else
                                fac= (float)( floor(fac + 0.5f) );
                }
-               
+
                /* check if any need to apply nla-mapping */
                if (adt)
                        startx= BKE_nla_tweakedit_remap(adt, startx, NLATIME_CONVERT_UNMAP);
-                       
+
                /* now, calculate the new value */
                *(td->val) = td->ival - startx;
                *(td->val) *= fac;
                *(td->val) += startx;
-               
+
                /* apply nearest snapping */
                doAnimEdit_SnapFrame(t, td, adt, autosnap);
        }
 }
 
-int TimeScale(TransInfo *t, short mval[2]) 
+int TimeScale(TransInfo *t, short mval[2])
 {
        float cval, sval;
        float deltax, startx;
        float width= 0.0f;
        char str[200];
-       
+
        sval= t->imval[0];
        cval= mval[0];
-       
+
        /* calculate scaling factor */
        startx= sval-(width/2+(t->ar->winx)/2);
        deltax= cval-(width/2+(t->ar->winx)/2);
        t->values[0] = deltax / startx;
-       
+
        /* handle numeric-input stuff */
        t->vec[0] = t->values[0];
        applyNumInput(&t->num, &t->vec[0]);
        t->values[0] = t->vec[0];
        headerTimeScale(t, str);
-       
+
        applyTimeScale(t);
 
        recalcData(t);
@@ -4789,7 +5577,7 @@ void NDofTransform()
                        maxval = val;
                }
        }
-       
+
        switch(axis)
        {
                case -1:
@@ -4810,7 +5598,7 @@ void NDofTransform()
                default:
                        printf("ndof: what we are doing here ?");
        }
-       
+
        if (mode != 0)
        {
                initTransform(mode, CTX_NDOF);