Transform project.
authorTon Roosendaal <ton@blender.org>
Fri, 25 Feb 2005 11:35:24 +0000 (11:35 +0000)
committerTon Roosendaal <ton@blender.org>
Fri, 25 Feb 2005 11:35:24 +0000 (11:35 +0000)
Brought back functionality to work with "Ipo Keys" (Kkey in 3d window). New
transform code is looking more messy now... its design was not purposed to
clean on this level. Acceptable for this stage however.

Also renamed old variables *tob into *td.

source/blender/include/BIF_transform.h
source/blender/src/editobject.c
source/blender/src/transform.c
source/blender/src/transform.h
source/blender/src/transform_generics.c

index a491fb2a133d366d898c0cfd6b7c20da3636a1ef..71c89d23473132f2d97bb649b2a7638095a8719a 100755 (executable)
@@ -33,7 +33,7 @@
 #ifndef BIF_TRANSFORM_H
 #define BIF_TRANSFORM_H
 
-// #define NEWTRANSFORM        1
+#define NEWTRANSFORM   1
 
 /* ******************** Macros & Prototypes *********************** */
 
index 0af89a1b909cd0a4728dfbf6aca1d3c5a634fc6f..6ba36a427d720e3933d06b6233a66ea29a60b395 100644 (file)
@@ -4571,7 +4571,7 @@ void apply_keyb_grid(float *val, float fac1, float fac2, float fac3, int invert)
        }
 }
 
-
+/* exported to transform.c */
 void compatible_eul(float *eul, float *oldrot)
 {
        float dx, dy, dz;
index 4276b11842bf96819d6030f95d1fb30918dc982b..13b9ac22006fb068b74cd8e42302ca9d545c98d8 100755 (executable)
 
 #include "BKE_action.h"
 #include "BKE_armature.h"
+#include "BKE_blender.h"
 #include "BKE_curve.h"
 #include "BKE_displist.h"
 #include "BKE_effect.h"
 #include "BKE_global.h"
+#include "BKE_ipo.h"
 #include "BKE_lattice.h"
 #include "BKE_mball.h"
 #include "BKE_object.h"
@@ -96,6 +98,8 @@
 
 #include "BSE_view.h"
 #include "BSE_edit.h"
+#include "BSE_editipo.h"
+#include "BSE_editipo_types.h"
 #include "BDR_editobject.h"            // reset_slowparents()
 
 #include "BLI_arithb.h"
@@ -263,8 +267,10 @@ static void createTransPose(void)
        /* init trans data */
     td = Trans.data = MEM_mallocN(Trans.total*sizeof(TransData), "TransPoseBone");
     tdx = MEM_mallocN(Trans.total*sizeof(TransDataExtension), "TransPoseBoneExt");
-       for(i=0; i<Trans.total; i++, td++, tdx++) td->ext= tdx;
-       
+       for(i=0; i<Trans.total; i++, td++, tdx++) {
+               td->ext= tdx;
+               td->tdi = NULL;
+       }       
        /* recursive fill trans data */
        td= Trans.data;
        add_pose_transdata(&arm->bonebase, G.obpose, &td);
@@ -304,6 +310,7 @@ static void createTransArmatureVerts(void)
                        Mat3CpyMat3(td->mtx, mtx);
 
                        td->ext = NULL;
+                       td->tdi = NULL;
 
                        td->dist = 0.0f;
                        
@@ -318,6 +325,7 @@ static void createTransArmatureVerts(void)
                        Mat3CpyMat3(td->mtx, mtx);
 
                        td->ext = NULL;
+                       td->tdi = NULL;
 
                        td->dist = 0.0f;
                
@@ -356,6 +364,7 @@ static void createTransMBallVerts(void)
                        Mat3CpyMat3(td->mtx, mtx);
 
                        td->ext = tx;
+                       td->tdi = NULL;
 
                        tx->size = &ml->expx;
                        tx->isize[0] = ml->expx;
@@ -405,6 +414,7 @@ static void createTransCurveVerts(void)
                                                VECCOPY(td->center, td->loc);
                                                td->flag= TD_SELECTED;
                                                td->ext = NULL;
+                                               td->tdi = NULL;
 
                                                Mat3CpyMat3(td->smtx, smtx);
                                                Mat3CpyMat3(td->mtx, mtx);
@@ -420,6 +430,7 @@ static void createTransCurveVerts(void)
                                                VECCOPY(td->center, td->loc);
                                                td->flag= TD_SELECTED;
                                                td->ext = NULL;
+                                               td->tdi = NULL;
 
                                                Mat3CpyMat3(td->smtx, smtx);
                                                Mat3CpyMat3(td->mtx, mtx);
@@ -435,6 +446,7 @@ static void createTransCurveVerts(void)
                                                VECCOPY(td->center, td->loc);
                                                td->flag= TD_SELECTED;
                                                td->ext = NULL;
+                                               td->tdi = NULL;
 
                                                Mat3CpyMat3(td->smtx, smtx);
                                                Mat3CpyMat3(td->mtx, mtx);
@@ -459,6 +471,7 @@ static void createTransCurveVerts(void)
                                                VECCOPY(td->center, td->loc);
                                                td->flag= TD_SELECTED;
                                                td->ext = NULL;
+                                               td->tdi = NULL;
 
                                                Mat3CpyMat3(td->smtx, smtx);
                                                Mat3CpyMat3(td->mtx, mtx);
@@ -512,6 +525,7 @@ static void createTransLatticeVerts(void)
                                Mat3CpyMat3(td->mtx, mtx);
 
                                td->ext = NULL;
+                               td->tdi = NULL;
 
                                td->dist = 0.0f;
 
@@ -523,13 +537,14 @@ static void createTransLatticeVerts(void)
        }
 } 
 
-static void VertsToTransData(TransData *tob, EditVert *eve)
+static void VertsToTransData(TransData *td, EditVert *eve)
 {
-       tob->flag = 0;
-       tob->loc = eve->co;
-       VECCOPY(tob->center, tob->loc);
-       VECCOPY(tob->iloc, tob->loc);
-       tob->ext = NULL;
+       td->flag = 0;
+       td->loc = eve->co;
+       VECCOPY(td->center, td->loc);
+       VECCOPY(td->iloc, td->loc);
+       td->ext = NULL;
+       td->tdi = NULL;
 }
 
 static void createTransEditVerts(void)
@@ -648,9 +663,98 @@ static void createTransEditVerts(void)
        }
 }
 
+/* **************** IpoKey stuff, for Object TransData ********** */
+
+/* storage of bezier triple. thats why -3 and +3! */
+static void set_tdi_old(float *old, float *poin)
+{
+       old[0]= *(poin);
+       old[3]= *(poin-3);
+       old[6]= *(poin+3);
+}
+
+/* while transforming */
+static void add_tdi_poin(float *poin, float *old, float delta)
+{
+       if(poin) {
+               poin[0]= old[0]+delta;
+               poin[-3]= old[3]+delta;
+               poin[3]= old[6]+delta;
+       }
+}
+
+/* fill ipokey transdata with old vals and pointers */
+static void ipokey_to_transdata(IpoKey *ik, TransData *td)
+{
+       extern int ob_ar[];             // blenkernel ipo.c
+       TransDataIpokey *tdi= td->tdi;
+       BezTriple *bezt;
+       int a, delta= 0;
+       
+       for(a=0; a<OB_TOTIPO; a++) {
+               if(ik->data[a]) {
+                       bezt= ik->data[a];
+                       
+                       switch( ob_ar[a] ) {
+                               case OB_LOC_X:
+                               case OB_DLOC_X:
+                                       tdi->locx= &(bezt->vec[1][1]); break;
+                               case OB_LOC_Y:
+                               case OB_DLOC_Y:
+                                       tdi->locy= &(bezt->vec[1][1]); break;
+                               case OB_LOC_Z:
+                               case OB_DLOC_Z:
+                                       tdi->locz= &(bezt->vec[1][1]); break;
+                                       
+                               case OB_DROT_X:
+                                       delta= 1;
+                               case OB_ROT_X:
+                                       tdi->rotx= &(bezt->vec[1][1]); break;
+                               case OB_DROT_Y:
+                                       delta= 1;
+                               case OB_ROT_Y:
+                                       tdi->roty= &(bezt->vec[1][1]); break;
+                               case OB_DROT_Z:
+                                       delta= 1;
+                               case OB_ROT_Z:
+                                       tdi->rotz= &(bezt->vec[1][1]); break;
+                                       
+                               case OB_SIZE_X:
+                               case OB_DSIZE_X:
+                                       tdi->sizex= &(bezt->vec[1][1]); break;
+                               case OB_SIZE_Y:
+                               case OB_DSIZE_Y:
+                                       tdi->sizey= &(bezt->vec[1][1]); break;
+                               case OB_SIZE_Z:
+                               case OB_DSIZE_Z:
+                                       tdi->sizez= &(bezt->vec[1][1]); break;          
+                       }       
+               }
+       }
+       
+       /* oldvals for e.g. undo */
+       if(tdi->locx) set_tdi_old(tdi->oldloc, tdi->locx);
+       if(tdi->locy) set_tdi_old(tdi->oldloc+1, tdi->locy);
+       if(tdi->locz) set_tdi_old(tdi->oldloc+2, tdi->locz);
+       
+       /* remember, for mapping curves ('1'=10 degrees)  */
+       if(tdi->rotx) set_tdi_old(tdi->oldrot, tdi->rotx);
+       if(tdi->roty) set_tdi_old(tdi->oldrot+1, tdi->roty);
+       if(tdi->rotz) set_tdi_old(tdi->oldrot+2, tdi->rotz);
+       
+       /* this is not allowed to be dsize! */
+       if(tdi->sizex) set_tdi_old(tdi->oldsize, tdi->sizex);
+       if(tdi->sizey) set_tdi_old(tdi->oldsize+1, tdi->sizey);
+       if(tdi->sizez) set_tdi_old(tdi->oldsize+2, tdi->sizez);
+       
+       tdi->flag= TOB_IPO;
+       if(delta) tdi->flag |= TOB_IPODROT;
+}
+
+
 /* *************************** Object Transform data ******************* */
 
-static void ObjectToTransData(TransData *tob, Object *ob) 
+static void ObjectToTransData(TransData *td, Object *ob) 
 {
        float obmtx[3][3];
        Object *tr;
@@ -670,37 +774,39 @@ static void ObjectToTransData(TransData *tob, Object *ob)
        ob->constraints.first = cfirst;
        ob->constraints.last = clast;
 
-       tob->ob = ob;
+       td->ob = ob;
 
-       tob->loc = ob->loc;
-       VECCOPY(tob->iloc, tob->loc);
+       td->loc = ob->loc;
+       VECCOPY(td->iloc, td->loc);
        
-       tob->ext->rot = ob->rot;
-       VECCOPY(tob->ext->irot, ob->rot);
+       td->ext->rot = ob->rot;
+       VECCOPY(td->ext->irot, ob->rot);
+       VECCOPY(td->ext->drot, ob->drot);
        
-       tob->ext->size = ob->size;
-       VECCOPY(tob->ext->isize, ob->size);
+       td->ext->size = ob->size;
+       VECCOPY(td->ext->isize, ob->size);
+       VECCOPY(td->ext->dsize, ob->dsize);
 
-       VECCOPY(tob->center, ob->obmat[3]);
+       VECCOPY(td->center, ob->obmat[3]);
 
-       Mat3CpyMat4(tob->mtx, ob->obmat);
+       Mat3CpyMat4(td->mtx, ob->obmat);
 
        object_to_mat3(ob, obmtx);
 
        /*
        Mat3CpyMat4(totmat, ob->obmat);
        Mat3Inv(obinv, totmat);
-       Mat3MulMat3(tob->smtx, obmtx, obinv);
+       Mat3MulMat3(td->smtx, obmtx, obinv);
        */
        if (ob->parent)
        {
-               Mat3CpyMat4(tob->mtx, ob->parent->obmat);
-               Mat3Inv(tob->smtx, tob->mtx);
+               Mat3CpyMat4(td->mtx, ob->parent->obmat);
+               Mat3Inv(td->smtx, td->mtx);
        }
        else
        {
-               Mat3One(tob->smtx);
-               Mat3One(tob->mtx);
+               Mat3One(td->smtx);
+               Mat3One(td->mtx);
        }
 }
 
@@ -863,12 +969,13 @@ static void clear_trans_object_base_flags(void)
 
 static void createTransObject(void)
 {
-       TransData *tob = NULL;
+       TransData *td = NULL;
        TransDataExtension *tx;
        Object *ob;
        Base *base;
-       int totsel= 0;
-
+       IpoKey *ik;
+       ListBase elems;
+       
        /* hackish... but we have to do it somewhere */
        reset_slowparents();
        
@@ -877,8 +984,22 @@ static void createTransObject(void)
        /* count */     
        for(base= FIRSTBASE; base; base= base->next) {
                if TESTBASELIB(base) {
-                       Trans.total++;
-                       totsel++;
+                       ob= base->object;
+                       
+                       /* store ipo keys? */
+                       if(ob->ipo && ob->ipo->showkey && (ob->ipoflag & OB_DRAWKEY)) {
+                               elems.first= elems.last= NULL;
+                               make_ipokey_transform(ob, &elems, 1); /* '1' only selected keys */
+                               
+                               pushdata(&elems, sizeof(ListBase));
+                               
+                               for(ik= elems.first; ik; ik= ik->next) Trans.total++;
+
+                               if(elems.first==NULL) Trans.total++;
+                       }
+                       else {
+                               Trans.total++;
+                       }
                }
        }
 
@@ -888,34 +1009,73 @@ static void createTransObject(void)
                return;
        }
        
-       tob = Trans.data = MEM_mallocN(Trans.total*sizeof(TransData), "TransOb");
+       td = Trans.data = MEM_mallocN(Trans.total*sizeof(TransData), "TransOb");
        tx = MEM_mallocN(Trans.total*sizeof(TransDataExtension), "TransObExtension");
 
        for(base= FIRSTBASE; base; base= base->next) {
                if TESTBASELIB(base) {
                        ob= base->object;
                        
-                       tob->flag= TD_SELECTED|TD_OBJECT;
-
-                       tob->ext = tx;
-
-                       ObjectToTransData(tob, ob);
-
-                       tob->dist = 0.0f;
+                       td->flag= TD_SELECTED|TD_OBJECT;
+                       td->ext = tx;
+                       td->dist = 0.0f;
 
-                       tob++;
+                       /* store ipo keys? */
+                       if(ob->ipo && ob->ipo->showkey && (ob->ipoflag & OB_DRAWKEY)) {
+                               
+                               popfirst(&elems);       // bring back pushed listbase
+                               
+                               if(elems.first) {
+                                       float cfraont;
+                                       int ipoflag;
+                                       
+                                       base->flag |= BA_DO_IPO+BA_WASSEL;
+                                       base->flag &= ~SELECT;
+                                       
+                                       cfraont= CFRA;
+                                       set_no_parent_ipo(1);
+                                       ipoflag= ob->ipoflag;
+                                       ob->ipoflag &= ~OB_OFFS_OB;
+                                       
+                                       pushdata(ob->loc, 7*3*4); // tsk! tsk!
+                                       
+                                       for(ik= elems.first; ik; ik= ik->next) {
+                                               
+                                               /* weak... this doesn't correct for floating values, giving small errors */
+                                               CFRA= ik->val/G.scene->r.framelen;
+                                               
+                                               do_ob_ipo(ob);
+                                               ObjectToTransData(td, ob);      // does where_is_object()
+                                               
+                                               td->tdi= MEM_callocN(sizeof(TransDataIpokey), "TransDataIpokey");
+                                               /* also does tdi->flag and oldvals, needs to be after ob_to_transob()! */
+                                               ipokey_to_transdata(ik, td);
+                                               
+                                               td++;
+                                               tx++;
+                                               if(ik->next) td->ext= tx;       // prevent corrupting mem!
+                                       }
+                                       free_ipokey(&elems);
+                                       
+                                       poplast(ob->loc);
+                                       set_no_parent_ipo(0);
+                                       
+                                       CFRA= cfraont;
+                                       ob->ipoflag= ipoflag;
+                               }
+                               else {
+                                       ObjectToTransData(td, ob);
+                                       td->tdi= NULL;
+                               }
+                       }
+                       else {
+                               ObjectToTransData(td, ob);
+                               td->tdi= NULL;
+                       }
+                       td++;
                        tx++;
                }
        }
-/*
-       KICK OUT CHILDS OF OBJECTS THAT ARE BEING TRANSFORMED
-       SINCE TRANSFORMATION IS ALREADY APPLIED ON PARENT
-
-       THERE MUST BE A BETTER WAY TO DO THIS
-       Yes there is! For now I copy the baseflag method from old transform (ton)
-*/
-
 }
 
 static void createTransData(void) 
@@ -1346,16 +1506,34 @@ int Resize(TransInfo *t, short mval[2])
 
                        if (td->flag & TD_OBJECT) {
                                float obsizemat[3][3];
-                               Mat3MulMat3(obsizemat, tmat, td->smtx);
+                               Mat3MulMat3(obsizemat, td->smtx, tmat);
                                Mat3ToSize(obsizemat, fsize);
                        }
                        else {
                                Mat3ToSize(tmat, fsize);
                        }
-                       // TEMPORARY NAIVE CODE
-                       td->ext->size[0] = td->ext->isize[0] + td->ext->isize[0] * (fsize[0] - 1.0f) * td->factor;
-                       td->ext->size[1] = td->ext->isize[1] + td->ext->isize[1] * (fsize[1] - 1.0f) * td->factor;
-                       td->ext->size[2] = td->ext->isize[2] + td->ext->isize[2] * (fsize[2] - 1.0f) * td->factor;
+                       
+                       /* handle ipokeys? */
+                       if(td->tdi) {
+                               TransDataIpokey *tdi= td->tdi;
+                               /* calculate delta size (equal for size and dsize) */
+                               
+                               // commented out for now
+                               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 {
+                               // TEMPORARY NAIVE CODE
+                               td->ext->size[0] = td->ext->isize[0] + td->ext->isize[0] * (fsize[0] - 1.0f) * td->factor;
+                               td->ext->size[1] = td->ext->isize[1] + td->ext->isize[1] * (fsize[1] - 1.0f) * td->factor;
+                               td->ext->size[2] = td->ext->isize[2] + td->ext->isize[2] * (fsize[2] - 1.0f) * td->factor;
+                       }
                }
                VecSubf(vec, td->center, t->center);
 
@@ -1591,18 +1769,55 @@ int Rotation(TransInfo *t, short mval[2])
                                Mat3MulSerie(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0);
                                
                                Mat3ToQuat(fmat, quat); // Actual transform
-                               //printf("Quat %f %f %f %f\n", quat[0], quat[1], quat[2], quat[3]);
                                
                                QuatMul(td->ext->quat, quat, td->ext->iquat);
                        }
                        else {
                                float obmat[3][3];
-                               EulToMat3(td->ext->irot, obmat);
-
-                               Mat3MulMat3(fmat, mat, obmat);
                                
-                               Mat3ToEul(fmat, eul);
-                               VECCOPY(td->ext->rot, eul);
+                               /* are there ipo keys? */
+                               if(td->tdi) {
+                                       TransDataIpokey *tdi= td->tdi;
+                                       float rot[3];
+                                       
+                                       /* 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);
+                                       Mat3ToEul(fmat, eul);
+                                       compatible_eul(eul, td->ext->irot);
+                                       
+                                       /* 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, 9.0/M_PI_2);
+                                       VecSubf(rot, 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 {
+                                       
+                                       /* 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, mat, obmat);
+                                       Mat3ToEul(fmat, eul);
+                                       compatible_eul(eul, td->ext->irot);
+                                       
+                                       /* correct back for delta rot */
+                                       VecSubf(eul, eul, td->ext->drot);
+                                       /* and apply */
+                                       VECCOPY(td->ext->rot, eul);
+                               }
                        }
                }
        }
@@ -1670,10 +1885,16 @@ int Translation(TransInfo *t, short mval[2])
                }
 
                Mat3MulVecfl(td->smtx, tvec);
-
                VecMulf(tvec, td->factor);
-
-               VecAddf(td->loc, td->iloc, 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);
        }
 
 
index fabe20b378664dbf1bca8978718c6f388d16dc7f..19fe986cf2b0fd6536725dc482ce7d99e07cba98 100755 (executable)
@@ -55,16 +55,30 @@ typedef struct TransCon {
                          /* Apply function pointer for rotation transformation (prototype will change */
 } TransCon;
 
+typedef struct TransDataIpokey {
+       int flag;                                       /* which keys */
+       float *locx, *locy, *locz;      /* channel pointers */
+       float *rotx, *roty, *rotz;
+       float *quatx, *quaty, *quatz, *quatw;
+       float *sizex, *sizey, *sizez;
+       float oldloc[9];                        /* storage old values */
+       float oldrot[9];
+       float oldsize[9];
+       float oldquat[12];
+} TransDataIpokey;
+
 typedef struct TransDataExtension {
+       float drot[3];           /* Initial object drot */
+       float dsize[3];          /* Initial object dsize */
     float *rot;          /* Rotation of the data to transform (Faculative)                                 */
     float  irot[3];      /* Initial rotation                                                               */
     float *quat;         /* Rotation quaternion of the data to transform (Faculative)                      */
     float  iquat[4];    /* Initial rotation quaternion                                                    */
     float *size;         /* Size of the data to transform (Faculative)                                     */
     float  isize[3];    /* Initial size                                                                   */
-       float  obmat[3][3];      /* Object matrix */
+       float  obmat[3][3];      /* Object matrix */  
 
-       void *bone;                     /* BWARGH! old transform demanded it, added for now (ton) */
+       void *bone;                     /* ARGH! old transform demanded it, added for now (ton) */
 } TransDataExtension;
 
 typedef struct TransData {
@@ -76,7 +90,8 @@ typedef struct TransData {
     float  mtx[3][3];    /* Transformation matrix from data space to global space                          */
     float  smtx[3][3];   /* Transformation matrix from global space to data space                          */
        struct Object *ob;
-       struct TransDataExtension *ext;
+       TransDataExtension *ext;        /* for objects, poses. 1 single malloc per TransInfo! */
+       TransDataIpokey *tdi;           /* for objects, ipo keys. per transdata a malloc */
     int    flag;         /* Various flags */
 } TransData;
 
index be89dfba240c43b56a9d663077a24284af348b30..e1b4940e2feda9fd9c25fe94902d250e3b911e59 100755 (executable)
@@ -221,7 +221,7 @@ void recalcData(TransInfo *t)
                        }
                }
                else if (G.obedit->type == OB_MBALL) {
-               makeDispList(G.obedit); 
+                       makeDispList(G.obedit); 
                }       
        }
        else {
@@ -351,14 +351,20 @@ void drawLine(float *center, float *dir, char axis)
 void postTrans (TransInfo *t) 
 {
        TransDataExtension *tx = t->data->ext;
+       TransData *td;
+       int a;
+       
        G.moving = 0; // Set moving flag off (display as usual)
 
+       /* since ipokeys are optional on objects, we mallocced them per trans-data */
+       for(a=0, td= t->data; a<t->total; a++, td++) {
+               if(td->tdi) MEM_freeN(td->tdi);
+       }
+       
        MEM_freeN(t->data);
        t->data = NULL;
 
-       if (tx) {
-               MEM_freeN(tx);
-       }
+       if (tx) MEM_freeN(tx);
        
 }
 
@@ -421,38 +427,67 @@ void apply_grid2(float *val, int max_index, float factor, float factor2)
 
 void applyTransObjects(TransInfo *t)
 {
-    TransData *tob;
-       for (tob = t->data; tob < t->data + t->total; tob++) {
-        VECCOPY(tob->iloc, tob->loc);
-               if (tob->ext->rot) {
-                       VECCOPY(tob->ext->irot, tob->ext->rot);
+       TransData *td;
+       
+       for (td = t->data; td < t->data + t->total; td++) {
+               VECCOPY(td->iloc, td->loc);
+               if (td->ext->rot) {
+                       VECCOPY(td->ext->irot, td->ext->rot);
                }
-               if (tob->ext->size) {
-                       VECCOPY(tob->ext->isize, tob->ext->size);
+               if (td->ext->size) {
+                       VECCOPY(td->ext->isize, td->ext->size);
                }
-    }    
+       }       
        recalcData(t);
 } 
 
+/* helper for below */
+static void restore_ipokey(float *poin, float *old)
+{
+       if(poin) {
+               poin[0]= old[0];
+               poin[-3]= old[3];
+               poin[3]= old[6];
+       }
+}
+
 void restoreTransObjects(TransInfo *t)
 {
-    TransData *tob;
-       for (tob = t->data; tob < t->data + t->total; tob++) {
-        VECCOPY(tob->loc, tob->iloc);
-               if (tob->ext) {
-                       if (tob->ext->rot) {
-                               VECCOPY(tob->ext->rot, tob->ext->irot);
+       TransData *td;
+       
+       for (td = t->data; td < t->data + t->total; td++) {
+               VECCOPY(td->loc, td->iloc);
+               
+               if (td->ext) {
+                       if (td->ext->rot) {
+                               VECCOPY(td->ext->rot, td->ext->irot);
                        }
-                       if (tob->ext->size) {
-                               VECCOPY(tob->ext->size, tob->ext->isize);
+                       if (td->ext->size) {
+                               VECCOPY(td->ext->size, td->ext->isize);
                        }
-                       if(tob->flag & TD_USEQUAT) {
-                               if (tob->ext->quat) {
-                                       QUATCOPY(tob->ext->quat, tob->ext->iquat);
+                       if(td->flag & TD_USEQUAT) {
+                               if (td->ext->quat) {
+                                       QUATCOPY(td->ext->quat, td->ext->iquat);
                                }
                        }
                }
-    }    
+               if(td->tdi) {
+                       TransDataIpokey *tdi= td->tdi;
+                       
+                       restore_ipokey(tdi->locx, tdi->oldloc);
+                       restore_ipokey(tdi->locy, tdi->oldloc+1);
+                       restore_ipokey(tdi->locz, tdi->oldloc+2);
+
+                       restore_ipokey(tdi->rotx, tdi->oldrot);
+                       restore_ipokey(tdi->roty, tdi->oldrot+1);
+                       restore_ipokey(tdi->rotz, tdi->oldrot+2);
+                       
+                       restore_ipokey(tdi->sizex, tdi->oldsize);
+                       restore_ipokey(tdi->sizey, tdi->oldsize+1);
+                       restore_ipokey(tdi->sizez, tdi->oldsize+2);
+               }
+               
+       }       
        recalcData(t);
 }