2.5 / Nodes / Transformations
[blender.git] / source / blender / editors / transform / transform_conversions.c
index cfc9a61e32c253fcd7a2431ca96c98595f6870fd..6b9c635779f1c3a38157ca0d2fd59e72e18eee81 100644 (file)
  * ***** END GPL LICENSE BLOCK *****
  */
 
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
 #ifndef WIN32
 #include <unistd.h>
 #else
@@ -56,6 +52,7 @@
 #include "DNA_meta_types.h"
 #include "DNA_modifier_types.h"
 #include "DNA_nla_types.h"
+#include "DNA_node_types.h"
 #include "DNA_object_types.h"
 #include "DNA_object_force.h"
 #include "DNA_particle_types.h"
 //#include "BIF_toolbox.h"
 
 #include "ED_types.h"
+#include "ED_anim_api.h"
+#include "ED_keyframing.h"
+#include "ED_keyframes_edit.h"
 #include "ED_view3d.h"
+#include "ED_mesh.h"
+
+#include "UI_view2d.h"
 
 //#include "BSE_drawipo.h"
 //#include "BSE_edit.h"
@@ -157,8 +160,6 @@ void transform_aspect_ratio_tface_uv(float *a1, float *a2) {}
 
 /* local function prototype - for Object/Bone Constraints */
 static short constraints_list_needinv(TransInfo *t, ListBase *list);
-/* local function prototype - for finding number of keyframes that are selected for editing */
-static int count_ipo_keys(Ipo *ipo, char side, float cfra);
 
 /* ************************** Functions *************************** */
 
@@ -340,7 +341,6 @@ static void createTransTexspace(bContext *C, TransInfo *t)
 static void createTransEdge(bContext *C, TransInfo *t) {
 #if 0  // TRANSFORM_FIX_ME
        TransData *td = NULL;
-       EditMesh *em = G.editMesh;
        EditEdge *eed;
        float mtx[3][3], smtx[3][3];
        int count=0, countsel=0;
@@ -365,7 +365,7 @@ static void createTransEdge(bContext *C, TransInfo *t) {
 
        td= t->data= MEM_callocN(t->total * sizeof(TransData), "TransCrease");
 
-       Mat3CpyMat4(mtx, G.obedit->obmat);
+       Mat3CpyMat4(mtx, t->obedit->obmat);
        Mat3Inv(smtx, mtx);
 
        for(eed= em->edges.first; eed; eed= eed->next) {
@@ -1023,7 +1023,7 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t)
        // TRANSFORM_FIX_ME
 #if 0
        EditBone *ebo;
-       bArmature *arm= G.obedit->data;
+       bArmature *arm= t->obedit->data;
        TransData *td;
        float mtx[3][3], smtx[3][3], delta[3], bonemat[3][3];
 
@@ -1049,7 +1049,7 @@ static void createTransArmatureVerts(bContext *C, TransInfo *t)
 
     if (!t->total) return;
        
-       Mat3CpyMat4(mtx, G.obedit->obmat);
+       Mat3CpyMat4(mtx, t->obedit->obmat);
        Mat3Inv(smtx, mtx);
 
     td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransEditBone");
@@ -1221,7 +1221,7 @@ static void createTransMBallVerts(bContext *C, TransInfo *t)
        td = t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(MBall EditMode)");
        tx = t->ext = MEM_callocN(t->total*sizeof(TransDataExtension), "MetaElement_TransExtension");
 
-       Mat3CpyMat4(mtx, G.obedit->obmat);
+       Mat3CpyMat4(mtx, t->obedit->obmat);
        Mat3Inv(smtx, mtx);
     
        for(ml= editelems.first; ml; ml= ml->next) {
@@ -1372,7 +1372,7 @@ static void createTransCurveVerts(bContext *C, TransInfo *t)
        else t->total = countsel;
        t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(Curve EditMode)");
 
-       Mat3CpyMat4(mtx, G.obedit->obmat);
+       Mat3CpyMat4(mtx, t->obedit->obmat);
        Mat3Inv(smtx, mtx);
        
     td = t->data;
@@ -1560,7 +1560,7 @@ static void createTransLatticeVerts(bContext *C, TransInfo *t)
        else t->total = countsel;
        t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(Lattice EditMode)");
        
-       Mat3CpyMat4(mtx, G.obedit->obmat);
+       Mat3CpyMat4(mtx, t->obedit->obmat);
        Mat3Inv(smtx, mtx);
 
        td = t->data;
@@ -1756,9 +1756,8 @@ void flushTransParticles(TransInfo *t)
 #define E_VEC(a)       (vectors + (3 * (a)->tmp.l))
 #define E_NEAR(a)      (nears[((a)->tmp.l)])
 #define THRESHOLD      0.0001f
-static void editmesh_set_connectivity_distance(int total, float *vectors, EditVert **nears)
+static void editmesh_set_connectivity_distance(EditMesh *em, int total, float *vectors, EditVert **nears)
 {
-       EditMesh *em = G.editMesh;
        EditVert *eve;
        EditEdge *eed;
        int i= 0, done= 1;
@@ -1869,9 +1868,8 @@ static void editmesh_set_connectivity_distance(int total, float *vectors, EditVe
 }
 
 /* loop-in-a-loop I know, but we need it! (ton) */
-static void get_face_center(float *cent, EditVert *eve)
+static void get_face_center(float *cent, EditMesh *em, EditVert *eve)
 {
-       EditMesh *em = G.editMesh;
        EditFace *efa;
        
        for(efa= em->faces.first; efa; efa= efa->next)
@@ -1885,7 +1883,7 @@ static void get_face_center(float *cent, EditVert *eve)
 
 //way to overwrite what data is edited with transform
 //static void VertsToTransData(TransData *td, EditVert *eve, BakeKey *key)
-static void VertsToTransData(TransData *td, EditVert *eve)
+static void VertsToTransData(TransInfo *t, TransData *td, EditMesh *em, EditVert *eve)
 {
        td->flag = 0;
        //if(key)
@@ -1894,9 +1892,8 @@ static void VertsToTransData(TransData *td, EditVert *eve)
        td->loc = eve->co;
        
        VECCOPY(td->center, td->loc);
-// TRANSFORM_FIX_ME    
-//     if(G.vd->around==V3D_LOCAL && (G.scene->selectmode & SCE_SELECT_FACE))
-//             get_face_center(td->center, eve);
+       if(t->around==V3D_LOCAL && (em->selectmode & SCE_SELECT_FACE))
+               get_face_center(td->center, em, eve);
        VECCOPY(td->iloc, td->loc);
 
        // Setting normals
@@ -1912,7 +1909,7 @@ static void VertsToTransData(TransData *td, EditVert *eve)
        td->tdi = NULL;
        td->val = NULL;
        td->extra = NULL;
-       if (BIF_GetTransInfo()->mode == TFM_BWEIGHT) {
+       if (t->mode == TFM_BWEIGHT) {
                td->val = &(eve->bweight);
                td->ival = eve->bweight;
        }
@@ -1953,19 +1950,20 @@ static int modifiers_disable_subsurf_temporary(Object *ob)
 }
 
 /* disable subsurf temporal, get mapped cos, and enable it */
-static float *get_crazy_mapped_editverts(void)
+static float *get_crazy_mapped_editverts(TransInfo *t)
 {
+       Mesh *me= t->obedit->data;
        DerivedMesh *dm;
        float *vertexcos;
 
        /* disable subsurf temporal, get mapped cos, and enable it */
-       if(modifiers_disable_subsurf_temporary(G.obedit)) {
+       if(modifiers_disable_subsurf_temporary(t->obedit)) {
                /* need to make new derivemesh */
-               makeDerivedMesh(G.obedit, CD_MASK_BAREMESH);
+               makeDerivedMesh(t->obedit, me->edit_mesh, CD_MASK_BAREMESH);
        }
 
        /* now get the cage */
-       dm= editmesh_get_derived_cage(CD_MASK_BAREMESH);
+       dm= editmesh_get_derived_cage(t->obedit, me->edit_mesh, CD_MASK_BAREMESH);
 
        vertexcos= MEM_mallocN(3*sizeof(float)*G.totvert, "vertexcos map");
        dm->foreachMappedVert(dm, make_vertexcos__mapFunc, vertexcos);
@@ -1973,7 +1971,7 @@ static float *get_crazy_mapped_editverts(void)
        dm->release(dm);
        
        /* set back the flag, no new cage needs to be built, transform does it */
-       modifiers_disable_subsurf_temporary(G.obedit);
+       modifiers_disable_subsurf_temporary(t->obedit);
        
        return vertexcos;
 }
@@ -1996,9 +1994,8 @@ static void set_crazy_vertex_quat(float *quat, float *v1, float *v2, float *v3,
 }
 #undef TAN_MAKE_VEC
 
-static void set_crazyspace_quats(float *origcos, float *mappedcos, float *quats)
+static void set_crazyspace_quats(EditMesh *em, float *origcos, float *mappedcos, float *quats)
 {
-       EditMesh *em = G.editMesh;
        EditVert *eve, *prev;
        EditFace *efa;
        float *v1, *v2, *v3, *v4, *co1, *co2, *co3, *co4;
@@ -2095,10 +2092,9 @@ void createTransBMeshVerts(TransInfo *t, BME_Mesh *bm, BME_TransData_Head *td) {
 
 static void createTransEditVerts(bContext *C, TransInfo *t)
 {
-       // TRANSFORM_FIX_ME
-#if 0
+       Scene *scene = CTX_data_scene(C);
        TransData *tob = NULL;
-       EditMesh *em = G.editMesh;
+       EditMesh *em = ((Mesh *)t->obedit->data)->edit_mesh;
        EditVert *eve;
        EditVert **nears = NULL;
        EditVert *eve_act = NULL;
@@ -2108,13 +2104,13 @@ static void createTransEditVerts(bContext *C, TransInfo *t)
        int propmode = t->flag & T_PROP_EDIT;
        int mirror = 0;
        
-       if ((t->context & CTX_NO_MIRROR) == 0 && (G.scene->toolsettings->editbutflag & B_MESH_X_MIRROR))
+       if ((t->options & CTX_NO_MIRROR) == 0 && (scene->toolsettings->editbutflag & B_MESH_X_MIRROR))
        {
                mirror = 1;
        }
 
        // transform now requires awareness for select mode, so we tag the f1 flags in verts
-       if(G.scene->selectmode & SCE_SELECT_VERTEX) {
+       if(scene->selectmode & SCE_SELECT_VERTEX) {
                for(eve= em->verts.first; eve; eve= eve->next) {
                        if(eve->h==0 && (eve->f & SELECT)) 
                                eve->f1= SELECT;
@@ -2122,7 +2118,7 @@ static void createTransEditVerts(bContext *C, TransInfo *t)
                                eve->f1= 0;
                }
        }
-       else if(G.scene->selectmode & SCE_SELECT_EDGE) {
+       else if(scene->selectmode & SCE_SELECT_EDGE) {
                EditEdge *eed;
                for(eve= em->verts.first; eve; eve= eve->next) eve->f1= 0;
                for(eed= em->edges.first; eed; eed= eed->next) {
@@ -2153,8 +2149,8 @@ static void createTransEditVerts(bContext *C, TransInfo *t)
        if (countsel==0) return;
        
        /* check active */
-       if (G.editMesh->selected.last) {
-               EditSelection *ese = G.editMesh->selected.last;
+       if (em->selected.last) {
+               EditSelection *ese = em->selected.last;
                if ( ese->type == EDITVERT ) {
                        eve_act = (EditVert *)ese->data;
                }
@@ -2171,26 +2167,26 @@ static void createTransEditVerts(bContext *C, TransInfo *t)
        else t->total = countsel;
        tob= t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(Mesh EditMode)");
        
-       Mat3CpyMat4(mtx, G.obedit->obmat);
+       Mat3CpyMat4(mtx, t->obedit->obmat);
        Mat3Inv(smtx, mtx);
 
-       if(propmode) editmesh_set_connectivity_distance(t->total, vectors, nears);
+       if(propmode) editmesh_set_connectivity_distance(em, t->total, vectors, nears);
        
        /* detect CrazySpace [tm] */
        if(propmode==0) {
-               if(modifiers_getCageIndex(G.obedit, NULL)>=0) {
-                       if(modifiers_isDeformed(G.obedit)) {
+               if(modifiers_getCageIndex(t->obedit, NULL)>=0) {
+                       if(modifiers_isDeformed(t->obedit)) {
                                /* check if we can use deform matrices for modifier from the
                                   start up to stack, they are more accurate than quats */
-                               totleft= editmesh_get_first_deform_matrices(&defmats, &defcos);
+                               totleft= editmesh_get_first_deform_matrices(t->obedit, em, &defmats, &defcos);
 
                                /* if we still have more modifiers, also do crazyspace
                                   correction with quats, relative to the coordinates after
                                   the modifiers that support deform matrices (defcos) */
                                if(totleft > 0) {
-                                       mappedcos= get_crazy_mapped_editverts();
+                                       mappedcos= get_crazy_mapped_editverts(t);
                                        quats= MEM_mallocN( (t->total)*sizeof(float)*4, "crazy quats");
-                                       set_crazyspace_quats((float*)defcos, mappedcos, quats);
+                                       set_crazyspace_quats(em, (float*)defcos, mappedcos, quats);
                                        if(mappedcos)
                                                MEM_freeN(mappedcos);
                                }
@@ -2215,7 +2211,7 @@ static void createTransEditVerts(bContext *C, TransInfo *t)
        for (a=0, eve=em->verts.first; eve; eve=eve->next, a++) {
                if(eve->h==0) {
                        if(propmode || eve->f1) {
-                               VertsToTransData(tob, eve);
+                               VertsToTransData(t, tob, em, eve);
                                
                                /* selected */
                                if(eve->f1) tob->flag |= TD_SELECTED;
@@ -2265,7 +2261,7 @@ static void createTransEditVerts(bContext *C, TransInfo *t)
                                
                                /* Mirror? */
                                if( (mirror>0 && tob->iloc[0]>0.0f) || (mirror<0 && tob->iloc[0]<0.0f)) {
-                                       EditVert *vmir= editmesh_get_x_mirror_vert(G.obedit, tob->iloc);        /* initializes octree on first call */
+                                       EditVert *vmir= editmesh_get_x_mirror_vert(t->obedit, em, tob->iloc);   /* initializes octree on first call */
                                        if(vmir != eve) tob->extra = vmir;
                                }
                                tob++;
@@ -2281,7 +2277,19 @@ static void createTransEditVerts(bContext *C, TransInfo *t)
                MEM_freeN(quats);
        if(defmats)
                MEM_freeN(defmats);
-#endif
+}
+
+/* *** NODE EDITOR *** */
+void flushTransNodes(TransInfo *t)
+{
+       int a;
+       TransData2D *td;
+       
+       /* flush to 2d vector from internally used 3d vector */
+       for(a=0, td= t->data2d; a<t->total; a++, td++) {
+               td->loc2d[0]= td->loc[0];
+               td->loc2d[1]= td->loc[1];
+       }
 }
 
 /* ********************* UV ****************** */
@@ -2333,7 +2341,7 @@ static void createTransUVs(bContext *C, TransInfo *t)
        int propmode = t->flag & T_PROP_EDIT;
        int efa_s1,efa_s2,efa_s3,efa_s4;
 
-       EditMesh *em = G.editMesh;
+       EditMesh *em = ((Mesh *)t->obedit->data)->edit_mesh;
        EditFace *efa;
        
        if(is_uv_tface_editing_allowed()==0) return;
@@ -2467,7 +2475,7 @@ void flushTransUVs(TransInfo *t)
        TransData2D *td;
        int a, width, height;
        Object *ob= OBACT;
-       EditMesh *em = G.editMesh;
+       EditMesh *em = ((Mesh *)ob->data)->edit_mesh;
        float aspx, aspy, invx, invy;
 
        transform_aspect_ratio_tface_uv(&aspx, &aspy);
@@ -2570,6 +2578,8 @@ void flushTransIpoData(TransInfo *t)
        
        /* flush to 2d vector from internally used 3d vector */
        for (a=0, td= t->data2d; a<t->total; a++, td++) {
+               // FIXME: autosnap needs to be here...
+               
                /* we need to unapply the nla-scaling from the time in some situations */
                if (NLA_IPO_SCALED)
                        td->loc2d[0]= get_action_frame(OBACT, td->loc[0]);
@@ -2675,191 +2685,113 @@ static void posttrans_gpd_clean (bGPdata *gpd)
        }
 }
 
-/* Called by special_aftertrans_update to make sure selected keyframes replace
+/* Called during special_aftertrans_update to make sure selected keyframes replace
  * any other keyframes which may reside on that frame (that is not selected).
  */
-static void posttrans_ipo_clean (Ipo *ipo)
+static void posttrans_icu_clean (IpoCurve *icu)
 {
-#if 0 // TRANSFORM_FIX_ME
-       IpoCurve *icu;
-       int i;
+       float *selcache;        /* cache for frame numbers of selected frames (icu->totvert*sizeof(float)) */
+       int len, index, i;      /* number of frames in cache, item index */
        
-       /* delete any keyframes that occur on same frame as selected keyframe, but is not selected */
-       for (icu= ipo->curve.first; icu; icu= icu->next) {
-               float *selcache;        /* cache for frame numbers of selected frames (icu->totvert*sizeof(float)) */
-               int len, index;         /* number of frames in cache, item index */
-               
-               /* allocate memory for the cache */
-               // TODO: investigate using GHash for this instead?
-               if (icu->totvert == 0) 
-                       continue;
-               selcache= MEM_callocN(sizeof(float)*icu->totvert, "IcuSelFrameNums");
-               len= 0;
-               index= 0;
+       /* allocate memory for the cache */
+       // TODO: investigate using GHash for this instead?
+       if (icu->totvert == 0) 
+               return;
+       selcache= MEM_callocN(sizeof(float)*icu->totvert, "IcuSelFrameNums");
+       len= 0;
+       index= 0;
+       
+       /* We do 2 loops, 1 for marking keyframes for deletion, one for deleting 
+        * as there is no guarantee what order the keyframes are exactly, even though 
+        * they have been sorted by time.
+        */
+        
+       /*      Loop 1: find selected keyframes   */
+       for (i = 0; i < icu->totvert; i++) {
+               BezTriple *bezt= &icu->bezt[i];
                
-               /* We do 2 loops, 1 for marking keyframes for deletion, one for deleting 
-                * as there is no guarantee what order the keyframes are exactly, even though 
-                * they have been sorted by time.
-                */
-                
-               /*      Loop 1: find selected keyframes   */
+               if (BEZSELECTED(bezt)) {
+                       selcache[index]= bezt->vec[1][0];
+                       index++;
+                       len++;
+               }
+       }
+       
+       /* Loop 2: delete unselected keyframes on the same frames (if any keyframes were found) */
+       if (len) {
                for (i = 0; i < icu->totvert; i++) {
                        BezTriple *bezt= &icu->bezt[i];
                        
-                       if (BEZSELECTED(bezt)) {
-                               selcache[index]= bezt->vec[1][0];
-                               index++;
-                               len++;
-                       }
-               }
-               
-               /* Loop 2: delete unselected keyframes on the same frames (if any keyframes were found) */
-               if (len) {
-                       for (i = 0; i < icu->totvert; i++) {
-                               BezTriple *bezt= &icu->bezt[i];
-                               
-                               if (BEZSELECTED(bezt) == 0) {
-                                       /* check beztriple should be removed according to cache */
-                                       for (index= 0; index < len; index++) {
-                                               if (IS_EQ(bezt->vec[1][0], selcache[index])) {
-                                                       delete_icu_key(icu, i, 0);
-                                                       break;
-                                               }
-                                               else if (bezt->vec[1][0] > selcache[index])
-                                                       break;
+                       if (BEZSELECTED(bezt) == 0) {
+                               /* check beztriple should be removed according to cache */
+                               for (index= 0; index < len; index++) {
+                                       if (IS_EQ(bezt->vec[1][0], selcache[index])) {
+                                               delete_icu_key(icu, i, 0);
+                                               break;
                                        }
+                                       else if (bezt->vec[1][0] > selcache[index])
+                                               break;
                                }
                        }
-                       
-                       testhandles_ipocurve(icu);
                }
                
-               /* free cache */
-               MEM_freeN(selcache);
+               testhandles_ipocurve(icu);
        }
-#endif
+       
+       /* free cache */
+       MEM_freeN(selcache);
 }
 
 /* Called by special_aftertrans_update to make sure selected keyframes replace
  * any other keyframes which may reside on that frame (that is not selected).
  * remake_action_ipos should have already been called 
  */
-static void posttrans_action_clean (bAction *act)
+static void posttrans_ipo_clean (Ipo *ipo)
 {
-#if 0 // TRANSFORM_FIX_ME
-       ListBase act_data = {NULL, NULL};
-       bActListElem *ale;
-       int filter;
+       IpoCurve *icu;
        
-       /* filter data */
-       filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
-       actdata_filter(&act_data, filter, act, ACTCONT_ACTION);
+       if (ipo == NULL)
+               return;
        
-       /* loop through relevant data, removing keyframes from the ipo-blocks that were attached 
+       /* loop through relevant data, removing keyframes from the ipocurves
         *      - all keyframes are converted in/out of global time 
         */
-       for (ale= act_data.first; ale; ale= ale->next) {
-               if (NLA_ACTION_SCALED) {
-                       actstrip_map_ipo_keys(OBACT, ale->key_data, 0, 1); 
-                       posttrans_ipo_clean(ale->key_data);
-                       actstrip_map_ipo_keys(OBACT, ale->key_data, 1, 1);
-               }
-               else 
-                       posttrans_ipo_clean(ale->key_data);
+       for (icu= ipo->curve.first; icu; icu= icu->next) {
+               posttrans_icu_clean(icu);
        }
-       
-       /* free temp data */
-       BLI_freelistN(&act_data);
-#endif
 }
 
 /* Called by special_aftertrans_update to make sure selected keyframes replace
  * any other keyframes which may reside on that frame (that is not selected).
- * remake_all_ipos should have already been called 
+ * remake_action_ipos should have already been called 
  */
-static void posttrans_nla_clean (TransInfo *t)
+static void posttrans_action_clean (bAnimContext *ac, bAction *act)
 {
-#if 0 // TRANSFORM_FIX_ME
-       Base *base;
-       Object *ob;
-       bActionStrip *strip;
-       bActionChannel *achan;
-       bConstraintChannel *conchan;
-       float cfra;
-       char side;
-       int i;
+       ListBase anim_data = {NULL, NULL};
+       bAnimListElem *ale;
+       int filter;
        
-       /* which side of the current frame should be allowed */
-       if (t->mode == TFM_TIME_EXTEND) {
-               /* only side on which mouse is gets transformed */
-               float xmouse, ymouse;
-               
-               areamouseco_to_ipoco(G.v2d, t->imval, &xmouse, &ymouse);
-               side = (xmouse > CFRA) ? 'R' : 'L';
-       }
-       else {
-               /* normal transform - both sides of current frame are considered */
-               side = 'B';
-       }
+       /* filter data */
+       filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_ONLYICU);
+       ANIM_animdata_filter(&anim_data, filter, act, ANIMCONT_ACTION);
        
-       /* only affect keyframes */
-       for (base=G.scene->base.first; base; base=base->next) {
-               ob= base->object;
-               
-               /* Check object ipos */
-               i= count_ipo_keys(ob->ipo, side, (float)CFRA);
-               if (i) posttrans_ipo_clean(ob->ipo);
-               
-               /* Check object constraint ipos */
-               for (conchan=ob->constraintChannels.first; conchan; conchan=conchan->next) {
-                       i= count_ipo_keys(conchan->ipo, side, (float)CFRA);     
-                       if (i) posttrans_ipo_clean(conchan->ipo);
-               }
-               
-               /* skip actions and nlastrips if object is collapsed */
-               if (ob->nlaflag & OB_NLA_COLLAPSED)
-                       continue;
+       /* loop through relevant data, removing keyframes from the ipo-blocks that were attached 
+        *      - all keyframes are converted in/out of global time 
+        */
+       for (ale= anim_data.first; ale; ale= ale->next) {
+               Object *nob= ANIM_nla_mapping_get(ac, ale);
                
-               /* Check action ipos */
-               if (ob->action) {
-                       /* exclude if strip is selected too */
-                       for (strip=ob->nlastrips.first; strip; strip=strip->next) {
-                               if (strip->flag & ACTSTRIP_SELECT) {
-                                       if (strip->act == ob->action)
-                                               break;
-                               }
-                       }
-                       if (strip==NULL) {
-                               cfra = get_action_frame(ob, (float)CFRA);
-                               
-                               for (achan=ob->action->chanbase.first; achan; achan=achan->next) {
-                                       if (EDITABLE_ACHAN(achan)) {
-                                               i= count_ipo_keys(achan->ipo, side, cfra);
-                                               if (i) {
-                                                       actstrip_map_ipo_keys(ob, achan->ipo, 0, 1); 
-                                                       posttrans_ipo_clean(achan->ipo);
-                                                       actstrip_map_ipo_keys(ob, achan->ipo, 1, 1);
-                                               }
-                                               
-                                               /* Check action constraint ipos */
-                                               if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
-                                                       for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
-                                                               if (EDITABLE_CONCHAN(conchan)) {
-                                                                       i = count_ipo_keys(conchan->ipo, side, cfra);
-                                                                       if (i) {
-                                                                               actstrip_map_ipo_keys(ob, conchan->ipo, 0, 1); 
-                                                                               posttrans_ipo_clean(conchan->ipo);
-                                                                               actstrip_map_ipo_keys(ob, conchan->ipo, 1, 1);
-                                                                       }
-                                                               }
-                                                       }
-                                               }
-                                       }
-                               }
-                       }               
+               if (nob) {
+                       ANIM_nla_mapping_apply_ipocurve(nob, ale->key_data, 0, 1); 
+                       posttrans_icu_clean(ale->key_data);
+                       ANIM_nla_mapping_apply_ipocurve(nob, ale->key_data, 1, 1);
                }
+               else 
+                       posttrans_icu_clean(ale->key_data);
        }
-#endif
+       
+       /* free temp data */
+       BLI_freelistN(&anim_data);
 }
 
 /* ----------------------------- */
@@ -2878,27 +2810,24 @@ static short FrameOnMouseSide(char side, float frame, float cframe)
 }
 
 /* fully select selected beztriples, but only include if it's on the right side of cfra */
-static int count_ipo_keys(Ipo *ipo, char side, float cfra)
+static int count_icu_keys(IpoCurve *icu, char side, float cfra)
 {
-       IpoCurve *icu;
        BezTriple *bezt;
        int i, count = 0;
        
-       if (ipo == NULL)
+       if (icu == NULL)
                return count;
        
        /* only include points that occur on the right side of cfra */
-       for (icu= ipo->curve.first; icu; icu= icu->next) {
-               for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) {
-                       if (bezt->f2 & SELECT) {
-                               /* fully select the other two keys */
-                               bezt->f1 |= SELECT;
-                               bezt->f3 |= SELECT;
-                               
-                               /* increment by 3, as there are 3 points (3 * x-coordinates) that need transform */
-                               if (FrameOnMouseSide(side, bezt->vec[1][0], cfra))
-                                       count += 3;
-                       }
+       for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) {
+               if (bezt->f2 & SELECT) {
+                       /* fully select the other two keys */
+                       bezt->f1 |= SELECT;
+                       bezt->f3 |= SELECT;
+                       
+                       /* increment by 3, as there are 3 points (3 * x-coordinates) that need transform */
+                       if (FrameOnMouseSide(side, bezt->vec[1][0], cfra))
+                               count += 3;
                }
        }
        
@@ -2941,44 +2870,38 @@ static void TimeToTransData(TransData *td, float *time, Object *ob)
 
 /* This function advances the address to which td points to, so it must return
  * the new address so that the next time new transform data is added, it doesn't
- * overwrite the existing ones...  i.e.   td = IpoToTransData(td, ipo, ob, side, cfra);
+ * overwrite the existing ones...  i.e.   td = IcuToTransData(td, icu, ob, side, cfra);
  *
  * The 'side' argument is needed for the extend mode. 'B' = both sides, 'R'/'L' mean only data
  * on the named side are used. 
  */
-static TransData *IpoToTransData(TransData *td, Ipo *ipo, Object *ob, char side, float cfra)
+static TransData *IcuToTransData(TransData *td, IpoCurve *icu, Object *ob, char side, float cfra)
 {
-#if 0 // TRANSFORM_FIX_ME      
-       IpoCurve *icu;
        BezTriple *bezt;
        int i;
        
-       if (ipo == NULL)
+       if (icu == NULL)
                return td;
-       
-       for (icu= ipo->curve.first; icu; icu= icu->next) {
-               for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) {
-                       /* only add selected keyframes (for now, proportional edit is not enabled) */
-                       if (BEZSELECTED(bezt)) {
-                               /* only add if on the right 'side' of the current frame */
-                               if (FrameOnMouseSide(side, bezt->vec[1][0], cfra)) {
-                                       /* each control point needs to be added separetely */
-                                       TimeToTransData(td, bezt->vec[0], ob);
-                                       td++;
-                                       
-                                       TimeToTransData(td, bezt->vec[1], ob);
-                                       td++;
-                                       
-                                       TimeToTransData(td, bezt->vec[2], ob);
-                                       td++;
-                               }
-                       }       
-               }
+               
+       for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) {
+               /* only add selected keyframes (for now, proportional edit is not enabled) */
+               if (BEZSELECTED(bezt)) {
+                       /* only add if on the right 'side' of the current frame */
+                       if (FrameOnMouseSide(side, bezt->vec[1][0], cfra)) {
+                               /* each control point needs to be added separetely */
+                               TimeToTransData(td, bezt->vec[0], ob);
+                               td++;
+                               
+                               TimeToTransData(td, bezt->vec[1], ob);
+                               td++;
+                               
+                               TimeToTransData(td, bezt->vec[2], ob);
+                               td++;
+                       }
+               }       
        }
        
        return td;
-#endif
-return NULL;
 }
 
 /* helper struct for gp-frame transforms (only used here) */
@@ -3041,16 +2964,13 @@ static int GPLayerToTransData (TransData *td, tGPFtransdata *tfd, bGPDlayer *gpl
 
 static void createTransActionData(bContext *C, TransInfo *t)
 {
-       // TRANSFORM_FIX_ME
-#if 0
+       Scene *scene= CTX_data_scene(C);
        TransData *td = NULL;
        tGPFtransdata *tfd = NULL;
-       Object *ob= NULL;
        
-       ListBase act_data = {NULL, NULL};
-       bActListElem *ale;
-       void *data;
-       short datatype;
+       bAnimContext ac;
+       ListBase anim_data = {NULL, NULL};
+       bAnimListElem *ale;
        int filter;
        
        int count=0;
@@ -3058,26 +2978,22 @@ static void createTransActionData(bContext *C, TransInfo *t)
        char side;
        
        /* determine what type of data we are operating on */
-       data = get_action_context(&datatype);
-       if (data == NULL) return;
+       if (ANIM_animdata_get_context(C, &ac) == 0)
+               return;
        
        /* filter data */
-       if (datatype == ACTCONT_GPENCIL)
-               filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT);
+       if (ac.datatype == ANIMCONT_GPENCIL)
+               filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT);
        else
-               filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
-       actdata_filter(&act_data, filter, data, datatype);
-       
-       /* is the action scaled? if so, the it should belong to the active object */
-       if (NLA_ACTION_SCALED)
-               ob= OBACT;
+               filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_ONLYICU);
+       ANIM_animdata_filter(&anim_data, filter, ac.data, ac.datatype);
                
        /* which side of the current frame should be allowed */
        if (t->mode == TFM_TIME_EXTEND) {
                /* only side on which mouse is gets transformed */
                float xmouse, ymouse;
                
-               areamouseco_to_ipoco(G.v2d, t->imval, &xmouse, &ymouse);
+               UI_view2d_region_to_view(&ac.ar->v2d, t->imval[0], t->imval[1], &xmouse, &ymouse);
                side = (xmouse > CFRA) ? 'R' : 'L';
        }
        else {
@@ -3085,26 +3001,28 @@ static void createTransActionData(bContext *C, TransInfo *t)
                side = 'B';
        }
        
-       /* convert current-frame to action-time (slightly less accurate, espcially under
-        * higher scaling ratios, but is faster than converting all points) 
-        */
-       if (ob) 
-               cfra = get_action_frame(ob, (float)CFRA);
-       else
-               cfra = (float)CFRA;
-       
        /* loop 1: fully select ipo-keys and count how many BezTriples are selected */
-       for (ale= act_data.first; ale; ale= ale->next) {
-               if (ale->type == ACTTYPE_GPLAYER)
-                       count += count_gplayer_frames(ale->data, side, cfra);
+       for (ale= anim_data.first; ale; ale= ale->next) {
+               Object *nob= ANIM_nla_mapping_get(&ac, ale);
+               
+               /* convert current-frame to action-time (slightly less accurate, espcially under
+                * higher scaling ratios, but is faster than converting all points) 
+                */
+               if (nob) 
+                       cfra = get_action_frame(nob, (float)CFRA);
                else
-                       count += count_ipo_keys(ale->key_data, side, cfra);
+                       cfra = (float)CFRA;
+               
+               //if (ale->type == ANIMTYPE_GPLAYER)
+               //      count += count_gplayer_frames(ale->data, side, cfra);
+               //else
+                       count += count_icu_keys(ale->key_data, side, cfra);
        }
        
        /* stop if trying to build list if nothing selected */
        if (count == 0) {
                /* cleanup temp list */
-               BLI_freelistN(&act_data);
+               BLI_freelistN(&anim_data);
                return;
        }
        
@@ -3114,7 +3032,7 @@ static void createTransActionData(bContext *C, TransInfo *t)
        t->data= MEM_callocN(t->total*sizeof(TransData), "TransData(Action Editor)");
        td= t->data;
        
-       if (datatype == ACTCONT_GPENCIL) {
+       if (ac.datatype == ANIMCONT_GPENCIL) {
                if (t->mode == TFM_TIME_SLIDE) {
                        t->customData= MEM_callocN((sizeof(float)*2)+(sizeof(tGPFtransdata)*count), "TimeSlide + tGPFtransdata");
                        tfd= (tGPFtransdata *)( (float *)(t->customData) + 2 );
@@ -3128,20 +3046,29 @@ static void createTransActionData(bContext *C, TransInfo *t)
                t->customData= MEM_callocN(sizeof(float)*2, "TimeSlide Min/Max");
        
        /* loop 2: build transdata array */
-       for (ale= act_data.first; ale; ale= ale->next) {
-               if (ale->type == ACTTYPE_GPLAYER) {
-                       bGPDlayer *gpl= (bGPDlayer *)ale->data;
-                       int i;
+       for (ale= anim_data.first; ale; ale= ale->next) {
+               //if (ale->type == ANIMTYPE_GPLAYER) {
+               //      bGPDlayer *gpl= (bGPDlayer *)ale->data;
+               //      int i;
+               //      
+               //      i = GPLayerToTransData(td, tfd, gpl, side, cfra);
+               //      td += i;
+               //      tfd += i;
+               //}
+               //else {
+                       Object *nob= ANIM_nla_mapping_get(&ac, ale);
+                       IpoCurve *icu= (IpoCurve *)ale->key_data;
                        
-                       i = GPLayerToTransData(td, tfd, gpl, side, cfra);
-                       td += i;
-                       tfd += i;
-               }
-               else {
-                       Ipo *ipo= (Ipo *)ale->key_data;
+                       /* convert current-frame to action-time (slightly less accurate, espcially under
+                        * higher scaling ratios, but is faster than converting all points) 
+                        */
+                       if (nob) 
+                               cfra = get_action_frame(nob, (float)CFRA);
+                       else
+                               cfra = (float)CFRA;
                        
-                       td= IpoToTransData(td, ipo, ob, side, cfra);
-               }
+                       td= IcuToTransData(td, icu, nob, side, cfra);
+               //}
        }
        
        /* check if we're supposed to be setting minx/maxx for TimeSlide */
@@ -3164,166 +3091,9 @@ static void createTransActionData(bContext *C, TransInfo *t)
        }
        
        /* cleanup temp list */
-       BLI_freelistN(&act_data);
-#endif
+       BLI_freelistN(&anim_data);
 }
 
-static void createTransNlaData(bContext *C, TransInfo *t)
-{
-       // TRANSFORM_FIX_ME
-#if 0
-       Base *base;
-       bActionStrip *strip;
-       bActionChannel *achan;
-       bConstraintChannel *conchan;
-       
-       TransData *td = NULL;
-       int count=0, i;
-       float cfra;
-       char side;
-       
-       /* which side of the current frame should be allowed */
-       if (t->mode == TFM_TIME_EXTEND) {
-               /* only side on which mouse is gets transformed */
-               float xmouse, ymouse;
-               
-               areamouseco_to_ipoco(G.v2d, t->imval, &xmouse, &ymouse);
-               side = (xmouse > CFRA) ? 'R' : 'L';
-       }
-       else {
-               /* normal transform - both sides of current frame are considered */
-               side = 'B';
-       }
-       
-       /* Ensure that partial selections result in beztriple selections */
-       for (base=G.scene->base.first; base; base=base->next) {
-               /* Check object ipos */
-               i= count_ipo_keys(base->object->ipo, side, (float)CFRA);
-               if (i) base->flag |= BA_HAS_RECALC_OB;
-               count += i;
-               
-               /* Check object constraint ipos */
-               for (conchan=base->object->constraintChannels.first; conchan; conchan=conchan->next)
-                       count += count_ipo_keys(conchan->ipo, side, (float)CFRA);                       
-               
-               /* skip actions and nlastrips if object is collapsed */
-               if (base->object->nlaflag & OB_NLA_COLLAPSED)
-                       continue;
-               
-               /* Check action ipos */
-               if (base->object->action) {
-                       /* exclude if strip is selected too */
-                       for (strip=base->object->nlastrips.first; strip; strip=strip->next) {
-                               if (strip->flag & ACTSTRIP_SELECT) {
-                                       if (strip->act == base->object->action)
-                                               break;
-                               }
-                       }
-                       if (strip==NULL) {
-                               cfra = get_action_frame(base->object, (float)CFRA);
-                               
-                               for (achan=base->object->action->chanbase.first; achan; achan=achan->next) {
-                                       if (EDITABLE_ACHAN(achan)) {
-                                               i= count_ipo_keys(achan->ipo, side, cfra);
-                                               if (i) base->flag |= BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA;
-                                               count += i;
-                                               
-                                               /* Check action constraint ipos */
-                                               if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
-                                                       for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
-                                                               if (EDITABLE_CONCHAN(conchan))
-                                                                       count += count_ipo_keys(conchan->ipo, side, cfra);
-                                                       }
-                                               }
-                                       }
-                               }
-                       }               
-               }
-               
-               /* Check nlastrips */
-               for (strip=base->object->nlastrips.first; strip; strip=strip->next) {
-                       if (strip->flag & ACTSTRIP_SELECT) {
-                               base->flag |= BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA;
-                               
-                               if (FrameOnMouseSide(side, strip->start, (float)CFRA)) count++;
-                               if (FrameOnMouseSide(side, strip->end, (float)CFRA)) count++;
-                       }
-               }
-       }
-       
-       /* If nothing is selected, bail out */
-       if (count == 0)
-               return;
-       
-       /* allocate memory for data */
-       t->total= count;
-       t->data= MEM_callocN(t->total*sizeof(TransData), "TransData (NLA Editor)");
-       
-       /* build the transdata structure */
-       td= t->data;
-       for (base=G.scene->base.first; base; base=base->next) {
-               /* Manipulate object ipos */
-               /*      - no scaling of keyframe times is allowed here  */
-               td= IpoToTransData(td, base->object->ipo, NULL, side, (float)CFRA);
-               
-               /* Manipulate object constraint ipos */
-               /*      - no scaling of keyframe times is allowed here  */
-               for (conchan=base->object->constraintChannels.first; conchan; conchan=conchan->next)
-                       td= IpoToTransData(td, conchan->ipo, NULL, side, (float)CFRA);
-               
-               /* skip actions and nlastrips if object collapsed */
-               if (base->object->nlaflag & OB_NLA_COLLAPSED)
-                       continue;
-                       
-               /* Manipulate action ipos */
-               if (base->object->action) {
-                       /* exclude if strip that active action belongs to is selected too */
-                       for (strip=base->object->nlastrips.first; strip; strip=strip->next) {
-                               if (strip->flag & ACTSTRIP_SELECT) {
-                                       if (strip->act == base->object->action)
-                                               break;
-                               }
-                       }
-                       
-                       /* can include if no strip found */
-                       if (strip==NULL) {
-                               cfra = get_action_frame(base->object, (float)CFRA);
-                               
-                               for (achan=base->object->action->chanbase.first; achan; achan=achan->next) {
-                                       if (EDITABLE_ACHAN(achan)) {
-                                               td= IpoToTransData(td, achan->ipo, base->object, side, cfra);
-                                               
-                                               /* Manipulate action constraint ipos */
-                                               if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
-                                                       for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
-                                                               if (EDITABLE_CONCHAN(conchan))
-                                                                       td= IpoToTransData(td, conchan->ipo, base->object, side, cfra);
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-               }
-               
-               /* Manipulate nlastrips */
-               for (strip=base->object->nlastrips.first; strip; strip=strip->next) {
-                       if (strip->flag & ACTSTRIP_SELECT) {
-                               /* first TransData is the start, second is the end */
-                               if (FrameOnMouseSide(side, strip->start, (float)CFRA)) {
-                                       td->val = &strip->start;
-                                       td->ival = strip->start;
-                                       td++;
-                               }
-                               if (FrameOnMouseSide(side, strip->end, (float)CFRA)) {
-                                       td->val = &strip->end;
-                                       td->ival = strip->end;
-                                       td++;
-                               }
-                       }
-               }
-       }
-#endif
-}
 
 /* **************** IpoKey stuff, for Object TransData ********** */
 
@@ -3950,13 +3720,12 @@ static void recalc_all_ipos(void)
 void special_aftertrans_update(TransInfo *t)
 {
        Object *ob;
-       Base *base;
-       short redrawipo=0, resetslowpar=1;
+//     short redrawipo=0, resetslowpar=1;
        int cancelled= (t->state == TRANS_CANCEL);
        short duplicate= (t->undostr && strstr(t->undostr, "Duplicate")) ? 1 : 0;
        
        if (t->spacetype==SPACE_VIEW3D) {
-               if (G.obedit) {
+               if (t->obedit) {
                        if (cancelled==0) {
 #if 0 // TRANSFORM_FIX_ME
                                EM_automerge(1);
@@ -3968,67 +3737,100 @@ void special_aftertrans_update(TransInfo *t)
                        }
                }
        }
-#if 0 // TRANSFORM_FIX_ME
+       
        if (t->spacetype == SPACE_ACTION) {
-               void *data;
-               short datatype;
+               SpaceAction *saction= (SpaceAction *)t->sa->spacedata.first;
+               Scene *scene;
+               bAnimContext ac;
+               
+               /* initialise relevant anim-context 'context' data from TransInfo data */
+                       /* NOTE: sync this with the code in ANIM_animdata_get_context() */
+               memset(&ac, 0, sizeof(bAnimContext));
                
-               /* determine what type of data we are operating on */
-               data = get_action_context(&datatype);
-               if (data == NULL) return;
-               ob = OBACT;
+               scene= ac.scene= t->scene;
+               ob= ac.obact= OBACT;
+               ac.sa= t->sa;
+               ac.ar= t->ar;
+               ac.spacetype= (t->sa)? t->sa->spacetype : 0;
+               ac.regiontype= (t->ar)? t->ar->regiontype : 0;
                
-               if (datatype == ACTCONT_ACTION) {
+               if (ANIM_animdata_context_getdata(&ac) == 0)
+                       return;
+               
+               if (ac.datatype == ANIMCONT_DOPESHEET) {
+                       ListBase anim_data = {NULL, NULL};
+                       bAnimListElem *ale;
+                       short filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_ONLYICU);
+                       
+                       /* get channels to work on */
+                       ANIM_animdata_filter(&anim_data, filter, ac.data, ac.datatype);
+                       
+                       /* these should all be ipo-blocks */
+                       for (ale= anim_data.first; ale; ale= ale->next) {
+                               Object *nob= ANIM_nla_mapping_get(&ac, ale);
+                               IpoCurve *icu= (IpoCurve *)ale->key_data;
+                               
+                               if ( (saction->flag & SACTION_NOTRANSKEYCULL)==0 && 
+                                    ((cancelled == 0) || (duplicate)) )
+                               {
+                                       if (nob) {
+                                               ANIM_nla_mapping_apply_ipocurve(nob, icu, 0, 1); 
+                                               posttrans_icu_clean(icu);
+                                               ANIM_nla_mapping_apply_ipocurve(nob, icu, 1, 1);
+                                       }
+                                       else
+                                               posttrans_icu_clean(icu);
+                               }
+                       }
+                       
+                       /* free temp memory */
+                       BLI_freelistN(&anim_data);
+               }
+               else if (ac.datatype == ANIMCONT_ACTION) {
                        /* Depending on the lock status, draw necessary views */
+                       // fixme... some of this stuff is not good
                        if (ob) {
                                ob->ctime= -1234567.0f;
                                
-                               if(ob->pose || ob_get_key(ob))
-                                       DAG_object_flush_update(G.scene, ob, OB_RECALC);
+                               if (ob->pose || ob_get_key(ob))
+                                       DAG_object_flush_update(scene, ob, OB_RECALC);
                                else
-                                       DAG_object_flush_update(G.scene, ob, OB_RECALC_OB);
+                                       DAG_object_flush_update(scene, ob, OB_RECALC_OB);
                        }
                        
                        /* Do curve cleanups? */
-                       if ( (G.saction->flag & SACTION_NOTRANSKEYCULL)==0 && 
+                       if ( (saction->flag & SACTION_NOTRANSKEYCULL)==0 && 
                             ((cancelled == 0) || (duplicate)) )
                        {
-                               posttrans_action_clean((bAction *)data);
+                               posttrans_action_clean(&ac, (bAction *)ac.data);
                        }
-                       
-                       /* Do curve updates */
-                       remake_action_ipos((bAction *)data);
                }
-               else if (datatype == ACTCONT_SHAPEKEY) {
+               else if (ac.datatype == ANIMCONT_SHAPEKEY) {
                        /* fix up the Ipocurves and redraw stuff */
-                       Key *key= (Key *)data;
+                       Key *key= (Key *)ac.data;
+                       
                        if (key->ipo) {
-                               IpoCurve *icu;
-                               
-                               if ( (G.saction->flag & SACTION_NOTRANSKEYCULL)==0 && 
+                               if ( (saction->flag & SACTION_NOTRANSKEYCULL)==0 && 
                                     ((cancelled == 0) || (duplicate)) )
                                {
                                        posttrans_ipo_clean(key->ipo);
                                }
-                               
-                               for (icu = key->ipo->curve.first; icu; icu=icu->next) {
-                                       sort_time_ipocurve(icu);
-                                       testhandles_ipocurve(icu);
-                               }
                        }
                        
-                       DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
+                       DAG_object_flush_update(scene, OBACT, OB_RECALC_DATA);
                }
-               else if (datatype == ACTCONT_GPENCIL) {
+#if 0 // XXX future of this is still not clear
+               else if (ac.datatype == ANIMCONT_GPENCIL) {
                        /* remove duplicate frames and also make sure points are in order! */
                        if ((cancelled == 0) || (duplicate))
                        {
+                               bScreen *sc= (bScreen *)ac.data;
                                ScrArea *sa;
                                
                                /* BAD... we need to loop over all screen areas for current screen...
                                 *      - sync this with actdata_filter_gpencil() in editaction.c 
                                 */
-                               for (sa= G.curscreen->areabase.first; sa; sa= sa->next) {
+                               for (sa= sc->areabase.first; sa; sa= sa->next) {
                                        bGPdata *gpd= gpencil_data_getactive(sa);
                                        
                                        if (gpd) 
@@ -4036,9 +3838,15 @@ void special_aftertrans_update(TransInfo *t)
                                }
                        }
                }
+#endif // XXX future of this is still not clear
                
-               G.saction->flag &= ~SACTION_MOVING;
+               /* make sure all IPO-curves are set correctly */
+               ANIM_editkeyframes_refresh(&ac);
+               
+               /* clear flag that was set for time-slide drawing */
+               saction->flag &= ~SACTION_MOVING;
        }
+#if 0 // TRANSFORM_FIX_ME
        else if (t->spacetype == SPACE_NLA) {
                recalc_all_ipos();      // bad
                synchronize_action_strips();
@@ -4074,12 +3882,12 @@ void special_aftertrans_update(TransInfo *t)
                if (G.sipo->blocktype==ID_SEQ)
                        resetslowpar= 0;
        }
-       else if (G.obedit) {
+       else if (t->obedit) {
                if (t->mode==TFM_BONESIZE || t->mode==TFM_BONE_ENVELOPE)
                        allqueue(REDRAWBUTSEDIT, 0);
                
                /* table needs to be created for each edit command, since vertices can move etc */
-               mesh_octree_table(G.obedit, NULL, 'e');
+               mesh_octree_table(t->obedit, NULL, 'e');
        }
        else if ((t->flag & T_POSE) && (t->poseobj)) {
                bArmature *arm;
@@ -4312,16 +4120,57 @@ static void createTransObject(bContext *C, TransInfo *t)
        }
 }
 
+/* transcribe given node into TransData2D for Transforming */
+static void NodeToTransData(TransData *td, TransData2D *td2d, bNode *node)
+// static void NodeToTransData(bContext *C, TransInfo *t, TransData2D *td, bNode *node) 
+{
+       td2d->loc[0] = node->locx; /* hold original location */
+       td2d->loc[1] = node->locy;
+       td2d->loc[2] = 0.0f;
+       td2d->loc2d = &node->locx; /* current location */
+
+       td->flag = 0;
+       td->loc = td2d->loc;
+       VECCOPY(td->center, td->loc);
+       VECCOPY(td->iloc, td->loc);
+
+       memset(td->axismtx, 0, sizeof(td->axismtx));
+       td->axismtx[2][2] = 1.0f;
+
+       td->ext= NULL; td->tdi= NULL; td->val= NULL;
+
+       td->flag |= TD_SELECTED;
+       td->dist= 0.0;
+
+       Mat3One(td->mtx);
+       Mat3One(td->smtx);
+}
+
+void createTransNodeData(bContext *C, TransInfo *t)
+{
+       TransData *td;
+       TransData2D *td2d;
+       
+       CTX_DATA_COUNT(C, selected_nodes, t->total)
+       
+       td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransNode TransData");
+       td2d = t->data2d = MEM_callocN(t->total*sizeof(TransData2D), "TransNode TransData2D");
+       
+       CTX_DATA_BEGIN(C, bNode *, selnode, selected_nodes)
+               NodeToTransData(td++, td2d++, selnode);
+       CTX_DATA_END
+}
+
 void createTransData(bContext *C, TransInfo *t) 
 {
        Scene *scene = CTX_data_scene(C);
        Object *ob = OBACT;
        
-       if (t->context == CTX_TEXTURE) {
+       if (t->options == CTX_TEXTURE) {
                t->flag |= T_TEXTURE;
                createTransTexspace(C, t);
        }
-       else if (t->context == CTX_EDGE) {
+       else if (t->options == CTX_EDGE) {
                t->ext = NULL;
                t->flag |= T_EDIT;
                createTransEdge(C, t);
@@ -4331,7 +4180,7 @@ void createTransData(bContext *C, TransInfo *t)
                        sort_trans_data_dist(t);
                }
        }
-       else if (t->context == CTX_BMESH) {
+       else if (t->options == CTX_BMESH) {
                // TRANSFORM_FIX_ME
                //createTransBMeshVerts(t, G.editBMesh->bm, G.editBMesh->td);
        }
@@ -4350,7 +4199,8 @@ void createTransData(bContext *C, TransInfo *t)
        }
        else if (t->spacetype == SPACE_NLA) {
                t->flag |= T_POINTS|T_2D_EDIT;
-               createTransNlaData(C, t);
+               // TRANSFORM_FIX_ME
+               //createTransNlaData(C, t);
        }
        else if (t->spacetype == SPACE_IPO) {
                t->flag |= T_POINTS|T_2D_EDIT;
@@ -4361,23 +4211,25 @@ void createTransData(bContext *C, TransInfo *t)
                        sort_trans_data_dist(t);
                }
        }
-       else if (0) { // // TRANSFORM_FIX_ME (G.obedit) {
-               Object *obedit = NULL; // TRANSFORM_FIX_ME
-               
+       else if(t->spacetype == SPACE_NODE) {
+               t->flag |= T_2D_EDIT|T_POINTS;
+               createTransNodeData(C, t);
+       }
+       else if (t->obedit) {
                t->ext = NULL;
-               if (obedit->type == OB_MESH) {
+               if (t->obedit->type == OB_MESH) {
                        createTransEditVerts(C, t);     
                }
-               else if ELEM(obedit->type, OB_CURVE, OB_SURF) {
+               else if ELEM(t->obedit->type, OB_CURVE, OB_SURF) {
                        createTransCurveVerts(C, t);
                }
-               else if (obedit->type==OB_LATTICE) {
+               else if (t->obedit->type==OB_LATTICE) {
                        createTransLatticeVerts(C, t);
                }
-               else if (obedit->type==OB_MBALL) {
+               else if (t->obedit->type==OB_MBALL) {
                        createTransMBallVerts(C, t);
                }
-               else if (obedit->type==OB_ARMATURE) {
+               else if (t->obedit->type==OB_ARMATURE) {
                        t->flag &= ~T_PROP_EDIT;
                        createTransArmatureVerts(C, t);
                }                                                       
@@ -4386,7 +4238,7 @@ void createTransData(bContext *C, TransInfo *t)
                }
 
                if(t->data && t->flag & T_PROP_EDIT) {
-                       if (ELEM(obedit->type, OB_CURVE, OB_MESH)) {
+                       if (ELEM(t->obedit->type, OB_CURVE, OB_MESH)) {
                                sort_trans_data(t);     // makes selected become first in array
                                set_prop_dist(t, 0);
                                sort_trans_data_dist(t);