Stage two of the giant animation recode project; Ipo/Action/NLA cleanup
[blender.git] / source / blender / src / editobject.c
index 67e3a42a30767b21957556d1876f886a0329fe95..d46c06bd4b9ecd39d24e73a5bfa9fafbb59b5536 100644 (file)
@@ -62,7 +62,6 @@
 #include "DNA_constraint_types.h"
 #include "DNA_curve_types.h"
 #include "DNA_effect_types.h"
-#include "DNA_ika_types.h"
 #include "DNA_image_types.h"
 #include "DNA_ipo_types.h"
 #include "DNA_key_types.h"
 #include "DNA_meshdata_types.h"
 #include "DNA_meta_types.h"
 #include "DNA_object_types.h"
+#include "DNA_object_force.h"
 #include "DNA_scene_types.h"
 #include "DNA_screen_types.h"
 #include "DNA_texture_types.h"
-#include "DNA_view3d_types.h"
-#include "DNA_world_types.h"
-#include "DNA_userdef_types.h"
 #include "DNA_property_types.h"
+#include "DNA_userdef_types.h"
+#include "DNA_view3d_types.h"
 #include "DNA_vfont_types.h"
+#include "DNA_world_types.h"
+#include "DNA_modifier_types.h"
 
 #include "BLI_blenlib.h"
 #include "BLI_arithb.h"
 #include "BLI_editVert.h"
 #include "BLI_ghash.h"
 
-#include "BKE_constraint.h"
 #include "BKE_action.h"
-#include "BKE_armature.h"
-#include "BKE_utildefines.h"
 #include "BKE_anim.h"
+#include "BKE_armature.h"
+#include "BKE_constraint.h"
 #include "BKE_blender.h"
 #include "BKE_booleanops.h"
 #include "BKE_curve.h"
 #include "BKE_displist.h"
+#include "BKE_depsgraph.h"
 #include "BKE_DerivedMesh.h"
 #include "BKE_effect.h"
 #include "BKE_font.h"
 #include "BKE_global.h"
-#include "BKE_ika.h"
 #include "BKE_ipo.h"
 #include "BKE_key.h"
 #include "BKE_lattice.h"
 #include "BKE_subsurf.h"
 #include "BKE_texture.h"
 #include "BKE_utildefines.h"
+#include "BKE_modifier.h"
 
 #include "BIF_gl.h"
 #include "BIF_graphics.h"
 #include "BIF_editconstraint.h"
 #include "BIF_editdeform.h"
 #include "BIF_editfont.h"
-#include "BIF_editika.h"
 #include "BIF_editlattice.h"
 #include "BIF_editmesh.h"
 #include "BIF_editoops.h"
 #include "BIF_resources.h"
 
 #include "BSE_edit.h"
-#include "BSE_editaction.h"
 #include "BSE_editipo.h"
 #include "BSE_filesel.h"       /* For activate_databrowse() */
 #include "BSE_view.h"
 #include "nla.h"
 
 #include "blendef.h"
-
+#include "butspace.h"
 #include "BIF_transform.h"
 
 #include "BIF_poseobject.h"
 
-/*  extern Lattice *copy_lattice(Lattice *lt); */
-extern ListBase editNurb;
-extern ListBase editelems;
-
-TransOb *transmain= 0;
-TransVert *transvmain= 0;
-int tottrans=0, transmode=0;   /* 1: texspace */
-
-float prop_size= 1.0;
-int prop_mode= 0;
-float prop_cent[3];
-
 /* used in editipo, editcurve and here */
 #define BEZSELECTED(bezt)   (((bezt)->f1 & 1) || ((bezt)->f2 & 1) || ((bezt)->f3 & 1))
 
-#define TRANS_TEX      1
-
-#define KEYFLAG_ROT            0x00000001
-#define KEYFLAG_LOC            0x00000002
-#define KEYFLAG_SIZE   0x00000004
-
-float centre[3], centroid[3];
-
-void mirrormenu(void);
-
 /* local prototypes -------------*/
-int pose_flags_reset_done(Object *); /* used in transform_generic.c */
-void figure_bone_nocalc(Object *); /* used in transform.c */
-void figure_pose_updating(void); /* used in transform.c */
-void constline_callback(void);  /* used in drawview.c */
+
 /* --------------------------------- */
 
 void add_object_draw(int type) /* for toolbox or menus, only non-editmode stuff */
@@ -207,6 +181,7 @@ void add_object_draw(int type)      /* for toolbox or menus, only non-editmode stuff
        if ELEM3(curarea->spacetype, SPACE_VIEW3D, SPACE_BUTS, SPACE_INFO) {
                if (G.obedit) exit_editmode(2); // freedata, and undo
                ob= add_object(type);
+               set_active_base(BASACT);
                base_init_from_view3d(BASACT, G.vd);
                
                /* only undo pushes on objects without editmode... */
@@ -227,6 +202,8 @@ void add_object_draw(int type)      /* for toolbox or menus, only non-editmode stuff
 
        deselect_all_area_oops();
        set_select_flag_oops();
+       
+       DAG_scene_sort(G.scene);
        allqueue(REDRAWINFO, 1);        /* 1, because header->win==0! */
 }
 
@@ -248,7 +225,7 @@ void add_objectLamp(short type)
        allqueue(REDRAWALL, 0);
 }
 
-// really bad, doesnt do constraints, that has been coded in test_scene_constraints();
+/* note: now unlinks constraints as well */
 void free_and_unlink_base(Base *base)
 {
        if (base==BASACT)
@@ -264,7 +241,6 @@ void delete_obj(int ok)
        Base *base;
        int islamp= 0;
        
-       if(G.obpose) return;
        if(G.obedit) return;
        if(G.scene->id.lib) return;
        
@@ -273,7 +249,7 @@ void delete_obj(int ok)
                Base *nbase= base->next;
 
                if TESTBASE(base) {
-                       if(ok==0 &&  (ok=okee("Erase selected"))==0) return;
+                       if(ok==0 &&  (ok=okee("Erase selected Object(s)"))==0) return;
                        if(base->object->type==OB_LAMP) islamp= 1;
                        
                        free_and_unlink_base(base);
@@ -288,10 +264,8 @@ void delete_obj(int ok)
        
        if(islamp && G.vd->drawtype==OB_SHADED) reshadeall_displist();
 
-       test_scene_constraints(); // do because of delete obj
-       
-       allqueue(REDRAWVIEW3D, 0);
        redraw_test_buttons(OBACT);
+       allqueue(REDRAWVIEW3D, 0);
        allqueue (REDRAWACTION, 0);
        allqueue(REDRAWIPO, 0);
        allqueue(REDRAWDATASELECT, 0);
@@ -299,10 +273,12 @@ void delete_obj(int ok)
        allqueue(REDRAWACTION, 0);
        allqueue(REDRAWNLA, 0);
        
+       DAG_scene_sort(G.scene);
+       
        BIF_undo_push("Delete object(s)");
 }
 
-static int return_editmesh_indexar(int **indexar, float *cent)
+static int return_editmesh_indexar(int *tot, int **indexar, float *cent)
 {
        EditMesh *em = G.editMesh;
        EditVert *eve;
@@ -314,6 +290,7 @@ static int return_editmesh_indexar(int **indexar, float *cent)
        if(totvert==0) return 0;
        
        *indexar= index= MEM_mallocN(4*totvert, "hook indexar");
+       *tot= totvert;
        nr= 0;
        cent[0]= cent[1]= cent[2]= 0.0;
        
@@ -325,27 +302,57 @@ static int return_editmesh_indexar(int **indexar, float *cent)
                nr++;
        }
        
-       VecMulf(cent, 1.0/(float)totvert);
+       VecMulf(cent, 1.0f/(float)totvert);
        
        return totvert;
 }
 
-static void select_editmesh_hook(ObHook *hook)
+static int return_editmesh_vgroup(char *name, float *cent)
+{
+       EditMesh *em = G.editMesh;
+       EditVert *eve;
+       int i, totvert=0;
+       
+       cent[0]= cent[1]= cent[2]= 0.0;
+       
+       if (G.obedit->actdef) {
+               
+               /* find the vertices */
+               for(eve= em->verts.first; eve; eve= eve->next) {
+                       for (i=0; i<eve->totweight; i++){
+                               if(eve->dw[i].def_nr == (G.obedit->actdef-1)) {
+                                       totvert++;
+                                       VecAddf(cent, cent, eve->co);
+                               }
+                       }
+               }
+               if(totvert) {
+                       bDeformGroup *defGroup = BLI_findlink(&G.obedit->defbase, G.obedit->actdef-1);
+                       strcpy(name, defGroup->name);
+                       VecMulf(cent, 1.0f/(float)totvert);
+                       return 1;
+               }
+       }
+       
+       return 0;
+}      
+
+static void select_editmesh_hook(HookModifierData *hmd)
 {
        EditMesh *em = G.editMesh;
        EditVert *eve;
        int index=0, nr=0;
        
        for(eve= em->verts.first; eve; eve= eve->next, nr++) {
-               if(nr==hook->indexar[index]) {
+               if(nr==hmd->indexar[index]) {
                        eve->f |= SELECT;
-                       if(index < hook->totindex-1) index++;
+                       if(index < hmd->totindex-1) index++;
                }
        }
        EM_select_flush();
 }
 
-static int return_editlattice_indexar(int **indexar, float *cent)
+static int return_editlattice_indexar(int *tot, int **indexar, float *cent)
 {
        BPoint *bp;
        int *index, nr, totvert=0, a;
@@ -363,6 +370,7 @@ static int return_editlattice_indexar(int **indexar, float *cent)
        if(totvert==0) return 0;
        
        *indexar= index= MEM_mallocN(4*totvert, "hook indexar");
+       *tot= totvert;
        nr= 0;
        cent[0]= cent[1]= cent[2]= 0.0;
        
@@ -379,12 +387,12 @@ static int return_editlattice_indexar(int **indexar, float *cent)
                nr++;
        }
        
-       VecMulf(cent, 1.0/(float)totvert);
+       VecMulf(cent, 1.0f/(float)totvert);
        
        return totvert;
 }
 
-static void select_editlattice_hook(ObHook *hook)
+static void select_editlattice_hook(HookModifierData *hmd)
 {
        BPoint *bp;
        int index=0, nr=0, a;
@@ -393,16 +401,16 @@ static void select_editlattice_hook(ObHook *hook)
        a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
        bp= editLatt->def;
        while(a--) {
-               if(hook->indexar[index]==nr) {
+               if(hmd->indexar[index]==nr) {
                        bp->f1 |= SELECT;
-                       if(index < hook->totindex-1) index++;
+                       if(index < hmd->totindex-1) index++;
                }
                nr++;
                bp++;
        }
 }
 
-static int return_editcurve_indexar(int **indexar, float *cent)
+static int return_editcurve_indexar(int *tot, int **indexar, float *cent)
 {
        extern ListBase editNurb;
        Nurb *nu;
@@ -433,6 +441,7 @@ static int return_editcurve_indexar(int **indexar, float *cent)
        if(totvert==0) return 0;
        
        *indexar= index= MEM_mallocN(4*totvert, "hook indexar");
+       *tot= totvert;
        nr= 0;
        cent[0]= cent[1]= cent[2]= 0.0;
        
@@ -473,12 +482,12 @@ static int return_editcurve_indexar(int **indexar, float *cent)
                }
        }
        
-       VecMulf(cent, 1.0/(float)totvert);
+       VecMulf(cent, 1.0f/(float)totvert);
        
        return totvert;
 }
 
-static void select_editcurve_hook(ObHook *hook)
+static void select_editcurve_hook(HookModifierData *hmd)
 {
        extern ListBase editNurb;
        Nurb *nu;
@@ -491,19 +500,19 @@ static void select_editcurve_hook(ObHook *hook)
                        bezt= nu->bezt;
                        a= nu->pntsu;
                        while(a--) {
-                               if(nr == hook->indexar[index]) {
+                               if(nr == hmd->indexar[index]) {
                                        bezt->f1 |= SELECT;
-                                       if(index<hook->totindex-1) index++;
+                                       if(index<hmd->totindex-1) index++;
                                }
                                nr++;
-                               if(nr == hook->indexar[index]) {
+                               if(nr == hmd->indexar[index]) {
                                        bezt->f2 |= SELECT;
-                                       if(index<hook->totindex-1) index++;
+                                       if(index<hmd->totindex-1) index++;
                                }
                                nr++;
-                               if(nr == hook->indexar[index]) {
+                               if(nr == hmd->indexar[index]) {
                                        bezt->f3 |= SELECT;
-                                       if(index<hook->totindex-1) index++;
+                                       if(index<hmd->totindex-1) index++;
                                }
                                nr++;
 
@@ -514,9 +523,9 @@ static void select_editcurve_hook(ObHook *hook)
                        bp= nu->bp;
                        a= nu->pntsu*nu->pntsv;
                        while(a--) {
-                               if(nr == hook->indexar[index]) {
+                               if(nr == hmd->indexar[index]) {
                                        bp->f1 |= SELECT;
-                                       if(index<hook->totindex-1) index++;
+                                       if(index<hmd->totindex-1) index++;
                                }
                                nr++;
                                bp++;
@@ -525,17 +534,46 @@ static void select_editcurve_hook(ObHook *hook)
        }
 }
 
+void hook_select(HookModifierData *hmd) 
+{
+       if(G.obedit->type==OB_MESH) select_editmesh_hook(hmd);
+       else if(G.obedit->type==OB_LATTICE) select_editlattice_hook(hmd);
+       else if(G.obedit->type==OB_CURVE) select_editcurve_hook(hmd);
+       else if(G.obedit->type==OB_SURF) select_editcurve_hook(hmd);
+}
+
+int hook_getIndexArray(int *tot, int **indexar, char *name, float *cent_r)
+{
+       *indexar= NULL;
+       *tot= 0;
+       name[0]= 0;
+
+       switch(G.obedit->type) {
+       case OB_MESH:
+               /* check selected vertices first */
+               if( return_editmesh_indexar(tot, indexar, cent_r)) return 1;
+               else return return_editmesh_vgroup(name, cent_r);
+       case OB_CURVE:
+       case OB_SURF:
+               return return_editcurve_indexar(tot, indexar, cent_r);
+       case OB_LATTICE:
+               return return_editlattice_indexar(tot, indexar, cent_r);
+       default:
+               return 0;
+       }
+}
+
 void add_hook(void)
 {
+       ModifierData *md = NULL;
+       HookModifierData *hmd = NULL;
        Object *ob=NULL;
-       ObHook *hook=NULL;
-       float cent[3];
-       int tot=0, *indexar, mode;
+       int mode;
 
        if(G.obedit==NULL) return;
        
-       if(G.obedit->hooks.first)
-               mode= pupmenu("Hooks %t|Add Hook, To New Empty %x1|Add Hook, To Selected Object %x2|Remove... %x3|Reassign... %x4|Select... %x5|Clear Offset...%x6");
+       if(modifiers_findByType(G.obedit, eModifierType_Hook))
+               mode= pupmenu("Hooks %t|Add, To New Empty %x1|Add, To Selected Object %x2|Remove... %x3|Reassign... %x4|Select... %x5|Clear Offset...%x6");
        else
                mode= pupmenu("Hooks %t|Add, New Empty %x1|Add, To Selected Object %x2");
 
@@ -564,7 +602,10 @@ void add_hook(void)
                char *cp;
                
                // make pupmenu with hooks
-               for(hook= G.obedit->hooks.first; hook; hook= hook->next) maxlen+=32;
+               for(md=G.obedit->modifiers.first; md; md= md->next) {
+                       if (md->type==eModifierType_Hook) 
+                               maxlen+=32;
+               }
                
                if(maxlen==0) {
                        error("Object has no hooks yet");
@@ -577,9 +618,11 @@ void add_hook(void)
                else if(mode==5) strcpy(cp, "Select %t|");
                else if(mode==6) strcpy(cp, "Clear Offset %t|");
                
-               for(hook= G.obedit->hooks.first; hook; hook= hook->next) {
-                       strcat(cp, hook->name);
-                       strcat(cp, " |");
+               for(md=G.obedit->modifiers.first; md; md= md->next) {
+                       if (md->type==eModifierType_Hook) {
+                               strcat(cp, md->name);
+                               strcat(cp, " |");
+                       }
                }
        
                nr= pupmenu(cp);
@@ -588,37 +631,39 @@ void add_hook(void)
                if(nr<1) return;
                
                a= 1;
-               for(hook= G.obedit->hooks.first; hook; hook= hook->next, a++) {
-                       if(a==nr) break;
+               for(md=G.obedit->modifiers.first; md; md=md->next) {
+                       if (md->type==eModifierType_Hook) {
+                               if(a==nr) break;
+                               a++;
+                       }
                }
-               ob= hook->parent;
+
+               hmd = (HookModifierData*) md;
+               ob= hmd->object;
        }
 
        /* do it, new hooks or reassign */
        if(mode==1 || mode==2 || mode==4) {
-       
-               switch(G.obedit->type) {
-               case OB_MESH:
-                       tot= return_editmesh_indexar(&indexar, cent);
-                       break;
-               case OB_CURVE:
-               case OB_SURF:
-                       tot= return_editcurve_indexar(&indexar, cent);
-                       break;
-               case OB_LATTICE:
-                       tot= return_editlattice_indexar(&indexar, cent);
-                       break;
-               }
+               float cent[3];
+               int tot, ok, *indexar;
+               char name[32];
                
-               if(tot==0) {
-                       error("Requires selected vertices");
+               ok = hook_getIndexArray(&tot, &indexar, name, cent);
+
+               if(ok==0) {
+                       error("Requires selected vertices or active Vertex Group");
                }
                else {
                        
                        if(mode==1) {
-                               Base *base= BASACT;
+                               Base *base= BASACT, *newbase;
 
                                ob= add_object(OB_EMPTY);
+                               /* set layers OK */
+                               newbase= BASACT;
+                               newbase->lay= base->lay;
+                               ob->lay= newbase->lay;
+                               
                                /* transform cent to global coords for loc */
                                VecMat4MulVecfl(ob->loc, G.obedit->obmat, cent);
                                
@@ -629,17 +674,23 @@ void add_hook(void)
                                                                        
                        /* new hook */
                        if(mode==1 || mode==2) {
-                               hook= MEM_callocN(sizeof(ObHook), "new hook");
-                               BLI_addtail(&G.obedit->hooks, hook);
-                               strncpy(hook->name, ob->id.name+2, 30);
-                               hook->force= 1.0;
+                               ModifierData *md = G.obedit->modifiers.first;
+
+                               while (md && modifierType_getInfo(md->type)->type==eModifierTypeType_OnlyDeform) {
+                                       md = md->next;
+                               }
+
+                               hmd = (HookModifierData*) modifier_new(eModifierType_Hook);
+                               BLI_insertlinkbefore(&G.obedit->modifiers, md, hmd);
+                               sprintf(hmd->modifier.name, "Hook-%s", ob->id.name+2);
                        }
-                       else MEM_freeN(hook->indexar); // reassign, hook was set
+                       else if (hmd->indexar) MEM_freeN(hmd->indexar); // reassign, hook was set
 
-                       hook->parent= ob;
-                       hook->indexar= indexar;
-                       VECCOPY(hook->cent, cent);
-                       hook->totindex= tot;
+                       hmd->object= ob;
+                       hmd->indexar= indexar;
+                       VECCOPY(hmd->cent, cent);
+                       hmd->totindex= tot;
+                       BLI_strncpy(hmd->name, name, 32);
                        
                        if(mode==1 || mode==2) {
                                /* matrix calculus */
@@ -650,33 +701,31 @@ void add_hook(void)
                
                                Mat4Invert(ob->imat, ob->obmat);
                                /* apparently this call goes from right to left... */
-                               Mat4MulSerie(hook->parentinv, ob->imat, G.obedit->obmat, NULL, 
+                               Mat4MulSerie(hmd->parentinv, ob->imat, G.obedit->obmat, NULL, 
                                                        NULL, NULL, NULL, NULL, NULL);
                        }
                }
        }
        else if(mode==3) { // remove
-               BLI_remlink(&G.obedit->hooks, hook);
-               MEM_freeN(hook->indexar);
-               MEM_freeN(hook);
+               BLI_remlink(&G.obedit->modifiers, md);
+               modifier_free(md);
        }
        else if(mode==5) { // select
-               if(G.obedit->type==OB_MESH) select_editmesh_hook(hook);
-               else if(G.obedit->type==OB_LATTICE) select_editlattice_hook(hook);
-               else if(G.obedit->type==OB_CURVE) select_editcurve_hook(hook);
-               else if(G.obedit->type==OB_SURF) select_editcurve_hook(hook);
+               hook_select(hmd);
        }
        else if(mode==6) { // clear offset
                where_is_object(ob);    // ob is hook->parent
 
                Mat4Invert(ob->imat, ob->obmat);
                /* this call goes from right to left... */
-               Mat4MulSerie(hook->parentinv, ob->imat, G.obedit->obmat, NULL, 
+               Mat4MulSerie(hmd->parentinv, ob->imat, G.obedit->obmat, NULL, 
                                        NULL, NULL, NULL, NULL, NULL);
        }
 
        allqueue(REDRAWVIEW3D, 0);
        allqueue(REDRAWBUTSOBJECT, 0);
+       DAG_scene_sort(G.scene);
+       
        BIF_undo_push("Add hook");
 }
 
@@ -708,7 +757,8 @@ void make_track(void)
 
                                        data = con->data;
                                        data->tar = BASACT->object;
-
+                                       base->object->recalc |= OB_RECALC;
+                                       
                                        /* Lamp and Camera track differently by default */
                                        if (base->object->type == OB_LAMP || base->object->type == OB_CAMERA) {
                                                data->reserved1 = TRACK_nZ;
@@ -721,9 +771,6 @@ void make_track(void)
                        base= base->next;
                }
 
-               test_scene_constraints();
-               allqueue(REDRAWVIEW3D, 0);
-               sort_baselist(G.scene);
        }
        else if (mode == 2){
                bConstraint *con;
@@ -738,7 +785,8 @@ void make_track(void)
 
                                        data = con->data;
                                        data->tar = BASACT->object;
-
+                                       base->object->recalc |= OB_RECALC;
+                                       
                                        /* Lamp and Camera track differently by default */
                                        if (base->object->type == OB_LAMP || base->object->type == OB_CAMERA) {
                                                data->trackflag = TRACK_nZ;
@@ -751,27 +799,24 @@ void make_track(void)
                        base= base->next;
                }
 
-               test_scene_constraints();
-               allqueue(REDRAWVIEW3D, 0);
-               sort_baselist(G.scene);
        }
        else if (mode == 3){
                base= FIRSTBASE;
                while(base) {
                        if TESTBASELIB(base) {
                                if(base!=BASACT) {
-
                                        base->object->track= BASACT->object;
+                                       base->object->recalc |= OB_RECALC;
                                }
                        }
                        base= base->next;
                }
-
-               test_scene_constraints();
-               allqueue(REDRAWVIEW3D, 0);
-               allqueue(REDRAWOOPS, 0);
-               sort_baselist(G.scene);
        }
+
+       allqueue(REDRAWOOPS, 0);
+       allqueue(REDRAWVIEW3D, 0);
+       DAG_scene_sort(G.scene);
+       
        BIF_undo_push("Make Track");
 }
 
@@ -820,32 +865,27 @@ void clear_parent(void)
        base= FIRSTBASE;
        while(base) {
                if TESTBASELIB(base) {
-                       par= 0;
+                       par= NULL;
                        if(mode==1 || mode==2) {
-                               if(base->object->type==OB_IKA) {
-                                       Ika *ika= base->object->data;
-                                       ika->parent= 0;
-                               }
                                par= base->object->parent;
-                               base->object->parent= 0;
-                       
+                               base->object->parent= NULL;
+                               base->object->recalc |= OB_RECALC;
+                               
                                if(mode==2) {
-                                       base->object->track= 0;
+                                       base->object->track= NULL;
                                        apply_obmat(base->object);
                                }
                        }
                        else if(mode==3) {
                                Mat4One(base->object->parentinv);
-                       }
-                       
-                       if(par) {
-                               makeDispList(base->object);     // just always..., checks are not available well (ton)
+                               base->object->recalc |= OB_RECALC;
                        }
                }
                base= base->next;
        }
 
-       test_scene_constraints();
+       DAG_scene_sort(G.scene);
+       DAG_scene_flush_update(G.scene, screen_view3d_layers());
        allqueue(REDRAWVIEW3D, 0);
        allqueue(REDRAWOOPS, 0);
        
@@ -867,15 +907,17 @@ void clear_track(void)
        base= FIRSTBASE;
        while(base) {
                if TESTBASELIB(base) {
-                       base->object->track= 0;
-
+                       base->object->track= NULL;
+                       base->object->recalc |= OB_RECALC;
+                       
                        if(mode==2) {
                                apply_obmat(base->object);
                        }                       
                }
                base= base->next;
        }
-       test_scene_constraints();
+
+       DAG_scene_sort(G.scene);
        allqueue(REDRAWVIEW3D, 0);
        allqueue(REDRAWOOPS, 0);
        
@@ -898,67 +940,55 @@ void clear_object(char mode)
        else if(mode=='o') str= "Clear origin";
        else return;
        
-       if (G.obpose){
-
-               switch (G.obpose->type){
-               case OB_ARMATURE:
-                       clear_armature (G.obpose, mode);
-#if 1
-                       clear_pose_constraint_status(G.obpose);
-                       make_displists_by_armature (G.obpose);
-#endif
-                       break;
-               }
-
-               allqueue(REDRAWVIEW3D, 0);
-               BIF_undo_push(str);
-               return;
-       }
-
        base= FIRSTBASE;
        while(base) {
                if TESTBASELIB(base) {
                        ob= base->object;
                        
-                       if(mode=='r') {
-                               memset(ob->rot, 0, 3*sizeof(float));
-                               memset(ob->drot, 0, 3*sizeof(float));
-                               QuatOne(ob->quat);
-                               QuatOne(ob->dquat);
+                       if(ob->flag & OB_POSEMODE) {
+                               // no test if we got armature; could be in future...
+                               clear_armature(ob, mode);
                        }
-                       else if(mode=='g') {
-                               memset(ob->loc, 0, 3*sizeof(float));
-                               memset(ob->dloc, 0, 3*sizeof(float));
-                       }
-                       else if(mode=='s') {
-                               memset(ob->dsize, 0, 3*sizeof(float));
-                               ob->size[0]= 1.0;
-                               ob->size[1]= 1.0;
-                               ob->size[2]= 1.0;
-                       }
-                       else if(mode=='o') {
-                               if(ob->parent) {
-                                       v1= ob->loc;
-                                       v3= ob->parentinv[3];
-                                       
-                                       Mat3CpyMat4(mat, ob->parentinv);
-                                       VECCOPY(v3, v1);
-                                       v3[0]= -v3[0];
-                                       v3[1]= -v3[1];
-                                       v3[2]= -v3[2];
-                                       Mat3MulVecfl(mat, v3);
+                       else if((G.f & G_WEIGHTPAINT)==0) {
+                               
+                               if(mode=='r') {
+                                       memset(ob->rot, 0, 3*sizeof(float));
+                                       memset(ob->drot, 0, 3*sizeof(float));
+                                       QuatOne(ob->quat);
+                                       QuatOne(ob->dquat);
+                               }
+                               else if(mode=='g') {
+                                       memset(ob->loc, 0, 3*sizeof(float));
+                                       memset(ob->dloc, 0, 3*sizeof(float));
+                               }
+                               else if(mode=='s') {
+                                       memset(ob->dsize, 0, 3*sizeof(float));
+                                       ob->size[0]= 1.0;
+                                       ob->size[1]= 1.0;
+                                       ob->size[2]= 1.0;
+                               }
+                               else if(mode=='o') {
+                                       if(ob->parent) {
+                                               v1= ob->loc;
+                                               v3= ob->parentinv[3];
+                                               
+                                               Mat3CpyMat4(mat, ob->parentinv);
+                                               VECCOPY(v3, v1);
+                                               v3[0]= -v3[0];
+                                               v3[1]= -v3[1];
+                                               v3[2]= -v3[2];
+                                               Mat3MulVecfl(mat, v3);
+                                       }
                                }
-                       }
-                       
-                       if(ob->parent && ob->partype==PARSKEL)
-                               freedisplist(&ob->disp);
-                       else if(ob->hooks.first)
-                               freedisplist(&ob->disp);
+                               
+                               ob->recalc |= OB_RECALC_OB;
+                       }                       
                }
                base= base->next;
        }
        
        allqueue(REDRAWVIEW3D, 0);
+       DAG_scene_flush_update(G.scene, screen_view3d_layers());
        BIF_undo_push(str);
 }
 
@@ -1023,6 +1053,7 @@ void make_vertex_parent(void)
                }
        }
        else if ELEM(G.obedit->type, OB_SURF, OB_CURVE) {
+               extern ListBase editNurb;
                nu= editNurb.first;
                while(nu) {
                        if((nu->type & 7)==CU_BEZIER) {
@@ -1069,7 +1100,9 @@ void make_vertex_parent(void)
        while(base) {
                if TESTBASELIB(base) {
                        if(base!=BASACT) {
+                               
                                ob= base->object;
+                               ob->recalc |= OB_RECALC;
                                par= BASACT->object->parent;
                                
                                while(par) {
@@ -1108,6 +1141,7 @@ void make_vertex_parent(void)
        }
        allqueue(REDRAWVIEW3D, 0);
        
+       DAG_scene_sort(G.scene);
        // BIF_undo_push(str); not, conflicts with editmode undo...
 }
 
@@ -1118,25 +1152,39 @@ int test_parent_loop(Object *par, Object *ob)
        if(par==0) return 0;
        if(ob == par) return 1;
        
-       if(par->type==OB_IKA) {
-               Ika *ika= par->data;
-               
-               if( ob == ika->parent ) return 1;
-               if( test_parent_loop(ika->parent, ob) ) return 1;
-       }
-
        return test_parent_loop(par->parent, ob);
 
 }
 
+static char *make_bone_menu (Object *ob)
+{
+       char *menustr=NULL;
+       bPoseChannel *pchan;
+       int             size;
+       int             index=0;
+       
+       //      Count the bones
+       for(size=0, pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next, size++);
+       
+       size = size*48 + 256;
+       menustr = MEM_callocN(size, "bonemenu");
+       
+       sprintf (menustr, "Select Bone%%t");
+       
+       for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next, index++) {
+               sprintf (menustr, "%s|%s%%x%d", menustr, pchan->bone->name, index);
+       }
+       
+       return menustr;
+}
+
+
 void make_parent(void)
 {
        Base *base;
        Object *par;
-       short qual, mode=0, limbnr=0, effchild=0;
-       char *bonestr=NULL;
        Bone    *bone=NULL;
-       int     bonenr;
+       short qual, mode=0;
 
        if(G.scene->id.lib) return;
        if(G.obedit) {
@@ -1149,21 +1197,43 @@ void make_parent(void)
        qual= G.qual;
        par= BASACT->object;
 
-       if(par->type == OB_CURVE){
+       if(par->type == OB_LATTICE){
+               mode= pupmenu("Make Parent %t|Normal Parent %x1|Lattice Deform %x2");
+               if(mode<=0){
+                       return;
+               }
+               else if(mode==1) {
+                       mode= PAROBJECT;
+               }
+               else if(mode==2) {
+                       mode= PARSKEL;
+               }
+       }
+       else if(par->type == OB_CURVE){
                bConstraint *con;
                bFollowPathConstraint *data;
 
-               mode= pupmenu("Make Parent %t|Normal Parent %x1|Follow Path %x2|Curve Deform %x3");
+               mode= pupmenu("Make Parent %t|Normal Parent %x1|Follow Path %x2|Curve Deform %x3|Path Constraint %x4");
                if(mode<=0){
                        return;
                }
                else if(mode==1) {
                        mode= PAROBJECT;
                }
+               else if(mode==2) {
+                       Curve *cu= par->data;
+                       
+                       mode= PAROBJECT;
+                       if((cu->flag & CU_PATH)==0) {
+                               cu->flag |= CU_PATH|CU_FOLLOW;
+                               makeDispListCurveTypes(par, 0);  // force creation of path data
+                       }
+                       else cu->flag |= CU_FOLLOW;
+               }
                else if(mode==3) {
                        mode= PARSKEL;
                }
-               else if(mode==2) {
+               else if(mode==4) {
 
                        base= FIRSTBASE;
                        while(base) {
@@ -1190,67 +1260,65 @@ void make_parent(void)
                                base= base->next;
                        }
 
-                       test_scene_constraints();
                        allqueue(REDRAWVIEW3D, 0);
-                       sort_baselist(G.scene);
+                       DAG_scene_sort(G.scene);
                        BIF_undo_push("make Parent");
                        return;
                }
        }
        else if(par->type == OB_ARMATURE){
-
-                       base= FIRSTBASE;
-                       while(base) {
-                               if TESTBASELIB(base) {
-                                       if(base!=BASACT) {
-                                               if(base->object->type==OB_MESH) {
-                                                       mode= pupmenu("Make Parent To%t|Bone %x1|Armature %x2|Object %x3");
-                                                       break;
-                                               }
-                                               else {
-                                                       mode= pupmenu("Make Parent To %t|Bone %x1|Object %x3");
-                                                       break;
-                                               }
+               int     bonenr;
+               char *bonestr=NULL;
+               
+               base= FIRSTBASE;
+               while(base) {
+                       if TESTBASELIB(base) {
+                               if(base!=BASACT) {
+                                       if(base->object->type==OB_MESH) {
+                                               mode= pupmenu("Make Parent To%t|Bone %x1|Armature %x2|Object %x3");
+                                               break;
+                                       }
+                                       else {
+                                               mode= pupmenu("Make Parent To %t|Bone %x1|Object %x3");
+                                               break;
                                        }
                                }
-                               base= base->next;
                        }
-               
-                       switch (mode){
-                       case 1:
-                               mode=PARBONE;
-                               /* Make bone popup menu */
-
-                               bonestr = make_bone_menu(get_armature(par));
-               //              if(mbutton(&bone, bonestr, 1, 24, "Bone: ")==0) {
+                       base= base->next;
+               }
+       
+               switch (mode){
+               case 1:
+                       mode=PARBONE;
+                       /* Make bone popup menu */
 
-                               bonenr= pupmenu_col(bonestr, 20);
-                               if (bonestr)
-                                       MEM_freeN (bonestr);
-                               
-                               if (bonenr==-1){
-                                       allqueue(REDRAWVIEW3D, 0);
-                                       return;
-                               }
+                       bonestr = make_bone_menu(par);
 
-                               apply_pose_armature(get_armature(par), par->pose, 0);
-                               bone=get_indexed_bone(get_armature(par), bonenr); 
-                               if (!bone){
-               //                      error ("Invalid bone!");
-                                       allqueue(REDRAWVIEW3D, 0);
-                                       return;
-                               }
+                       bonenr= pupmenu_col(bonestr, 20);
+                       if (bonestr)
+                               MEM_freeN (bonestr);
+                       
+                       if (bonenr==-1){
+                               allqueue(REDRAWVIEW3D, 0);
+                               return;
+                       }
 
-                               break;
-                       case 2:
-                               mode=PARSKEL;
-                               break;
-                       case 3:
-                               mode=PAROBJECT;
-                               break;
-                       default:
+                       bone= get_indexed_bone(par, bonenr<<16);                // function uses selection codes
+                       if (!bone){
+                               allqueue(REDRAWVIEW3D, 0);
                                return;
                        }
+
+                       break;
+               case 2:
+                       mode=PARSKEL;
+                       break;
+               case 3:
+                       mode=PAROBJECT;
+                       break;
+               default:
+                       return;
+               }
        }
        else {
                if(qual & LR_SHIFTKEY) {
@@ -1262,31 +1330,13 @@ void make_parent(void)
                        }
                        else if(okee("Make parent")==0) return;
 
-                       /* test effchild */
-                       base= FIRSTBASE;
-                       while(base) {
-                               if TESTBASELIB(base) {
-                                       if(base->object->type==OB_IKA && base->object != par) {
-                                               if(effchild==0) {
-                                                       if(okee("Effector as Child")) effchild= 1;
-                                                       else effchild= 2;
-                                               }
-                                       }
-                               }
-                               if(effchild) break;
-                               base= base->next;
-                       }
-                       
                        /* now we'll clearparentandkeeptransform all objects */
                        base= FIRSTBASE;
                        while(base) {
                                if TESTBASELIB(base) {
                                        if(base!=BASACT && base->object->parent) {
-                                               if(base->object->type==OB_IKA && effchild==1);
-                                               else {
-                                                       base->object->parent= 0;
-                                                       apply_obmat(base->object);
-                                               }
+                                               base->object->parent= NULL;
+                                               apply_obmat(base->object);
                                        }
                                }
                                base= base->next;
@@ -1294,6 +1344,7 @@ void make_parent(void)
                }
        }
        
+       par->recalc |= OB_RECALC_OB;
        
        base= FIRSTBASE;
        while(base) {
@@ -1305,13 +1356,11 @@ void make_parent(void)
                                }
                                else {
                                        
+                                       base->object->recalc |= OB_RECALC_OB|OB_RECALC_DATA;
+                                       
                                        /* the ifs below are horrible code (ton) */
                                        
-                                       if(par->type==OB_IKA){
-                                               base->object->partype= mode;
-                                               base->object->par1= limbnr;
-                                       }
-                                       else if (par->type==OB_ARMATURE){
+                                       if (par->type==OB_ARMATURE) {
                                                base->object->partype= mode;
                                                if (bone)
                                                        strcpy (base->object->parsubstr, bone->name);
@@ -1322,13 +1371,14 @@ void make_parent(void)
                                                if(qual & LR_ALTKEY) {
                                                        base->object->partype= PARVERT1;
                                                }
-                                               else if(par->type==OB_CURVE) {
+                                               else if(ELEM(par->type, OB_CURVE, OB_LATTICE)) {
                                                        base->object->partype= mode;
                                                }
                                                else {
                                                        base->object->partype= PAROBJECT;
                                                }
                                        }
+                                       
                                        base->object->parent= par;
                                        
                                        /* calculate inverse parent matrix? */
@@ -1356,11 +1406,8 @@ void make_parent(void)
                                                Mat4Invert(base->object->parentinv, workob.obmat);
                                        }
                                        
-                                       if(par->type==OB_LATTICE) makeDispList(base->object);
-                                       if(par->type==OB_CURVE && mode==PARSKEL) makeDispList(base->object);
                                        if(par->type==OB_ARMATURE && mode == PARSKEL){
                                                verify_defgroups(base->object);
-                                               makeDispList(base->object);
                                        }
                                }
                        }
@@ -1370,9 +1417,9 @@ void make_parent(void)
        allqueue(REDRAWVIEW3D, 0);
        allqueue(REDRAWOOPS, 0);
        
-       test_scene_constraints();
-       sort_baselist(G.scene);
-
+       DAG_scene_sort(G.scene);
+       DAG_scene_flush_update(G.scene, screen_view3d_layers());
+       
        BIF_undo_push("make Parent");
 }
 
@@ -1381,7 +1428,6 @@ void enter_editmode(void)
 {
        Base *base;
        Object *ob;
-       Ika *ika;
        ID *id;
        Mesh *me;
        int ok= 0;
@@ -1392,6 +1438,8 @@ void enter_editmode(void)
        if(base==0) return;
        if((G.vd==NULL || (base->lay & G.vd->lay))==0) return;
        
+       strcpy(G.editModeTitleExtra, "");
+
        ob= base->object;
        if(ob->data==0) return;
        
@@ -1426,20 +1474,6 @@ void enter_editmode(void)
                make_editArmature();
                allqueue (REDRAWVIEW3D,0);
        }
-       else if(ob->type==OB_IKA) {     /* grab type */
-               base= FIRSTBASE;
-               while(base) {
-                       if TESTBASE(base) {
-                               if(base->object->type==OB_IKA) {
-                                       ika= base->object->data;
-                                       if(ika->flag & IK_GRABEFF) ika->flag &= ~IK_GRABEFF;
-                                       else ika->flag |= IK_GRABEFF;
-                               }
-                       }
-                       base= base->next;
-               }
-               allqueue(REDRAWVIEW3D, 0);
-       }
        else if(ob->type==OB_FONT) {
                G.obedit= ob;
                ok= 1;
@@ -1468,27 +1502,17 @@ void enter_editmode(void)
                setcursor_space(SPACE_VIEW3D, CURSOR_EDIT);
        
                allqueue(REDRAWVIEW3D, 1);
+               DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
+               
        }
-       else G.obedit= 0;
+       else G.obedit= NULL;
 
-       if (G.obpose)
-               exit_posemode (1);
        scrarea_queue_headredraw(curarea);
 }
 
-void make_displists_by_parent(Object *ob) {
-       Base *base;
-       
-       for (base= FIRSTBASE; base; base= base->next)
-               if (ob==base->object->parent)
-                       makeDispList(base->object);
-}
-
 void exit_editmode(int freedata)       /* freedata==0 at render, 1= freedata, 2= do undo buffer too */
 {
-       Base *base;
        Object *ob;
-       Curve *cu;
 
        if(G.obedit==NULL) return;
 
@@ -1501,7 +1525,7 @@ void exit_editmode(int freedata)  /* freedata==0 at render, 1= freedata, 2= do un
                        error("Too many vertices");
                        return;
                }
-               load_editMesh();        /* makes new displist */
+               load_editMesh();
 
                if(freedata) free_editMesh(G.editMesh);
 
@@ -1509,14 +1533,13 @@ void exit_editmode(int freedata)        /* freedata==0 at render, 1= freedata, 2= do un
                        set_seamtface();
                        allqueue(REDRAWIMAGE, 0);
                }
-
-               build_particle_system(G.obedit);
        }
        else if (G.obedit->type==OB_ARMATURE){  
                load_editArmature();
                if (freedata) free_editArmature();
        }
        else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
+               extern ListBase editNurb;
                load_editNurb();
                if(freedata) freeNurblist(&editNurb);
        }
@@ -1528,44 +1551,25 @@ void exit_editmode(int freedata)        /* freedata==0 at render, 1= freedata, 2= do un
                if(freedata) free_editLatt();
        }
        else if(G.obedit->type==OB_MBALL) {
+               extern ListBase editelems;
                load_editMball();
                if(freedata) BLI_freelistN(&editelems);
        }
 
        ob= G.obedit;
        
-       /* displist make is different in editmode */
+       /* for example; displist make is different in editmode */
        if(freedata) G.obedit= NULL;
 
        /* total remake of softbody data */
-       if(ob->softflag & OB_SB_ENABLE) sbObjectToSoftbody(ob);
-       
-       makeDispList(ob);
-
-       /* has this influence at other objects? */
-       if(ob->type==OB_CURVE) {
-
-               /* test if ob is use as bevelcurve r textoncurve */
-               base= FIRSTBASE;
-               while(base) {
-                       if ELEM(base->object->type, OB_CURVE, OB_FONT) {
-                               cu= base->object->data;
-                               
-                               if(cu->textoncurve==ob) {
-                                       text_to_curve(base->object, 0);
-                                       makeDispList(base->object);
-                               }
-                               if(cu->bevobj==ob || cu->taperobj==ob) {
-                                       makeDispList(base->object);
-                               }
-                       }
-                       base= base->next;
+       if(modifiers_isSoftbodyEnabled(ob)) {
+               if (ob->soft && ob->soft->keys) {
+                       notice("Erased Baked SoftBody");
                }
-               
-       }
-       else if(ob->type==OB_LATTICE) {
-               make_displists_by_parent(ob);
+
+               sbObjectToSoftbody(ob);
        }
+       DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
 
        if(freedata) {
                setcursor_space(SPACE_VIEW3D, CURSOR_STD);
@@ -1604,30 +1608,42 @@ void docentre(int centremode)
        Nurb *nu, *nu1;
        EditVert *eve;
        float cent[3], centn[3], min[3], max[3], omat[3][3];
-       int a;
+       int a, total= 0;
        MVert *mvert;
 
        if(G.scene->id.lib) return;
-
+       
+       cent[0]= cent[1]= cent[2]= 0.0;
+       
        if(G.obedit) {
 
                INIT_MINMAX(min, max);
        
                if(G.obedit->type==OB_MESH) {
-                       eve= em->verts.first;
-                       while(eve) {
-                               DO_MINMAX(eve->co, min, max);
-                               eve= eve->next;
+                       for(eve= em->verts.first; eve; eve= eve->next) {
+                               if(G.vd->around==V3D_CENTROID) {
+                                       total++;
+                                       VECADD(cent, cent, eve->co);
+                               }
+                               else {
+                                       DO_MINMAX(eve->co, min, max);
+                               }
+                       }
+                       
+                       if(G.vd->around==V3D_CENTROID) {
+                               VecMulf(cent, 1.0f/(float)total);
+                       }
+                       else {
+                               cent[0]= (min[0]+max[0])/2.0f;
+                               cent[1]= (min[1]+max[1])/2.0f;
+                               cent[2]= (min[2]+max[2])/2.0f;
                        }
-                       cent[0]= (min[0]+max[0])/2.0f;
-                       cent[1]= (min[1]+max[1])/2.0f;
-                       cent[2]= (min[2]+max[2])/2.0f;
                        
-                       eve= em->verts.first;
-                       while(eve) {
+                       for(eve= em->verts.first; eve; eve= eve->next) {
                                VecSubf(eve->co, eve->co, cent);                        
-                               eve= eve->next;
                        }
+                       
+                       recalc_editnormals();
                }
        }
        
@@ -1722,17 +1738,11 @@ void docentre(int centremode)
                                                        ob= ob->id.next;
                                                }
                                        }
-                               
-                                       /* displist of all users, also this one */
-                                       makeDispList(base->object);
-                                       
-                                       /* DO: check all users... */
-                                       tex_space_mesh(me);
-               
                                }
                                else if ELEM(base->object->type, OB_CURVE, OB_SURF) {
                                                                        
                                        if(G.obedit) {
+                                               extern ListBase editNurb;
                                                nu1= editNurb.first;
                                        }
                                        else {
@@ -1792,10 +1802,8 @@ void docentre(int centremode)
                                        }
                        
                                        if(G.obedit) {
-                                               makeDispList(G.obedit);
                                                break;
                                        }
-                                       else makeDispList(base->object);
        
                                }
                                else if(base->object->type==OB_FONT) {
@@ -1810,12 +1818,10 @@ void docentre(int centremode)
                                        /* not really ok, do this better once! */
                                        cu->xof /= cu->fsize;
                                        cu->yof /= cu->fsize;
-                                       
-                                       text_to_curve(base->object, 0);
-                                       makeDispList(base->object);
-                                       
+
                                        allqueue(REDRAWBUTSEDIT, 0);
                                }
+                               DAG_object_flush_update(G.scene, base->object, OB_RECALC_OB|OB_RECALC_DATA);
                        }
                }
                base= base->next;
@@ -1891,18 +1897,48 @@ void movetolayer(void)
        BIF_undo_push("Move to layer");
 }
 
+void split_font()
+{
+       Object *ob = OBACT;
+       Base *oldbase = BASACT;
+       Curve *cu= ob->data;
+       char *p= cu->str;
+       int slen= strlen(p);
+       int i;
+
+       for (i = 0; i<=slen; p++, i++) {
+               adduplicate(1);
+               cu= OBACT->data;
+               cu->sepchar = i+1;
+               text_to_curve(OBACT, 0);        // pass 1: only one letter, adapt position
+               text_to_curve(OBACT, 0);        // pass 2: remake
+               freedisplist(&OBACT->disp);
+               makeDispListCurveTypes(OBACT, 0);
+               
+               OBACT->flag &= ~SELECT;
+               BASACT->flag &= ~SELECT;
+               oldbase->flag |= SELECT;
+               oldbase->object->flag |= SELECT;
+               set_active_base(oldbase);               
+       }
+}
 
 void special_editmenu(void)
 {
-       extern short editbutflag;
-       extern float doublimit;
+       Object *ob= OBACT;
        float fac;
        int nr,ret;
-       short randfac;
+       short randfac,numcuts;
        
-       if(G.obedit==0) {
-               if(G.f & G_FACESELECT) {
-                       Mesh *me= get_mesh(OBACT);
+       if(ob==NULL) return;
+       
+       if(G.obedit==NULL) {
+               
+               if(ob->flag & OB_POSEMODE) {
+                       pose_special_editmenu();
+               }
+               else if(G.f & G_FACESELECT) {
+                       Mesh *me= get_mesh(ob);
                        TFace *tface;
                        int a;
                        
@@ -1938,12 +1974,13 @@ void special_editmenu(void)
                                        }
                                }
                        }
+                       DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
                        allqueue(REDRAWVIEW3D, 0);
                        allqueue(REDRAWBUTSEDIT, 0);
                        BIF_undo_push("Change texture face");
                }
                else if(G.f & G_VERTEXPAINT) {
-                       Mesh *me= get_mesh(OBACT);
+                       Mesh *me= get_mesh(ob);
                        
                        if(me==0 || (me->mcol==NULL && me->tface==NULL) ) return;
                        
@@ -1957,18 +1994,31 @@ void special_editmenu(void)
                                
                                if(me->tface) mcol_to_tface(me, 1);
                                BIF_undo_push("Shared VertexCol");
+
+                               DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+                       }
+               }
+               else if(G.f & G_WEIGHTPAINT) {
+                       if(ob->parent && (ob->parent->flag & OB_POSEMODE)) {
+                               nr= pupmenu("Specials%t|Apply Bone Envelopes to VertexGroups %x1");
+                               if(nr==1) {
+                                       Mesh *me= ob->data;
+                                       if(me->dvert) copy_wpaint_undo(me->dvert, me->totvert);
+                                       pose_adds_vgroups(ob);
+                               }
                        }
                }
                else {
                        Base *base, *base_select= NULL;
-
+                       
                        // Get the active object mesh.
-                       Mesh *me= get_mesh(OBACT);
+                       Mesh *me= get_mesh(ob);
 
-                       // If the active object is a mesh...
-                       if (me) {
+                       // Booleans, if the active object is a mesh...
+                       if (me && ob->id.lib==NULL) {
+                               
                                // Bring up a little menu with the boolean operation choices on.
-                               nr= pupmenu("Boolean %t|Intersect%x1|Union%x2|Difference%x3");
+                               nr= pupmenu("Boolean Tools%t|Intersect%x1|Union%x2|Difference%x3|Add Intersect Modifier%x4|Add Union Modifier%x5|Add Difference Modifier%x6");
 
                                if (nr > 0) {
                                        // user has made a choice of a menu element.
@@ -1976,27 +2026,38 @@ void special_editmenu(void)
                                        // we search through the object list to find the other 
                                        // selected item and make sure it is distinct and a mesh.
 
-                                       base= FIRSTBASE;
-                                       while(base) {
-                                               if(base->flag & SELECT) {
-                                                       if(base->object != OBACT) base_select= base;
+                                       for(base= FIRSTBASE; base; base= base->next) {
+                                               if TESTBASELIB(base) {
+                                                       if(base->object != ob) base_select= base;
                                                }
-
-                                               base= base->next;
                                        }
 
                                        if (base_select) {
                                                if (get_mesh(base_select->object)) {
-                                                       waitcursor(1);
-                                                       ret = NewBooleanMesh(BASACT,base_select,nr);
-                                                       if (ret==0) {
-                                                               error("An internal error occurred -- sorry!");
-                                                       } else if(ret==-1) {
-                                                               error("Selected meshes must have faces to perform boolean operations");
-                                                       }
-                                                       else BIF_undo_push("Boolean");
-
-                                                       waitcursor(0);
+                                                       if(nr <= 3){
+                                                               waitcursor(1);
+                                                               ret = NewBooleanMesh(BASACT,base_select,nr);
+                                                               if (ret==0) {
+                                                                       error("An internal error occurred -- sorry!");
+                                                               } else if(ret==-1) {
+                                                                       error("Selected meshes must have faces to perform boolean operations");
+                                                               }
+                                                               else BIF_undo_push("Boolean");
+                                                               waitcursor(0);
+                                                       } else {
+                                                               BooleanModifierData *bmd = NULL;
+                                                               bmd = (BooleanModifierData *)modifier_new(eModifierType_Boolean);
+                                                               BLI_addtail(&ob->modifiers, bmd);
+                                                               bmd->object = base_select->object;
+                                                               bmd->modifier.mode |= eModifierMode_Realtime;
+                                                               switch(nr){
+                                                                       case 4: bmd->operation = eBooleanModifierOp_Intersect; break;
+                                                                       case 5: bmd->operation = eBooleanModifierOp_Union; break;
+                                                                       case 6: bmd->operation = eBooleanModifierOp_Difference; break;
+                                                               }
+                                                               do_common_editbuts(B_CHANGEDEP);
+                                                               BIF_undo_push("Add Boolean modifier");                                                          
+                                                       }                                                               
                                                } else {
                                                        error("Please select 2 meshes");
                                                }
@@ -2007,34 +2068,51 @@ void special_editmenu(void)
 
                                allqueue(REDRAWVIEW3D, 0);
                        }
+                       else if (ob->type == OB_FONT) {
+                               nr= pupmenu("Split %t|Characters%x1");
+                               if (nr > 0) {
+                                       switch(nr) {
+                                               case 1: split_font();
+                                       }
+                               }
+                       }                       
                }
        }
        else if(G.obedit->type==OB_MESH) {
 
-               nr= pupmenu("Specials%t|Subdivide%x1|Subdivide Fractal%x2|Subdivide Smooth%x3|Merge%x4|Remove Doubles%x5|Hide%x6|Reveal%x7|Select Swap%x8|Flip Normals %x9|Smooth %x10|Bevel %x11");
-               if(nr>0) waitcursor(1);
+               nr= pupmenu("Specials%t|Subdivide%x1|Subdivide Multi%x2|Subdivide Multi Fractal%x3|Subdivide Multi Smooth - WIP%x12|Subdivide Smooth Old%x13|Merge%x4|Remove Doubles%x5|Hide%x6|Reveal%x7|Select Swap%x8|Flip Normals %x9|Smooth %x10|Bevel %x11|Set Smooth %x14|Set Solid %x15");
                
                switch(nr) {
                case 1:
-                       subdivideflag(1, 0.0, editbutflag);
-                       BIF_undo_push("Subdivide");
+                       numcuts = 1;
+                       waitcursor(1);
+                       esubdivideflag(1, 0.0, G.scene->toolsettings->editbutflag,numcuts,0);
+                       
+                       BIF_undo_push("ESubdivide Single");            
                        break;
                case 2:
+               numcuts = 2;
+                       if(button(&numcuts, 1, 128, "Number of Cuts:")==0) return;
+                       waitcursor(1);
+                       esubdivideflag(1, 0.0, G.scene->toolsettings->editbutflag,numcuts,0);
+                       BIF_undo_push("ESubdivide");
+                       break;
+               case 3:
+                       numcuts = 2;
+                       if(button(&numcuts, 1, 128, "Number of Cuts:")==0) return;
+                       waitcursor(1);
                        randfac= 10;
                        if(button(&randfac, 1, 100, "Rand fac:")==0) return;
                        fac= -( (float)randfac )/100;
-                       subdivideflag(1, fac, editbutflag);
+                       esubdivideflag(1, fac, G.scene->toolsettings->editbutflag,numcuts,0);
                        BIF_undo_push("Subdivide Fractal");
                        break;
-               case 3:
-                       subdivideflag(1, 0.0, editbutflag | B_SMOOTH);
-                       BIF_undo_push("Subdivide Smooth");
-                       break;
+
                case 4:
                        mergemenu();
                        break;
                case 5:
-                       notice("Removed %d Vertices", removedoublesflag(1, doublimit));
+                       notice("Removed %d Vertices", removedoublesflag(1, G.scene->toolsettings->doublimit));
                        BIF_undo_push("Remove Doubles");
                        break;
                case 6:
@@ -2056,9 +2134,27 @@ void special_editmenu(void)
                case 11:
                        bevel_menu();
                        break;
-               }               
+               case 12:
+                       numcuts = 2;
+                       if(button(&numcuts, 1, 128, "Number of Cuts:")==0) return;
+                       waitcursor(1);
+                       esubdivideflag(1, 0.0, G.scene->toolsettings->editbutflag | B_SMOOTH,numcuts,0);
+                       BIF_undo_push("Subdivide Smooth");
+                       break;          
+               case 13:
+                       waitcursor(1);
+                       subdivideflag(1, 0.0, G.scene->toolsettings->editbutflag | B_SMOOTH);
+                       BIF_undo_push("Subdivide Smooth");
+                       break;
+               case 14:
+                       mesh_set_smooth_faces(1);
+                       break;
+               case 15: 
+                       mesh_set_smooth_faces(0);
+                       break;
+               }
                
-               makeDispList(G.obedit);
+               DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
                
                if(nr>0) waitcursor(0);
                
@@ -2075,6 +2171,15 @@ void special_editmenu(void)
                        switchdirectionNurb2();
                        break;
                }
+               
+               DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
+       }
+       else if(G.obedit->type==OB_ARMATURE) {
+               nr= pupmenu("Specials%t|Subdivide %x1|Flip Left-Right Names%x2");
+               if(nr==1)
+                       subdivide_armature();
+               else if(nr==2)
+                       armature_flip_names();
        }
 
        countall();
@@ -2116,8 +2221,8 @@ void convertmenu(void)
                nr= pupmenu("Convert Nurbs Surface to%t|Mesh");
                if(nr>0) ok= 1;
        }
-       else if(ob->type==OB_MESH && mesh_uses_displist((Mesh*) ob->data)) {
-               nr= pupmenu("Convert SubSurf to%t|Mesh (Keep Original)%x1|Mesh (Delete Original)%x2");
+       else if(ob->type==OB_MESH) {
+               nr= pupmenu("Convert Modifiers to%t|Mesh (Keep Original)%x1|Mesh (Delete Original)%x2");
                if(nr>0) ok= 1;
        }
        if(ok==0) return;
@@ -2142,51 +2247,41 @@ void convertmenu(void)
                        if(ob->flag & OB_DONE);
                        else if(ob->type==OB_MESH) {
                                Mesh *oldme= ob->data;
-                               
-                               if (mesh_uses_displist(oldme)) {
-                                       DispListMesh *dlm;
-                                       DerivedMesh *dm;
+                               DispListMesh *dlm;
+                               DerivedMesh *dm;
 
-                                       basedel = base;
+                               basedel = base;
 
-                                       ob->flag |= OB_DONE;
+                               ob->flag |= OB_DONE;
 
-                                       ob1= copy_object(ob);
+                               ob1= copy_object(ob);
+                               ob1->recalc |= OB_RECALC;
+                               object_free_modifiers(ob1);
 
-                                       basen= MEM_mallocN(sizeof(Base), "duplibase");
-                                       *basen= *base;
-                                       BLI_addhead(&G.scene->base, basen);     /* addhead: otherwise eternal loop */
-                                       basen->object= ob1;
-                                       basen->flag &= ~SELECT;
-                                               
-                                       me= ob1->data;
-                                       me->id.us--;
-                                               
-                                       ob1->data= add_mesh();
-                                       G.totmesh++;
-                                       ob1->type= OB_MESH;
-
-                                       me= ob1->data;
-                                       me->totcol= oldme->totcol;
-                                       if(ob1->totcol) {
-                                               me->mat= MEM_dupallocN(oldme->mat);
-                                               for(a=0; a<ob1->totcol; a++) id_us_plus((ID *)me->mat[a]);
-                                       }
+                               basen= MEM_mallocN(sizeof(Base), "duplibase");
+                               *basen= *base;
+                               BLI_addhead(&G.scene->base, basen);     /* addhead: otherwise eternal loop */
+                               basen->object= ob1;
+                               basen->flag &= ~SELECT;
                                        
-                                       dm= subsurf_make_derived_from_mesh(oldme, oldme->subdiv);
-                                       dlm= dm->convertToDispListMesh(dm);
-                                       dm->release(dm);
-
-                                       displistmesh_to_mesh(dlm, ob1->data);
-                                       displistmesh_free(dlm);
-
-                                       /* texspace and normals */
-                                       BASACT= basen;
-                                       enter_editmode();
-                                       exit_editmode(1); // freedata, but no undo
-                                       BASACT= basact;
+                               me= ob1->data;
+                               me->id.us--;
                                        
+                               ob1->data= add_mesh();
+                               G.totmesh++;
+                               ob1->type= OB_MESH;
+
+                               me= ob1->data;
+                               me->totcol= oldme->totcol;
+                               if(ob1->totcol) {
+                                       me->mat= MEM_dupallocN(oldme->mat);
+                                       for(a=0; a<ob1->totcol; a++) id_us_plus((ID *)me->mat[a]);
                                }
+
+                               dm= mesh_create_derived_no_deform(ob, NULL);
+                               dlm= dm->convertToDispListMesh(dm, 0);
+                               displistmesh_to_mesh(dlm, ob1->data);
+                               dm->release(dm);
                        }
                        else if(ob->type==OB_FONT) {
                                if(nr==1) {
@@ -2200,11 +2295,26 @@ void convertmenu(void)
                                                cu->vfont->id.us--;
                                                cu->vfont= 0;
                                        }
+                                       if(cu->vfontb) {
+                                               cu->vfontb->id.us--;
+                                               cu->vfontb= 0;
+                                       }
+                                       if(cu->vfonti) {
+                                               cu->vfonti->id.us--;
+                                               cu->vfonti= 0;
+                                       }
+                                       if(cu->vfontbi) {
+                                               cu->vfontbi->id.us--;
+                                               cu->vfontbi= 0;
+                                       }                                       
                                        /* other users */
                                        if(cu->id.us>1) {
                                                ob1= G.main->object.first;
                                                while(ob1) {
-                                                       if(ob1->data==cu) ob1->type= OB_CURVE;
+                                                       if(ob1->data==cu) {
+                                                               ob1->type= OB_CURVE;
+                                                               ob1->recalc |= OB_RECALC;
+                                                       }
                                                        ob1= ob1->id.next;
                                                }
                                        }
@@ -2217,7 +2327,7 @@ void convertmenu(void)
                                        cu= ob->data;
                                        
                                        dl= cu->disp.first;
-                                       if(dl==0) makeDispList(ob);
+                                       if(dl==0) makeDispListCurveTypes(ob, 0);                // force creation
 
                                        nurbs_to_mesh(ob); /* also does users */
 
@@ -2226,7 +2336,7 @@ void convertmenu(void)
                                        enter_editmode();
                                        exit_editmode(1); // freedata, but no undo
                                        BASACT= basact;
-                               }
+                               }
                        }
                        else if(ob->type==OB_MBALL) {
                        
@@ -2239,6 +2349,7 @@ void convertmenu(void)
                                                ob->flag |= OB_DONE;
 
                                                ob1= copy_object(ob);
+                                               ob1->recalc |= OB_RECALC;
 
                                                basen= MEM_mallocN(sizeof(Base), "duplibase");
                                                *basen= *base;
@@ -2261,7 +2372,6 @@ void convertmenu(void)
                                                }
                                                
                                                mball_to_mesh(&ob->disp, ob1->data);
-                                               tex_space_mesh(me);
                                        }
                                }
                        }
@@ -2271,14 +2381,14 @@ void convertmenu(void)
                        free_and_unlink_base(basedel);  
                basedel = NULL;                         
        }
-       
-       test_scene_constraints();       // always call after delete object
-       
+
        countall();
        allqueue(REDRAWVIEW3D, 0);
        allqueue(REDRAWOOPS, 0);
        allqueue(REDRAWBUTSEDIT, 0);
        BIF_undo_push("Convert Object");
+
+       DAG_scene_sort(G.scene);
 }
 
        /* Change subdivision properties of mesh object ob, if
@@ -2286,23 +2396,41 @@ void convertmenu(void)
         */
 void flip_subdivison(Object *ob, int level)
 {
-       Mesh *me = ob->data;
+       ModifierData *md = modifiers_findByType(ob, eModifierType_Subsurf);
 
-       if (level == -1) {
-               me->flag ^= ME_SUBSURF;
+       if (md) {
+               SubsurfModifierData *smd = (SubsurfModifierData*) md;
+
+               if (level == -1) {
+                       if (smd->modifier.mode&(eModifierMode_Render|eModifierMode_Realtime)) {
+                               smd->modifier.mode &= ~(eModifierMode_Render|eModifierMode_Realtime);
+                       } else {
+                               smd->modifier.mode |= (eModifierMode_Render|eModifierMode_Realtime);
+                       }
+               } else {
+                       smd->levels = level;
+               }
        } else {
-               me->subdiv = level;
+               SubsurfModifierData *smd = (SubsurfModifierData*) modifier_new(eModifierType_Subsurf);
+
+               BLI_addtail(&ob->modifiers, smd);
+
+               if (level!=-1) {
+                       smd->levels = level;
+               }
        }
 
+       countall();
        allqueue(REDRAWVIEW3D, 0);
        allqueue(REDRAWOOPS, 0);
        allqueue(REDRAWBUTSEDIT, 0);
-       makeDispList(ob);
+       allqueue(REDRAWBUTSOBJECT, 0);
+       DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
        
        BIF_undo_push("Switch subsurf on/off");
 }
  
-void copymenu_properties(Object *ob)
+static void copymenu_properties(Object *ob)
 {      
        bProperty *prop, *propn, *propc;
        Base *base;
@@ -2368,7 +2496,7 @@ void copymenu_properties(Object *ob)
        BIF_undo_push("Copy properties");
 }
 
-void copymenu_logicbricks(Object *ob)
+static void copymenu_logicbricks(Object *ob)
 {
        Base *base;
        
@@ -2402,11 +2530,79 @@ void copymenu_logicbricks(Object *ob)
        BIF_undo_push("Copy logic");
 }
 
+static void copymenu_modifiers(Object *ob)
+{
+       char str[512];
+       int i, event;
+       Base *base;
+
+       strcpy(str, "Copy Modifiers %t");
+
+       sprintf(str+strlen(str), "|All%%x%d|%%l", NUM_MODIFIER_TYPES);
+
+       for (i=eModifierType_None+1; i<NUM_MODIFIER_TYPES; i++) {
+               ModifierTypeInfo *mti = modifierType_getInfo(i);
+
+               if (ELEM(i, eModifierType_Hook, eModifierType_Softbody)) continue;
+
+               if (    (mti->flags&eModifierTypeFlag_AcceptsCVs) || 
+                               (ob->type==OB_MESH && (mti->flags&eModifierTypeFlag_AcceptsMesh))) {
+                       sprintf(str+strlen(str), "|%s%%x%d", mti->name, i);
+               }
+       }
+
+       event = pupmenu(str);
+       if(event<=0) return;
+
+       for (base= FIRSTBASE; base; base= base->next) {
+               if(base->object != ob) {
+                       if(TESTBASELIB(base)) {
+                               ModifierData *md;
+
+                               base->object->recalc |= OB_RECALC_OB|OB_RECALC_DATA;
+
+                               if (base->object->type==OB_MESH) {
+                                       if (event==NUM_MODIFIER_TYPES) {
+                                               object_free_modifiers(base->object);
+
+                                               for (md=ob->modifiers.first; md; md=md->next) {
+                                                       if (md->type!=eModifierType_Hook) {
+                                                               ModifierData *nmd = modifier_new(md->type);
+                                                               modifier_copyData(md, nmd);
+                                                               BLI_addtail(&base->object->modifiers, nmd);
+                                                       }
+                                               }
+                                       } else {
+                                               ModifierData *md = modifiers_findByType(ob, event);
+
+                                               if (md) {
+                                                       ModifierData *tmd = modifiers_findByType(base->object, event);
+
+                                                       if (!tmd) {
+                                                               tmd = modifier_new(event);
+                                                               BLI_addtail(&base->object->modifiers, tmd);
+                                                       }
+
+                                                       modifier_copyData(md, tmd);
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+                               
+       allqueue(REDRAWVIEW3D, 0);
+       allqueue(REDRAWBUTSOBJECT, 0);
+       DAG_scene_sort(G.scene);
+       
+       BIF_undo_push("Copy modifiers");
+}
+
 void copy_attr_menu()
 {
        Object *ob;
        short event;
-       char str[256];
+       char str[512];
 
        /* If you change this menu, don't forget to update the menu in header_view3d.c
         * view3d_edit_object_copyattrmenu() and in toolbox.c
@@ -2423,6 +2619,10 @@ void copy_attr_menu()
        
        if(ob->type == OB_FONT) strcat(str, "|Font Settings%x18|Bevel Settings%x19");
        if(ob->type == OB_CURVE) strcat(str, "|Bevel Settings%x19");
+       
+       if((ob->type == OB_FONT) || (ob->type == OB_CURVE)) {
+                       strcat(str, "|Curve Resolution%x25");
+       }
 
        if(ob->type==OB_MESH){
                strcat(str, "|Subdiv%x21");
@@ -2430,6 +2630,12 @@ void copy_attr_menu()
 
        if( give_parteff(ob) ) strcat(str, "|Particle Settings%x20");
 
+       if(ob->soft) strcat(str, "|Soft Body Settings%x23");
+       
+       if(ob->type==OB_MESH){
+               strcat(str, "|Modifiers ...%x24");
+       }
+
        event= pupmenu(str);
        if(event<= 0) return;
        
@@ -2441,6 +2647,7 @@ void copy_attr(short event)
        Object *ob, *obt;
        Base *base;
        Curve *cu, *cu1;
+       Nurb *nu;
        void *poin1, *poin2=0;
        
        if(G.scene->id.lib) return;
@@ -2466,11 +2673,16 @@ void copy_attr(short event)
                copymenu_logicbricks(ob);
                return;
        }
+       else if(event==24) {
+               copymenu_modifiers(ob);
+               return;
+       }
 
        base= FIRSTBASE;
        while(base) {
                if(base != BASACT) {
                        if(TESTBASELIB(base)) {
+                               base->object->recalc |= OB_RECALC_OB;
                                
                                if(event==1) {  /* loc */
                                        VECCOPY(base->object->loc, ob->loc);
@@ -2489,7 +2701,7 @@ void copy_attr(short event)
                                else if(event==4) {  /* drawtype */
                                        base->object->dt= ob->dt;
                                        base->object->dtx= ob->dtx;
-                                       }
+                               }
                                else if(event==5) {  /* time offs */
                                        base->object->sf= ob->sf;
                                }
@@ -2519,7 +2731,7 @@ void copy_attr(short event)
                                        if(poin1) {
                                                memcpy(poin1, poin2, 4+12+12+12);
                                        
-                                               if(obt->type==OB_MESH) tex_space_mesh(obt->data);
+                                               if(obt->type==OB_MESH) ;
                                                else if(obt->type==OB_MBALL) tex_space_mball(obt);
                                                else tex_space_curve(obt->data);
                                        }
@@ -2541,11 +2753,22 @@ void copy_attr(short event)
                                                if(cu1->vfont) cu1->vfont->id.us--;
                                                cu1->vfont= cu->vfont;
                                                id_us_plus((ID *)cu1->vfont);
-                                               text_to_curve(base->object, 0);
+                                               if(cu1->vfontb) cu1->vfontb->id.us--;
+                                               cu1->vfontb= cu->vfontb;
+                                               id_us_plus((ID *)cu1->vfontb);
+                                               if(cu1->vfonti) cu1->vfonti->id.us--;
+                                               cu1->vfonti= cu->vfonti;
+                                               id_us_plus((ID *)cu1->vfonti);
+                                               if(cu1->vfontbi) cu1->vfontbi->id.us--;
+                                               cu1->vfontbi= cu->vfontbi;
+                                               id_us_plus((ID *)cu1->vfontbi);                                         
+
+                                               text_to_curve(base->object, 0);         // needed?
+
                                                
                                                strcpy(cu1->family, cu->family);
                                                
-                                               makeDispList(base->object);
+                                               base->object->recalc |= OB_RECALC_DATA;
                                        }
                                }
                                else if(event==19) {    /* bevel settings */
@@ -2561,7 +2784,25 @@ void copy_attr(short event)
                                                cu1->ext1= cu->ext1;
                                                cu1->ext2= cu->ext2;
                                                
-                                               makeDispList(base->object);
+                                               base->object->recalc |= OB_RECALC_DATA;
+                                       }
+                               }
+                               else if(event==25) {    /* curve resolution */
+
+                                       if ELEM(base->object->type, OB_CURVE, OB_FONT) {
+                                               cu= ob->data;
+                                               cu1= base->object->data;
+                                               
+                                               cu1->resolu= cu->resolu;
+                                               
+                                               nu= cu1->nurb.first;
+                                               
+                                               while(nu) {
+                                                       nu->resolu= cu1->resolu;
+                                                       nu= nu->next;
+                                               }
+                                               
+                                               base->object->recalc |= OB_RECALC_DATA;
                                        }
                                }
                                else if(event==20) {    /* particle settings */
@@ -2592,17 +2833,22 @@ void copy_attr(short event)
                                }
                                else if(event==21){
                                        if (base->object->type==OB_MESH) {
-                                               Mesh *targetme= base->object->data;
-                                               Mesh *sourceme= ob->data;
-
-                                               targetme->flag= (targetme->flag&~ME_SUBSURF) | (sourceme->flag&ME_SUBSURF);
-                                               targetme->subsurftype = sourceme->subsurftype;
-                                               targetme->subdiv= sourceme->subdiv;
-                                               targetme->subdivr= sourceme->subdivr;
-                                               makeDispList(base->object);
+                                               ModifierData *md = modifiers_findByType(ob, eModifierType_Subsurf);
+
+                                               if (md) {
+                                                       ModifierData *tmd = modifiers_findByType(base->object, eModifierType_Subsurf);
+
+                                                       if (!tmd) {
+                                                               tmd = modifier_new(eModifierType_Subsurf);
+                                                               BLI_addtail(&base->object->modifiers, tmd);
+                                                       }
+
+                                                       modifier_copyData(md, tmd);
+                                                       base->object->recalc |= OB_RECALC_DATA;
+                                               }
                                        }
                                }
-                               else if(event==22){
+                               else if(event==22) {
                                        /* Clear the constraints on the target */
                                        free_constraints(&base->object->constraints);
                                        free_constraint_channels(&base->object->constraintChannels);
@@ -2612,9 +2858,17 @@ void copy_attr(short event)
                                        if (U.dupflag& USER_DUP_IPO)
                                                copy_constraint_channels(&base->object->constraintChannels, &ob->constraintChannels);
                                        else
-                                               clone_constraint_channels (&base->object->constraintChannels, &ob->constraintChannels, NULL);
+                                               clone_constraint_channels (&base->object->constraintChannels, &ob->constraintChannels);
+                               }
+                               else if(event==23) {
+                                       base->object->softflag= ob->softflag;
+                                       if(base->object->soft) sbFree(base->object->soft);
+                                       
+                                       base->object->soft= copy_softbody(ob->soft);
 
-                                       base->object->activecon = NULL;
+                                       if (!modifiers_findByType(base->object, eModifierType_Softbody)) {
+                                               BLI_addhead(&base->object->modifiers, modifier_new(eModifierType_Softbody));
+                                       }
                                }
                        }
                }
@@ -2622,6 +2876,8 @@ void copy_attr(short event)
        }
        
        allqueue(REDRAWVIEW3D, 0);
+       DAG_scene_flush_update(G.scene, screen_view3d_layers());
+
        if(event==20) {
                allqueue(REDRAWBUTSOBJECT, 0);
        }
@@ -2773,6 +3029,8 @@ void make_links(short event)
                                                        
                                                        /* if amount of material indices changed: */
                                                        test_object_materials(obt->data);
+
+                                                       obt->recalc |= OB_RECALC_DATA;
                                                }
                                        }
                                else if(event==4) {  /* ob ipo */
@@ -2841,7 +3099,9 @@ void make_links(short event)
        allqueue(REDRAWVIEW3D, 0);
        allqueue(REDRAWOOPS, 0);
        allqueue(REDRAWBUTSHEAD, 0);
-       
+
+       DAG_scene_flush_update(G.scene, screen_view3d_layers());
+
        BIF_undo_push("Create links");
 }
 
@@ -3047,3702 +3307,202 @@ void apply_object()
 
 /* ************ GENERAL  *************** */
 
-static Object *is_a_parent_selected_int(Object *startob, Object *ob, GHash *done_hash) {
-       if (ob!=startob && TESTBASE(ob))
-               return ob;
-               
-       if (BLI_ghash_haskey(done_hash, ob))
-               return NULL;
-       else
-               BLI_ghash_insert(done_hash, ob, NULL);
-       
-       if (ob->parent) {
-               Object *par= is_a_parent_selected_int(startob, ob->parent, done_hash);
-               if (par)
-                       return par;
-       }
 
-       /* IK is more complex in parents... */
-       
-       /* XXX, should we be handling armatures or constraints here? - zr */
+/* now only used in 2d spaces, like ipo, nla, sima... */
+void apply_keyb_grid(float *val, float fac1, float fac2, float fac3, int invert)
+{
+       /* fac1 is for 'nothing', fac2 for CTRL, fac3 for SHIFT */
+       int ctrl;
 
-       if(ob->type==OB_IKA) {
-               Ika *ika= ob->data;
-               
-               if (ika->def) {
-                       int i;
-                       
-                       for (i=0; i<ika->totdef; i++) {
-                               Deform *def= &ika->def[i];
-                               
-                               if (def->ob && ob!=def->ob && def->ob!=startob) {
-                                       Object *par= is_a_parent_selected_int(startob, def->ob, done_hash);
-                                       if (par)
-                                               return par;
-                               }
-                       }
-               }
-               
-               if (ika->parent) {
-                       Object *par= is_a_parent_selected_int(startob, ika->parent, done_hash);
-                       if (par)
-                               return par;
-               }
+       if(invert) {
+               if(G.qual & LR_CTRLKEY) ctrl= 0;
+               else ctrl= 1;
+       }
+       else ctrl= (G.qual & LR_CTRLKEY);
+
+       if(ctrl && (G.qual & LR_SHIFTKEY)) {
+               if(fac3!= 0.0) *val= fac3*floor(*val/fac3 +.5);
+       }
+       else if(ctrl) {
+               if(fac2!= 0.0) *val= fac2*floor(*val/fac2 +.5);
+       }
+       else {
+               if(fac1!= 0.0) *val= fac1*floor(*val/fac1 +.5);
        }
-       
-       return NULL;
 }
 
-static Object *is_a_parent_selected(Object *ob) {
-       GHash *gh= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
-       Object *res= is_a_parent_selected_int(ob, ob, gh);
-       BLI_ghash_free(gh, NULL, NULL);
+/* exported to transform.c */
+void compatible_eul(float *eul, float *oldrot)
+{
+       float dx, dy, dz;
        
-       return res;
-}
+       /* correct differences of about 360 degrees first */
 
-/*** POSE FIGURIN' -- START ***/
+       dx= eul[0] - oldrot[0];
+       dy= eul[1] - oldrot[1];
+       dz= eul[2] - oldrot[2];
 
-static void clear_pose_update_flag(Object *ob) {
-       /* Clear the flag for each pose channel that indicates that
-        * pose should be updated on every redraw
-        */
-       bPoseChannel *chan;
+       while( fabs(dx) > 5.1) {
+               if(dx > 0.0) eul[0] -= 2.0*M_PI; else eul[0]+= 2.0*M_PI;
+               dx= eul[0] - oldrot[0];
+       }
+       while( fabs(dy) > 5.1) {
+               if(dy > 0.0) eul[1] -= 2.0*M_PI; else eul[1]+= 2.0*M_PI;
+               dy= eul[1] - oldrot[1];
+       }
+       while( fabs(dz) > 5.1 ) {
+               if(dz > 0.0) eul[2] -= 2.0*M_PI; else eul[2]+= 2.0*M_PI;
+               dz= eul[2] - oldrot[2];
+       }
        
-       if (ob->pose) {
-               for (chan = ob->pose->chanbase.first; chan; 
-                        chan=chan->next){
-                       chan->flag &= ~PCHAN_TRANS_UPDATE;
-               }
+       /* is 1 of the axis rotations larger than 180 degrees and the other small? NO ELSE IF!! */      
+       if( fabs(dx) > 3.2 && fabs(dy)<1.6 && fabs(dz)<1.6 ) {
+               if(dx > 0.0) eul[0] -= 2.0*M_PI; else eul[0]+= 2.0*M_PI;
        }
-}
-
-/* exposed in transform.c */
-int pose_flags_reset_done(Object *ob) {
-       /* Clear the constraint done status for every pose channe;
-        * that has been flagged as needing constant updating
-        */
-       bPoseChannel *chan;
-       int numreset = 0;
-
-       if (ob->pose) {
-               for (chan = ob->pose->chanbase.first; chan; chan=chan->next){
-                       if (chan->flag & PCHAN_TRANS_UPDATE) {
-                               chan->flag &= ~PCHAN_DONE;
-                               numreset++;
-                       }
-
-               }
+       if( fabs(dy) > 3.2 && fabs(dz)<1.6 && fabs(dx)<1.6 ) {
+               if(dy > 0.0) eul[1] -= 2.0*M_PI; else eul[1]+= 2.0*M_PI;
        }
-       return numreset;
-}
-
-static int is_ob_constraint_target(Object *ob, ListBase *conlist) {
-       /* Is this object the target of a constraint in this list? 
-        */
-
-       bConstraint *con;
-
-       for (con=conlist->first; con; con=con->next)
-       {
-               if (get_constraint_target(con) == ob)
-                       return 1;
+       if( fabs(dz) > 3.2 && fabs(dx)<1.6 && fabs(dy)<1.6 ) {
+               if(dz > 0.0) eul[2] -= 2.0*M_PI; else eul[2]+= 2.0*M_PI;
        }
-       return 0;
-
-}
 
-static int clear_bone_nocalc(Object *ob, Bone *bone, void *ptr) {
-       /* When we aren't transform()-ing, we'll want to turn off
-        * the no calc flag for bone bone in case the frame changes,
-        * or something
-        */
-       bone->flag &= ~BONE_NOCALC;
+       return; /* <- intersting to find out who did that! */
        
-       return 0;
-}
-
+       /* calc again */
+       dx= eul[0] - oldrot[0];
+       dy= eul[1] - oldrot[1];
+       dz= eul[2] - oldrot[2];
 
-static void clear_bone_nocalc_ob(Object *ob) {
-       /* Let's clear no calc for all of the bones in the whole darn armature
-        */
-       bArmature *arm;
-       arm = get_armature(ob);
-       if (arm) {
-               bone_looper(ob, arm->bonebase.first, NULL, 
-                                       clear_bone_nocalc);
+       /* special case, tested for x-z  */
+       
+       if( (fabs(dx) > 3.1 && fabs(dz) > 1.5 ) || ( fabs(dx) > 1.5 && fabs(dz) > 3.1 ) ) {
+               if(dx > 0.0) eul[0] -= M_PI; else eul[0]+= M_PI;
+               if(eul[1] > 0.0) eul[1]= M_PI - eul[1]; else eul[1]= -M_PI - eul[1];
+               if(dz > 0.0) eul[2] -= M_PI; else eul[2]+= M_PI;
+               
+       }
+       else if( (fabs(dx) > 3.1 && fabs(dy) > 1.5 ) || ( fabs(dx) > 1.5 && fabs(dy) > 3.1 ) ) {
+               if(dx > 0.0) eul[0] -= M_PI; else eul[0]+= M_PI;
+               if(dy > 0.0) eul[1] -= M_PI; else eul[1]+= M_PI;
+               if(eul[2] > 0.0) eul[2]= M_PI - eul[2]; else eul[2]= -M_PI - eul[2];
+       }
+       else if( (fabs(dy) > 3.1 && fabs(dz) > 1.5 ) || ( fabs(dy) > 1.5 && fabs(dz) > 3.1 ) ) {
+               if(eul[0] > 0.0) eul[0]= M_PI - eul[0]; else eul[0]= -M_PI - eul[0];
+               if(dy > 0.0) eul[1] -= M_PI; else eul[1]+= M_PI;
+               if(dz > 0.0) eul[2] -= M_PI; else eul[2]+= M_PI;
        }
 
 }
 
-static int set_bone_nocalc(Object *ob, Bone *bone, void *ptr) {
-       /* Calculating bone transformation makes thins slow ...
-        * lets set the no calc flag for a bone by default
-        */
-       bone->flag |= BONE_NOCALC;
-       
-       return 0;
-}
 
-static int selected_bone_docalc(Object *ob, Bone *bone, void *ptr) {
-       /* Let's clear the no calc flag for selected bones.
-        * This function always returns 1 for non-no calc bones
-        * (a.k.a., the 'do calc' bones) so that the bone_looper 
-        * will count these
-        */
-       if (bone->flag & BONE_NOCALC) {
-               if ( (bone->flag & BONE_SELECTED) ) {
-                       bone->flag &= ~BONE_NOCALC;
-                       return 1;
-               }
-               
-       }
-       else {
-               return 1;
-       }
-       return 0;
-}
-
-static Bone *get_parent_bone_docalc(Bone *bone) {
-       Bone            *parBone;
-
-       for (parBone = bone->parent; parBone; parBone=parBone->parent)
-               if (~parBone->flag & BONE_NOCALC)
-                       return parBone;
-
-       return NULL;
-}
-
-static int is_bone_parent(Bone *childBone, Bone *parBone) {
-       Bone            *currBone;
-
-       for (currBone = childBone->parent; currBone; currBone=currBone->parent)
-               if (currBone == parBone)
-                       return 1;
-
-       return 0;
-}
-
-static void figure_bone_nocalc_constraint(Bone *conbone, bConstraint *con,
-                                                                                 Object *ob, bArmature *arm) {
-       /* If this bone has a constraint with a subtarget that has
-        * the nocalc flag cleared, then we better clear the no calc flag
-        * on this bone too (and the whole IK chain if this is an IK
-        * constraint).
-        *
-        * Conversly, if this bone has an IK constraint and the root of
-        * the chain has the no calc flag cleared, we had best clear that
-        * flag for the whole chain.
-        */
-       Bone *subtarbone;
-       Bone *parBone;
-       char *subtar;
-
-       subtar = get_con_subtarget_name(con, ob);
-
-       if (subtar) {
-               if ( (subtarbone = get_named_bone(arm, subtar)) ) {
-                       if ( (~subtarbone->flag & BONE_NOCALC) ||
-                                (get_parent_bone_docalc(subtarbone)) ) {
-                               if (con->type == CONSTRAINT_TYPE_KINEMATIC)
-                                       /* IK target is flaged for updating, so we
-                                        * must update the whole chain.
-                                        */
-                                       ik_chain_looper(ob, conbone, NULL, 
-                                                                       clear_bone_nocalc);
-                               else
-                                       /* Constraint target is flagged for
-                                        * updating, so we update this bone only
-                                        */
-                                       conbone->flag &= ~BONE_NOCALC;
-                       }
-                       else {
-                               if ( (parBone = get_parent_bone_docalc(conbone)) ) {
-                                       /* a parent is flagged for updating */
-                                       if (!is_bone_parent(subtarbone, parBone)) {
-                                               /* if the subtarget is also a child of
-                                                * this bone, we needn't worry, other
-                                                * wise, we have to update
-                                                */
-                                               if (con->type == CONSTRAINT_TYPE_KINEMATIC)
-                                                       ik_chain_looper(ob, conbone, NULL, 
-                                                                                       clear_bone_nocalc);
-                                               else
-                                                       conbone->flag &= ~BONE_NOCALC;
-                                       }
-                               }
-
-                       }
-               }
-       }
-       else {
-               /* no subtarget ... target is regular object */
-               if ( (parBone = get_parent_bone_docalc(conbone)) ) {
-                       /* parent is flagged for updating ... since
-                        * the target will never move (not a bone)
-                        * we had better update this bone/chain
-                        */
-                       if (con->type == CONSTRAINT_TYPE_KINEMATIC)
-                               ik_chain_looper(ob, conbone, NULL, 
-                                                               clear_bone_nocalc);
-                       else
-                               conbone->flag &= ~BONE_NOCALC;
-               }
-       }
-
-}
-
-static void figure_bone_nocalc_core(Object *ob, bArmature *arm) {
-       /* Let's figure out which bones need to be recalculated,
-        * and which don't. Calculations are based on which bones
-        * are selected, and the constraints that love them.
-        */
-       bPoseChannel *chan;
-       bConstraint *con;
-       Bone *conbone;
-
-       int numbones, oldnumbones, iterations;
-
-       oldnumbones = -1;
-       numbones    =  0;
-       iterations  =  0;
-
-       /* O.K., lets loop until we don't clear any more no calc bones
-        */
-       while (oldnumbones != numbones) {
-               /* I wonder if this will ever get executed? */
-               if ( (++iterations) == 1000) {
-                       printf("figurin' nocalc is talking too long\n");
-                       break;
-               }
-
-               oldnumbones = numbones;
-
-               /* clear no calc for selected bones and count */
-               numbones = bone_looper(ob, arm->bonebase.first, NULL, 
-                                                          selected_bone_docalc);
-
-               if (ob->pose) {
-                       for (chan = ob->pose->chanbase.first; chan; chan=chan->next){
-                               conbone = get_named_bone(arm, chan->name);
-                               if (conbone) {
-                                       for (con = chan->constraints.first; con; con=con->next) {
-                                               figure_bone_nocalc_constraint(conbone, con, ob, arm);
-                                       }
-                               }
-                       }
-               }
-       }
-}
-
-/* exposed in transform.c */
-void figure_bone_nocalc(Object *ob) {
-       /* Let's figure out which bones need to be recalculated,
-        * and which don't. Calculations are based on which bones
-        * are selected, and the constraints that love them.
-        */
-       bArmature *arm;
-
-       arm = get_armature(ob);
-       if (!arm) return;
-
-       if (arm->flag & ARM_RESTPOS) return;
-
-       /* Set no calc for all bones
-        */
-       bone_looper(ob, arm->bonebase.first, NULL, 
-                               set_bone_nocalc);
-
-       figure_bone_nocalc_core(ob, arm);
-}
-
-static int bone_nocalc2chan_trans_update(Object *ob, Bone *bone, void *ptr) {
-       /* Set PCHAN_TRANS_UPDATE for channels with bones that don't have
-        * the no calc flag set ... I hate this.
-        */
-       bPoseChannel *chan;
-
-       if (~bone->flag & BONE_NOCALC) {
-               chan = get_pose_channel(ob->pose, bone->name);
-               if (chan) chan->flag |= PCHAN_TRANS_UPDATE;
-       }
-       else {
-               /* reset this thing too */
-               bone->flag &= ~BONE_NOCALC;
-       }
-       
-       return 0;
-}
-
-static void clear_gonna_move(void) {
-       Base *base;
-
-       /* clear the gonna move flag */
-       for (base= FIRSTBASE; base; base= base->next) {
-               base->object->flag &= ~OB_GONNA_MOVE;
-       }
-}
-
-static int is_parent_gonna_move(Object *ob) {
-       if ( (ob->parent) &&
-                (ob->parent->flag & OB_GONNA_MOVE) ) {
-               return 1;
-       }
-       return 0;
-}
-
-static int is_constraint_target_gonna_move(Object *ob) {
-       Object *tarOb;
-       bConstraint *con;
-       bPoseChannel *chan;
-
-       for (con = ob->constraints.first; con; con=con->next) {
-               if ( (tarOb = get_constraint_target(con)) ) {
-                       if (tarOb->flag & OB_GONNA_MOVE )
-                               return 1;
-               }
-       }
-
-       if (ob->pose) {
-               for (chan = ob->pose->chanbase.first; chan; chan=chan->next){
-                       for (con = chan->constraints.first; con; con=con->next) {
-                               if ( (tarOb = get_constraint_target(con)) ) {
-                                       if (tarOb->flag & OB_GONNA_MOVE )
-                                               return 1;
-                               }
-                       }
-               }
-       }
-
-       return 0;
-}
-
-static void flag_moving_objects(void) {
-       Base *base;
-       int numgonnamove = 0, oldnumgonnamove = -1;
-
-       clear_gonna_move();
-
-       /* the 'well ordering principle' guarantees convergence (honest)
-        */
-       while (numgonnamove != oldnumgonnamove) {
-               oldnumgonnamove = numgonnamove;
-               numgonnamove = 0;
-               for (base= FIRSTBASE; base; base= base->next) {
-                       if (base->object->flag & OB_GONNA_MOVE) {
-                               ++numgonnamove;
-                       }
-                       else if (base->flag & SELECT) {
-                               base->object->flag |= OB_GONNA_MOVE;
-                               ++numgonnamove;
-                       }
-                       else if (is_parent_gonna_move(base->object)) {
-                               base->object->flag |= OB_GONNA_MOVE;
-                               ++numgonnamove;
-                       }
-                       else if (is_constraint_target_gonna_move(base->object)) {
-                               base->object->flag |= OB_GONNA_MOVE;
-                               ++numgonnamove;
-                       }
-               }
-       }
-
-}
-
-static int pose_do_update_flag(Object *ob) {
-       /* Figure out which pose channels need constant updating.
-        * Well use the bone BONE_NOCALC bit to do some temporary
-        * flagging (so we can reuse code), which will later be
-        * converted to a value for a channel... I hate this.
-        */
-       Base *base;
-       bPoseChannel *chan;
-       int do_update = 0;
-       bArmature *arm;
-
-       arm = get_armature(ob);
-       if (!arm) return 0;
-
-       /* initialize */
-       bone_looper(ob, arm->bonebase.first, NULL, 
-                               set_bone_nocalc);
-
-       if (ob->pose) {
-               for (chan = ob->pose->chanbase.first; chan; chan=chan->next){
-                       if (chan->constraints.first) {
-                               for (base= FIRSTBASE; base; base= base->next) {
-                                       if (is_ob_constraint_target(base->object, 
-                                                                                               &chan->constraints)) {
-                                               if( (base->object->flag & OB_GONNA_MOVE) || 
-                                                       (ob->flag & OB_GONNA_MOVE)) {
-                                                       Bone *bone;
-                                                       /* If this armature is selected, or if the
-                                                        * object that is the target of a constraint
-                                                        * is selected, then lets constantly update
-                                                        * this pose channel.
-                                                        */
-                                                       bone = get_named_bone(ob->data, chan->name);
-                                                       if (bone) {
-                                                               bone->flag &= ~BONE_NOCALC;
-                                                               ++do_update;
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-               }
-       }
-
-       if (do_update) {
-               figure_bone_nocalc_core(ob, arm);
-       }
-
-       bone_looper(ob, arm->bonebase.first, NULL, 
-                               bone_nocalc2chan_trans_update);
-
-       return do_update;
-}
-
-/* this is a confusing call, it also does the constraint update flags, but was not used...
-   hopefully transform refactor will take care better of it (ton) */
-/* exposed int transform.c */
-void figure_pose_updating(void)
-{
-       Base *base;
-
-       flag_moving_objects();
-
-       for (base= FIRSTBASE; base; base= base->next) {
-               /* Recalculate the pose if necessary, regardless of
-                * whether the layer is visible or not.
-                */
-               if (pose_do_update_flag(base->object)) {
-                       base->flag |= BA_WHERE_UPDATE;
-               }
-               else if(base->object->flag & OB_GONNA_MOVE) {
-                       /* if position updates, deform info could change too */
-                       if(base->object->hooks.first) base->flag |= BA_DISP_UPDATE;
-                       else if(base->object->parent) {
-                               if(base->object->parent->type==OB_LATTICE || base->object->partype==PARSKEL)
-                                       base->flag |= BA_DISP_UPDATE;
-                       }
-               }
-       }
-
-}
-
-/*** POSE FIGURIN' -- END ***/
-
-
-static void setbaseflags_for_editing(int mode) /* 0,'g','r','s' */
+int cylinder_intersect_test(void)
 {
-       /*
-               if base selected and has parent selected:
-                       base->flag= BA_WASSEL+BA_PARSEL
-               if base not selected and parent selected:
-                       base->flag= BA_PARSEL
-                               
-       */
-       GHash *object_to_base_hash= NULL; 
-       Base *base;
+       EditMesh *em = G.editMesh;
+       float *oldloc, speed[3], s, t, labda, labdacor, dist, len, len2, axis[3], *base, rc[3], n[3], o[3];
+       EditVert *v1;
+       
+       v1= em->verts.first;
 
-       /* moved to start of function, it is needed for hooks now too */
-       if (!object_to_base_hash) {
-               Base *b;
-               object_to_base_hash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
-               
-               for (b= FIRSTBASE; b; b= b->next)
-                       BLI_ghash_insert(object_to_base_hash, b->object, b);
-       }
+       base= v1->co;
+       v1= v1->next;
+       VecSubf(axis, v1->co, base);
        
+       v1= v1->next;
+       oldloc= v1->co;
+       v1= v1->next;
+       VecSubf(speed, v1->co, oldloc);
        
-       copy_baseflags();
-
-       for (base= FIRSTBASE; base; base= base->next) {
-               base->flag &= ~(BA_PARSEL+BA_WASSEL);
-
-               if( (base->lay & G.vd->lay) && base->object->id.lib==0) {
-                       Object *ob= base->object;
-                       Object *parsel= is_a_parent_selected(ob);
-                       
-                       /* parentkey here? */
-
-                       if(parsel) {
-                               if(base->flag & SELECT) {
-                                       base->flag &= ~SELECT;
-                                       base->flag |= (BA_PARSEL+BA_WASSEL);
-                               }
-                               else base->flag |= BA_PARSEL;
-                       }
-
-                       if(mode=='g')  {
-                               if(ob->track && TESTBASE(ob->track) && (base->flag & SELECT)==0)  
-                                       base->flag |= BA_PARSEL;
-                       }
-
-                       /* updates? */
-                       if(ob->type==OB_IKA) {
-                               Ika *ika= ob->data;
-                               if(ika->parent && parsel) base->flag |= BA_WHERE_UPDATE;
-                       }
-                       
-                       if(ob->hooks.first) {
-                               Base *b;
-                               ObHook *hook= ob->hooks.first;
-                               
-                               while(hook) {
-                                       if(hook->parent) {
-                                               Object *parsel= is_a_parent_selected(hook->parent);
-                                               
-                                               b= BLI_ghash_lookup(object_to_base_hash, hook->parent);
-                                               if(parsel || ((base->flag | b->flag) & (SELECT | BA_PARSEL)) ) {
-                                                       base->flag |= BA_DISP_UPDATE;
-                                               }
-                                       }
-                                       hook= hook->next;
-                               }
-                       }
-                       
-                       if(ob->parent && ob->parent->type==OB_LATTICE)
-                               if(ob->parent->hooks.first) base->flag |= BA_DISP_UPDATE;
-                       
-                       if(base->flag & (SELECT | BA_PARSEL)) {
-                               
-                               base->flag |= BA_WHERE_UPDATE;
-                               
-                               if(ob->parent) {
-                                       if(ob->parent->type==OB_LATTICE) base->flag |= BA_DISP_UPDATE;
-                                       else if(ob->partype==PARSKEL) {
-                                               if ELEM3(ob->parent->type, OB_IKA, OB_CURVE, OB_ARMATURE) 
-                                                       base->flag |= BA_DISP_UPDATE;
-                                       }
-                               }
-                               if(ob->track) {
-                                       ;
-                               }
-                               
-                               if( give_parteff(ob) ) base->flag |= BA_DISP_UPDATE;
-                               
-                               if(ob->type==OB_MBALL) {
-                                       Base *b;
-                                       
-                                       b= BLI_ghash_lookup(object_to_base_hash, find_basis_mball(ob));
-                                       b->flag |= BA_DISP_UPDATE;
-                               }
-                       }
-               }
-       }
+       VecSubf(rc, oldloc, base);
        
-       if (object_to_base_hash)
-               BLI_ghash_free(object_to_base_hash, NULL, NULL);
-}
-
-
-void clearbaseflags_for_editing()
-{
-       Base *base;
-
-       base= FIRSTBASE;
-       while(base) {
-               if(base->flag & BA_WASSEL) base->flag |= SELECT;
-               base->flag &= ~(BA_PARSEL+BA_WASSEL);
-               
-               base->flag &= ~(BA_DISP_UPDATE+BA_WHERE_UPDATE+BA_DO_IPO);
-
-               clear_pose_update_flag(base->object);
-               
-               base= base->next;
-       }
-       copy_baseflags();
-}
-
-void ob_to_transob(Object *ob, TransOb *tob)
-{
-       float totmat[3][3];
-       Object *tr;
-       void *cfirst, *clast;
+       /* the axis */
+       len2= Normalise(axis);
+       
+       Crossf(n, speed, axis);
+       len= Normalise(n);
+       if(len==0.0) return 0;
+       
+       dist= fabs( rc[0]*n[0] + rc[1]*n[1] + rc[2]*n[2] );
        
-       tob->ob= ob;
+       if( dist>=G.scene->editbutsize ) return 0;
        
-       cfirst = ob->constraints.first;
-       clast = ob->constraints.last;
+       Crossf(o, rc, axis);
+       t= -(o[0]*n[0] + o[1]*n[1] + o[2]*n[2])/len;
        
-       ob->constraints.first=ob->constraints.last=NULL;
+       Crossf(o, n, axis);
+       s=  fabs(sqrt(G.scene->editbutsize*G.scene->editbutsize-dist*dist) / (o[0]*speed[0] + o[1]*speed[1] + o[2]*speed[2]));
        
-       tr= ob->track;
-       ob->track= 0;
-       where_is_object(ob);
-       ob->track= tr;
-       ob->constraints.first = cfirst;
-       ob->constraints.last = clast;
+       labdacor= t-s;
+       labda= t+s;
 
+       /* two cases with no intersection point */
+       if(labdacor>=1.0 && labda>=1.0) return 0;
+       if(labdacor<=0.0 && labda<=0.0) return 0;
        
+       /* calc normal */
+       /* intersection: */
        
-       tob->loc= ob->loc;
-       VECCOPY(tob->oldloc, tob->loc);
+       rc[0]= oldloc[0] + labdacor*speed[0] - base[0];
+       rc[1]= oldloc[1] + labdacor*speed[1] - base[1];
+       rc[2]= oldloc[2] + labdacor*speed[2] - base[2];
        
-       tob->rot= ob->rot;
-       VECCOPY(tob->oldrot, ob->rot);
-       VECCOPY(tob->olddrot, ob->drot);
+       s= (rc[0]*axis[0] + rc[1]*axis[1] + rc[2]*axis[2]) ;
        
-       tob->quat= ob->quat;
-       QUATCOPY(tob->oldquat, ob->quat);
-       QUATCOPY(tob->olddquat, ob->dquat);
-
-       tob->size= ob->size;
-       VECCOPY(tob->oldsize, ob->size);
-
-       VECCOPY(tob->olddsize, ob->dsize);
-
-       /* only object, not parent */
-       object_to_mat3(ob, tob->obmat);
-       Mat3Inv(tob->obinv, tob->obmat);
+       if(s<0.0 || s>len2) return 0;
        
-       Mat3CpyMat4(totmat, ob->obmat);
-
-       /* this is totmat without obmat: so a parmat */
-       Mat3MulMat3(tob->parmat, totmat, tob->obinv);
-       Mat3Inv(tob->parinv, tob->parmat);
-
-       Mat3MulMat3(tob->axismat, tob->parmat, tob->obmat);     // New!
-       Mat3Ortho(tob->axismat);
-
-       VECCOPY(tob->obvec, ob->obmat[3]);
-
-       centroid[0]+= tob->obvec[0];
-       centroid[1]+= tob->obvec[1];
-       centroid[2]+= tob->obvec[2];
-
-       tob->eff= 0;
-
-       if(ob->type==OB_IKA) {
-               Ika *ika=ob->data;
-               
-               calc_ika(ika, 0);
-               
-               ika->effn[0]= ika->eff[0];
-               ika->effn[1]= ika->eff[1];
-               ika->effn[2]= 0.0;      
-               
-               VecMat4MulVecfl(ika->effg, ob->obmat, ika->effn);
-               
-               if(ika->flag & IK_GRABEFF) {
+       n[0]= (rc[0] - s*axis[0]);
+       n[1]= (rc[1] - s*axis[1]);
+       n[2]= (rc[2] - s*axis[2]);
 
-                       tob->eff= ika->effg;
-                       VECCOPY(tob->oldeff, tob->eff);
-                       tob->flag |= TOB_IKA;
+       printf("var1: %f, var2: %f, var3: %f\n", labdacor, len2, s);    
+       printf("var1: %f, var2: %f, var3: %f\n", rc[0], rc[1], rc[2]);  
+       printf("var1: %f, var2: %f, var3: %f\n", n[0], n[1], n[2]);     
 
-                       tob->loc= 0;
-               }
-               
-       }
+       return 1;
 }
 
-void ob_to_tex_transob(Object *ob, TransOb *tob)
+int sphere_intersect_test(void)
 {
-       Mesh *me;
-       Curve *cu;
-       MetaBall *mb;
-       ID *id;
-       
-       ob_to_transob(ob, tob);
+       EditMesh *em = G.editMesh;
+       float *oldloc, speed[3], labda, labdacor, len, bsq, u, disc, *base, rc[3];
+       EditVert *v1;
        
-       id= ob->data;
-       if(id==0);
-       else if( GS(id->name)==ID_ME) {
-               me= ob->data;
-               me->texflag &= ~AUTOSPACE;
-               tob->loc= me->loc;
-               tob->rot= me->rot;
-               tob->size= me->size;
-       }
-       else if( GS(id->name)==ID_CU) {
-               cu= ob->data;
-               cu->texflag &= ~CU_AUTOSPACE;
-               tob->loc= cu->loc;
-               tob->rot= cu->rot;
-               tob->size= cu->size;
-       }
-       else if( GS(id->name)==ID_MB) {
-               mb= ob->data;
-               mb->texflag &= ~MB_AUTOSPACE;
-               tob->loc= mb->loc;
-               tob->rot= mb->rot;
-               tob->size= mb->size;
-       }
-       
-       VECCOPY(tob->oldloc, tob->loc);
-       VECCOPY(tob->oldrot, tob->rot);
-       VECCOPY(tob->oldsize, tob->size);
-}
-
-void make_trans_objects()
-{
-       Base *base;
-       Object *ob;
-       TransOb *tob = NULL;
-       ListBase elems;
-       IpoKey *ik;
-       float cfraont, min[3], max[3];
-       int ipoflag;
-       
-       tottrans= 0;
-       
-       INIT_MINMAX(min, max);
-       centroid[0]=centroid[1]=centroid[2]= 0.0;
-       
-       /* count */     
-       base= FIRSTBASE;
-       while(base) {
-               if TESTBASELIB(base) {
-                       ob= base->object;
-                       
-                       if(transmode==TRANS_TEX) {
-                               if(ob->dtx & OB_TEXSPACE) tottrans++;
-                       }
-                       else {
-                               if(ob->ipo && ob->ipo->showkey && (ob->ipoflag & OB_DRAWKEY)) {
-                                       elems.first= elems.last= 0;
-                                       make_ipokey_transform(ob, &elems, 1); /* '1' only selected keys */
-                                       
-                                       pushdata(&elems, sizeof(ListBase));
-                                       
-                                       ik= elems.first;
-                                       while(ik) {
-                                               tottrans++;
-                                               ik= ik->next;
-                                       }
-                                       if(elems.first==0) tottrans++;
-                               }
-                               else tottrans++;
-                       }
-               }
-               base= base->next;
-       }
-
-       if(tottrans) tob= transmain= MEM_mallocN(tottrans*sizeof(TransOb), "transmain");
-       
-       reset_slowparents();
-
-
-       /*also do this below when tottrans==0, because of freeing pushpop and ipokeys */
-       
-       base= FIRSTBASE;
-       while(base) {
-               if TESTBASELIB(base) {
-                       ob= base->object;
-                       
-                       if(transmode==TRANS_TEX) {
-                               if(ob->dtx & OB_TEXSPACE) {
-                                       tob->flag= 0;
-                                       
-                                       ob_to_tex_transob(ob, tob);
-                                       DO_MINMAX(tob->obvec, min, max);
-                                       
-                                       tob++;                                  
-                               }
-                       }
-                       else {
-
-                               /* is needed! (bevobj) */
-                               if(base->flag & SELECT) ob->flag|= SELECT; else ob->flag &= ~SELECT;
-       
-                               if(ob->ipo && ob->ipo->showkey && (ob->ipoflag & OB_DRAWKEY)) {
-       
-                                       popfirst(&elems);
-       
-                                       if(elems.first) {
-                                               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);
-                                               
-                                               ik= elems.first;
-                                               while(ik) {
-               
-                                                       CFRA= ik->val/G.scene->r.framelen;
-                                                       
-                                                       do_ob_ipo(ob);
-                                                       where_is_object(ob);
-                                                       
-                                                       ob_to_transob(ob, tob);
-                                                       DO_MINMAX(tob->obvec, min, max);
-                                                       
-                                                       /* also does tob->flag and oldvals, needs to be after ob_to_transob()! */
-                                                       set_ipo_pointers_transob(ik, tob);
-                                                       
-                                                       tob++;
-                                                       ik= ik->next;
-                                               }
-                                               free_ipokey(&elems);
-                                               
-                                               poplast(ob->loc);
-                                               set_no_parent_ipo(0);
-                                               
-                                               CFRA= cfraont;
-                                               ob->ipoflag= ipoflag;
-                                       }
-                                       else {
-                                               tob->flag= 0;
-                                       
-                                               ob_to_transob(ob, tob);
-                                               DO_MINMAX(tob->obvec, min, max);
-                                               
-                                               tob++;
-                                       }
-                               }
-                               else {
-                                       tob->flag= 0;
-                               
-                                       ob_to_transob(ob, tob);
-                                       DO_MINMAX(tob->obvec, min, max);
-                                       
-                                       tob++;
-                               }
-                       }
-                       
-               }
-               base= base->next;
-       }
-       
-       pushpop_test(); /* only for debug & to be sure */
-       
-       if(tottrans==0) return;
-       
-       centroid[0]/= tottrans;
-       centroid[1]/= tottrans;
-       centroid[2]/= tottrans;
+       v1= em->verts.first;
+       base= v1->co;
        
-       centre[0]= (min[0]+max[0])/2.0;
-       centre[1]= (min[1]+max[1])/2.0;
-       centre[2]= (min[2]+max[2])/2.0;
-}
-
-/* mode: 1 = proportional */
-void make_trans_verts(float *min, float *max, int mode)        
-{
-       EditMesh *em = G.editMesh;
-/*     extern Lattice *editLatt; already in BKE_lattice.h */
-       Nurb *nu;
-       BezTriple *bezt;
-       BPoint *bp;
-       TransVert *tv=NULL;
-       MetaElem *ml;
-       EditVert *eve;
-       EditBone        *ebo;
-       float total;
-       int a;
-
-       tottrans= 0; // global!
+       v1= v1->next;
+       oldloc= v1->co;
        
-       INIT_MINMAX(min, max);
-       centroid[0]=centroid[1]=centroid[2]= 0.0;
+       v1= v1->next;
+       VecSubf(speed, v1->co, oldloc);
+       len= Normalise(speed);
+       if(len==0.0) return 0;
        
-       /* note for transform refactor: dont rely on countall anymore... its ancient */
-       /* I skip it for editmesh now (ton) */
-       if(G.obedit->type!=OB_MESH) {
-               countall();
-               if(mode) tottrans= G.totvert;
-               else tottrans= G.totvertsel;
+       VecSubf(rc, oldloc, base);
+       bsq= rc[0]*speed[0] + rc[1]*speed[1] + rc[2]*speed[2]; 
+       u= rc[0]*rc[0] + rc[1]*rc[1] + rc[2]*rc[2] - G.scene->editbutsize*G.scene->editbutsize;
 
-               if(G.totvertsel==0) {
-                       tottrans= 0;
-                       return;
-               }
-               tv=transvmain= MEM_callocN(tottrans*sizeof(TransVert), "maketransverts");
-       }
-       
-       /* we count again because of hide (old, not for mesh!) */
-       tottrans= 0;
+       disc= bsq*bsq - u;
        
-       if(G.obedit->type==OB_MESH) {
-               int proptrans= 0;
-               
-               // transform now requires awareness for select mode, so we tag the f1 flags in verts
-               tottrans= 0;
-               if(G.scene->selectmode & SCE_SELECT_VERTEX) {
-                       for(eve= em->verts.first; eve; eve= eve->next) {
-                               if(eve->h==0 && (eve->f & SELECT)) {
-                                       eve->f1= SELECT;
-                                       tottrans++;
-                               }
-                               else eve->f1= 0;
-                       }
-               }
-               else if(G.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) {
-                               if(eed->h==0 && (eed->f & SELECT)) eed->v1->f1= eed->v2->f1= SELECT;
-                       }
-                       for(eve= em->verts.first; eve; eve= eve->next) if(eve->f1) tottrans++;
-               }
-               else {
-                       EditFace *efa;
-                       for(eve= em->verts.first; eve; eve= eve->next) eve->f1= 0;
-                       for(efa= em->faces.first; efa; efa= efa->next) {
-                               if(efa->h==0 && (efa->f & SELECT)) {
-                                       efa->v1->f1= efa->v2->f1= efa->v3->f1= SELECT;
-                                       if(efa->v4) efa->v4->f1= SELECT;
-                               }
-                       }
-                       for(eve= em->verts.first; eve; eve= eve->next) if(eve->f1) tottrans++;
-               }
-               
-               /* proportional edit exception... */
-               if(mode==1 && tottrans) {
-                       for(eve= em->verts.first; eve; eve= eve->next) {
-                               if(eve->h==0) {
-                                       eve->f1 |= 2;
-                                       proptrans++;
-                               }
-                       }
-                       if(proptrans>tottrans) tottrans= proptrans;
-               }
-               
-               /* and now make transverts */
-               if(tottrans) {
-                       tv=transvmain= MEM_callocN(tottrans*sizeof(TransVert), "maketransverts");
-
-                       for(eve= em->verts.first; eve; eve= eve->next) {
-                               if(eve->f1) {
-                                       VECCOPY(tv->oldloc, eve->co);
-                                       tv->loc= eve->co;
-                                       if(eve->no[0]!=0.0 || eve->no[1]!=0.0 ||eve->no[2]!=0.0)
-                                               tv->nor= eve->no; // note this is a hackish signal (ton)
-                                       tv->flag= eve->f1 & SELECT;
-                                       tv++;
-                               }
-                       }
-               }
-       }
-       else if (G.obedit->type==OB_ARMATURE){
-               for (ebo=G.edbo.first;ebo;ebo=ebo->next){
-                       if (ebo->flag & BONE_TIPSEL){
-                               VECCOPY (tv->oldloc, ebo->tail);
-                               tv->loc= ebo->tail;
-                               tv->nor= NULL;
-                               tv->flag= 1;
-                               tv++;
-                               tottrans++;
-                       }
-
-                       /*  Only add the root if there is no selected IK parent */
-                       if (ebo->flag & BONE_ROOTSEL){
-                               if (!(ebo->parent && (ebo->flag & BONE_IK_TOPARENT) && ebo->parent->flag & BONE_TIPSEL)){
-                                       VECCOPY (tv->oldloc, ebo->head);
-                                       tv->loc= ebo->head;
-                                       tv->nor= NULL;
-                                       tv->flag= 1;
-                                       tv++;
-                                       tottrans++;
-                               }               
-                       }
-                       
-               }
-       }
-       else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
-               nu= editNurb.first;
-               while(nu) {
-                       if((nu->type & 7)==CU_BEZIER) {
-                               a= nu->pntsu;
-                               bezt= nu->bezt;
-                               while(a--) {
-                                       if(bezt->hide==0) {
-                                               if(mode==1 || (bezt->f1 & 1)) {
-                                                       VECCOPY(tv->oldloc, bezt->vec[0]);
-                                                       tv->loc= bezt->vec[0];
-                                                       tv->flag= bezt->f1 & 1;
-                                                       tv++;
-                                                       tottrans++;
-                                               }
-                                               if(mode==1 || (bezt->f2 & 1)) {
-                                                       VECCOPY(tv->oldloc, bezt->vec[1]);
-                                                       tv->loc= bezt->vec[1];
-                                                       tv->val= &(bezt->alfa);
-                                                       tv->oldval= bezt->alfa;
-                                                       tv->flag= bezt->f2 & 1;
-                                                       tv++;
-                                                       tottrans++;
-                                               }
-                                               if(mode==1 || (bezt->f3 & 1)) {
-                                                       VECCOPY(tv->oldloc, bezt->vec[2]);
-                                                       tv->loc= bezt->vec[2];
-                                                       tv->flag= bezt->f3 & 1;
-                                                       tv++;
-                                                       tottrans++;
-                                               }
-                                       }
-                                       bezt++;
-                               }
-                       }
-                       else {
-                               a= nu->pntsu*nu->pntsv;
-                               bp= nu->bp;
-                               while(a--) {
-                                       if(bp->hide==0) {
-                                               if(mode==1 || (bp->f1 & 1)) {
-                                                       VECCOPY(tv->oldloc, bp->vec);
-                                                       tv->loc= bp->vec;
-                                                       tv->val= &(bp->alfa);
-                                                       tv->oldval= bp->alfa;
-                                                       tv->flag= bp->f1 & 1;
-                                                       tv++;
-                                                       tottrans++;
-                                               }
-                                       }
-                                       bp++;
-                               }
-                       }
-                       nu= nu->next;
-               }
-       }
-       else if(G.obedit->type==OB_MBALL) {
-               ml= editelems.first;
-               while(ml) {
-                       if(ml->flag & SELECT) {
-                               tv->loc= &ml->x;
-                               VECCOPY(tv->oldloc, tv->loc);
-                               tv->val= &(ml->rad);
-                               tv->oldval= ml->rad;
-                               tv->flag= 1;
-                               tv++;
-                               tottrans++;
-                       }
-                       ml= ml->next;
-               }
-       }
-       else if(G.obedit->type==OB_LATTICE) {
-               bp= editLatt->def;
-               
-               a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
+       if(disc>=0.0) {
+               disc= sqrt(disc);
+               labdacor= (-bsq - disc)/len;    /* entry point */
+               labda= (-bsq + disc)/len;
                
-               while(a--) {
-                       if(mode==1 || (bp->f1 & 1)) {
-                               if(bp->hide==0) {
-                                       VECCOPY(tv->oldloc, bp->vec);
-                                       tv->loc= bp->vec;
-                                       tv->flag= bp->f1 & 1;
-                                       tv++;
-                                       tottrans++;
-                               }
-                       }
-                       bp++;
-               }
-       }
-       
-       /* cent etc */
-       tv= transvmain;
-       total= 0.0;
-       for(a=0; a<tottrans; a++, tv++) {
-               if(tv->flag & SELECT) {
-                       centroid[0]+= tv->oldloc[0];
-                       centroid[1]+= tv->oldloc[1];
-                       centroid[2]+= tv->oldloc[2];
-                       total+= 1.0;
-                       DO_MINMAX(tv->oldloc, min, max);
-               }
-       }
-       if(total!=0.0) {
-               centroid[0]/= total;
-               centroid[1]/= total;
-               centroid[2]/= total;
-       }
-
-       centre[0]= (min[0]+max[0])/2.0;
-       centre[1]= (min[1]+max[1])/2.0;
-       centre[2]= (min[2]+max[2])/2.0;
-       
-}
-
-/* now only in use by drawimage.c */
-void draw_prop_circle()
-{
-       if (G.f & G_PROPORTIONAL) {
-               float tmat[4][4], imat[4][4];
-
-               if(G.moving) {
-                       BIF_ThemeColor(TH_GRID);
-
-                       mygetmatrix(tmat);
-                       Mat4Invert(imat, tmat);
-
-                       drawcircball(prop_cent, prop_size, imat);
-               }
+               printf("var1: %f, var2: %f, var3: %f\n", labdacor, labda, G.scene->editbutsize);
        }
-}
+       else return 0;
 
-void set_proportional_weight(TransVert *tv, float *min, float *max)
-{
-       float dist, xdist, ydist, zdist;
-       
-       if(tv->oldloc[0]<min[0]) xdist= tv->oldloc[0]-min[0];
-       else if(tv->oldloc[0]>max[0]) xdist= tv->oldloc[0]-max[0];
-       else xdist= 0.0;
+       /* intersection and normal */
+       rc[0]= oldloc[0] + labdacor*speed[0] - base[0];
+       rc[1]= oldloc[1] + labdacor*speed[1] - base[1];
+       rc[2]= oldloc[2] + labdacor*speed[2] - base[2];
 
-       if(tv->oldloc[1]<min[1]) ydist= tv->oldloc[1]-min[1];
-       else if(tv->oldloc[1]>max[1]) ydist= tv->oldloc[1]-max[1];
-       else ydist= 0.0;
 
-       if(tv->oldloc[2]<min[2]) zdist= tv->oldloc[2]-min[2];
-       else if(tv->oldloc[2]>max[2]) zdist= tv->oldloc[2]-max[2];
-       else zdist= 0.0;
-       
-       dist= sqrt(xdist*xdist + ydist*ydist + zdist*zdist);
-       if(dist==0.0) tv->fac= 1.0;
-       else if(dist > prop_size) tv->fac= 0.0;
-       else {
-               dist= (prop_size-dist)/prop_size;
-               if(prop_mode==1) tv->fac= 3.0*dist*dist - 2.0*dist*dist*dist;
-               else tv->fac= dist*dist;
-       }
+       return 1;
 }
 
-void special_trans_update(int keyflags)
-{
-/*     extern Lattice *editLatt; already in BKE_lattice.h */
-       Base *base;
-       Curve *cu;
-       IpoCurve *icu;
-
-       if(G.obedit) {
-               if(G.obedit->type==OB_MESH) {
-                       recalc_editnormals();   // does face centers too
-               }
-               if(G.obedit->type==OB_CURVE) {
-                       cu= G.obedit->data;
-                       
-                       makeBevelList(G.obedit); // might be needed for deform
-                       calc_curvepath(G.obedit);
-                       
-                       base= FIRSTBASE;
-                       while(base) {
-                               if(base->lay & G.vd->lay) {
-                                       if(base->object->parent==G.obedit && base->object->partype==PARSKEL)
-                                               makeDispList(base->object);
-                                       else if(base->object->type==OB_CURVE) {
-                                               Curve *cu= base->object->data;
-                                               if(G.obedit==cu->bevobj || G.obedit==cu->taperobj)
-                                                       makeDispList(base->object);
-                                       }
-                               }
-                               base= base->next;
-                       }
-               }
-               else if(G.obedit->type==OB_ARMATURE){
-                       EditBone *ebo;
-
-                       /* Ensure all bones are correctly adjusted */
-                       for (ebo=G.edbo.first; ebo; ebo=ebo->next){
-                               
-                               if ((ebo->flag & BONE_IK_TOPARENT) && ebo->parent){
-                               /* If this bone has a parent tip that has been moved */
-                                       if (ebo->parent->flag & BONE_TIPSEL){
-                                               VECCOPY (ebo->head, ebo->parent->tail);
-                                       }
-                               /* If this bone has a parent tip that has NOT been moved */
-                                       else{
-                                               VECCOPY (ebo->parent->tail, ebo->head);
-                                       }
-                               }
-                       }
-               }
-               else if(G.obedit->type==OB_LATTICE) {
-                       
-                       if(editLatt->flag & LT_OUTSIDE) outside_lattice(editLatt);
-                       
-                       base= FIRSTBASE;
-                       while(base) {
-                               if(base->lay & G.vd->lay) {
-                                       if(base->object->parent==G.obedit) {
-                                               makeDispList(base->object);
-                                       }
-                               }
-                               base= base->next;
-                       }
-               }
-       }
-       else if(G.obpose){
-               int     i;
-               bPoseChannel    *chan;
-
-               if (!G.obpose->pose) G.obpose->pose= MEM_callocN(sizeof(bPose), "pose");
-               
-               switch (G.obpose->type){
-               case OB_ARMATURE:
-
-                       /*      Make channels for the transforming bones (in posemode) */
-                       for (i=0; i< tottrans; i++){
-                               chan = MEM_callocN (sizeof (bPoseChannel), "transPoseChannel");
-                               
-                               if (keyflags & KEYFLAG_ROT){
-                                       chan->flag |= POSE_ROT;
-                                       memcpy (chan->quat, transmain[i].quat, sizeof (chan->quat));
-                               }
-                               if (keyflags & KEYFLAG_LOC){
-                                       chan->flag |= POSE_LOC;
-                                       memcpy (chan->loc, transmain[i].loc, sizeof (chan->loc));
-                               }
-                               if (keyflags & KEYFLAG_SIZE){
-                                       chan->flag |= POSE_SIZE;
-                                       memcpy (chan->size, transmain[i].size, sizeof (chan->size));
-                               }
-                               
-                               strcpy (chan->name, ((Bone*) transmain[i].data)->name);
-                               
-                               set_pose_channel (G.obpose->pose, chan);
-                       }
-                       break;
-               }
-       }
-       else {
-               base= FIRSTBASE;
-               while(base) {
-                       if(base->flag & BA_DO_IPO) {
-                               
-                               base->object->ctime= -1234567.0;
-                               
-                               icu= base->object->ipo->curve.first;
-                               while(icu) {
-                                       calchandles_ipocurve(icu);
-                                       icu= icu->next;
-                               }
-                               
-                       }
-                       if(base->object->partype & PARSLOW) {
-                               base->object->partype -= PARSLOW;
-                               where_is_object(base->object);
-                               base->object->partype |= PARSLOW;
-                       }
-                       else if(base->flag & BA_WHERE_UPDATE) {
-                               where_is_object(base->object);
-                               if(base->object->type==OB_IKA) {
-                                       itterate_ika(base->object);
-                               }
-
-                       }
-
-                       base= base->next;
-               } 
-                               
-               base= FIRSTBASE;
-               while(base) {
-                       
-                       if(base->flag & BA_DISP_UPDATE) makeDispList(base->object);
-                       
-                       base= base->next;
-               }
-               
-       }
-
-       base= FIRSTBASE;
-       while(base) {
-               if (pose_flags_reset_done(base->object)) {
-                       if (!is_delay_deform())
-                               make_displists_by_armature(base->object);
-               }
-
-               base= base->next;
-       }
-
-#if 1
-       if (G.obpose && G.obpose->type == OB_ARMATURE)
-               clear_pose_constraint_status(G.obpose);
-
-       if (!is_delay_deform()) make_displists_by_armature(G.obpose);
-#endif
-
-       if(G.vd->drawtype == OB_SHADED) reshadeall_displist();
-
-}
-
-
-void special_aftertrans_update(char mode, int flip, short canceled, int keyflags)
-{
-       Object *ob;
-       Base *base;
-       MetaBall *mb;
-       Curve *cu;
-       Ika *ika;
-       int doit,redrawipo=0;
-
-       
-       /* displaylists etc. */
-       
-       if(G.obedit) {
-               if(G.obedit->type==OB_MBALL) {
-                       mb= G.obedit->data;
-                       if(mb->flag != MB_UPDATE_ALWAYS) makeDispList(G.obedit);
-               }
-               else if(G.obedit->type==OB_MESH) {
-                       if(flip) flip_editnormals();
-
-                       recalc_editnormals();
-               }
-       }
-       else if (G.obpose){
-               bAction *act;
-               bPose   *pose;
-               bPoseChannel *pchan;
-
-               /* we had better clear the no calc flags on the bones
-                * ... else things won't look too good when changing
-                * frames, etc.
-                */
-               clear_bone_nocalc_ob(G.obpose);
-
-               if (U.uiflag & USER_KEYINSERTACT && !canceled){
-                       act=G.obpose->action;
-                       pose=G.obpose->pose;
-                       
-                       if (!act)
-                               act=G.obpose->action=add_empty_action();
-
-                       collect_pose_garbage(G.obpose);
-                       filter_pose_keys ();
-                       for (pchan=pose->chanbase.first; pchan; pchan=pchan->next){
-                               if (pchan->flag & POSE_KEY){
-                                       if (keyflags & KEYFLAG_ROT){
-                                               set_action_key(act, pchan, AC_QUAT_X, 1);
-                                               set_action_key(act, pchan, AC_QUAT_Y, 1);
-                                               set_action_key(act, pchan, AC_QUAT_Z, 1);
-                                               set_action_key(act, pchan, AC_QUAT_W, 1);
-                                       }
-                                       if (keyflags & KEYFLAG_SIZE){
-                                               set_action_key(act, pchan, AC_SIZE_X, 1);
-                                               set_action_key(act, pchan, AC_SIZE_Y, 1);
-                                               set_action_key(act, pchan, AC_SIZE_Z, 1);
-                                       }
-                                       if (keyflags & KEYFLAG_LOC){
-                                               set_action_key(act, pchan, AC_LOC_X, 1);
-                                               set_action_key(act, pchan, AC_LOC_Y, 1);
-                                               set_action_key(act, pchan, AC_LOC_Z, 1);
-                                       }
-                               }
-                       }
-                       
-
-                       remake_action_ipos (act);
-                       allspace(REMAKEIPO, 0);
-                       allqueue(REDRAWACTION, 0);
-                       allqueue(REDRAWIPO, 0);
-                       allqueue(REDRAWNLA, 0);
-               }
-               if (!canceled && is_delay_deform()){
-                       clear_pose_constraint_status(G.obpose);
-                       make_displists_by_armature(G.obpose);
-               }
-
-       }
-       else {
-               base= FIRSTBASE;
-               while(base) {   
-
-                       ob= base->object;
-                       
-                       if(base->flag & BA_WHERE_UPDATE) {
-                               
-                               where_is_object(ob);
-
-                               if(ob->type==OB_IKA) {
-                                       ika= ob->data;                                  
-                                       VecMat4MulVecfl(ika->effg, ob->obmat, ika->eff);
-                                       itterate_ika(ob);
-                               }
-                               if(ob->type==OB_ARMATURE && canceled) {
-                                       /* Unfortunately, sometimes when you escape
-                                        * a transform on an object that is the
-                                        * target of an IK constraint on an armature
-                                        * bone, the rotations are not restored
-                                        * correctly on the bones in the IK chain. 
-                                        * There is probably a nice, elegant way to fix 
-                                        * this using transdata, but this system is so 
-                                        * darn confusing that we'll do it this brute
-                                        * force way instead:
-                                        */
-                                       clear_pose_constraint_status(ob);
-                                       make_displists_by_armature(ob);
-                               }
-                       }
-                       if(base->flag & BA_DISP_UPDATE) {
-                               if(ob->type==OB_MBALL) {
-                                       mb= ob->data;
-                                       if(mb->flag != MB_UPDATE_ALWAYS || G.obedit == NULL) makeDispList(ob);
-                               }
-                               if( give_parteff(ob) ) build_particle_system(ob);
-                       }
-                       if(base->flag & BA_DO_IPO) redrawipo= 1;
-                       
-                       if(mode=='s' && ob->type==OB_FONT) {
-                               doit= 0;
-                               cu= ob->data;
-                               
-                               if(cu->bevobj && (cu->bevobj->flag & SELECT) ) doit= 1;
-                               else if(cu->taperobj && (cu->taperobj->flag & SELECT) ) doit= 1;
-                               else if(cu->textoncurve) {
-                                       if(cu->textoncurve->flag & SELECT) doit= 1;
-                                       else if(ob->flag & SELECT) doit= 1;
-                               }
-                               
-                               if(doit) {
-                                       text_to_curve(ob, 0);
-                                       makeDispList(ob);
-                               }
-                       }
-                       if(mode=='s' && ob->type==OB_CURVE) {
-                               doit= 0;
-                               cu= ob->data;
-                               
-                               if(cu->bevobj && (cu->bevobj->flag & SELECT) ) 
-                                       makeDispList(ob);
-                               else if(cu->taperobj && (cu->taperobj->flag & SELECT) ) 
-                                       makeDispList(ob);
-                       }
-                       
-                       where_is_object(ob);    /* always do, for track etc. */
-
-                       /* Set autokey if necessary */
-                       if ((U.uiflag & USER_KEYINSERTOBJ) && (!canceled) && (base->flag & SELECT)){
-                               if (keyflags & KEYFLAG_ROT){
-                                       insertkey(&base->object->id, OB_ROT_X);
-                                       insertkey(&base->object->id, OB_ROT_Y);
-                                       insertkey(&base->object->id, OB_ROT_Z);
-                               }
-                               if (keyflags & KEYFLAG_LOC){
-                                       insertkey(&base->object->id, OB_LOC_X);
-                                       insertkey(&base->object->id, OB_LOC_Y);
-                                       insertkey(&base->object->id, OB_LOC_Z);
-                               }
-                               if (keyflags & KEYFLAG_SIZE){
-                                       insertkey(&base->object->id, OB_SIZE_X);
-                                       insertkey(&base->object->id, OB_SIZE_Y);
-                                       insertkey(&base->object->id, OB_SIZE_Z);
-                               }
-
-                               remake_object_ipos (ob);
-                               allqueue(REDRAWIPO, 0);
-                               allspace(REMAKEIPO, 0);
-                               allqueue(REDRAWVIEW3D, 0);
-                               allqueue(REDRAWNLA, 0);
-                       }
-                       
-                       base= base->next;
-               }
-               
-       }
-
-       if(redrawipo) {
-               allqueue(REDRAWNLA, 0);
-               allqueue(REDRAWACTION, 0);
-               allqueue(REDRAWIPO, 0);
-       }
-
-       if(G.vd->drawtype == OB_SHADED) reshadeall_displist();
-
-}
-
-
-
-void calc_trans_verts(void)
-{
-       if (ELEM(G.obedit->type, OB_MESH, OB_MBALL))
-               makeDispList(G.obedit);
-       else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
-               Nurb *nu= editNurb.first;
-               while(nu) {
-                       test2DNurb(nu);
-                       testhandlesNurb(nu); /* test for bezier too */
-                       nu= nu->next;
-               }
-               makeDispList(G.obedit);
-       }
-}
-
-
-static int test_midtog_proj(short xn, short yn, short *mval)
-{
-       float x,y,z;
-
-       /* which movement is the largest? that'll be the one */
-       xn= (xn-mval[0]);
-       yn= (yn-mval[1]);
-       x = fabs(G.vd->persinv[0][0]*xn + G.vd->persinv[1][0]*yn);
-       y = fabs(G.vd->persinv[0][1]*xn + G.vd->persinv[1][1]*yn);
-       z = fabs(G.vd->persinv[0][2]*xn + G.vd->persinv[1][2]*yn);
-
-       if(x>=y && x>=z) return 0;
-       else if(y>=x && y>=z) return 1;
-       else return 2;
-}
-
-void apply_keyb_grid(float *val, float fac1, float fac2, float fac3, int invert)
-{
-       /* fac1 is for 'nothing', fac2 for CTRL, fac3 for SHIFT */
-       int ctrl;
-
-       if(invert) {
-               if(G.qual & LR_CTRLKEY) ctrl= 0;
-               else ctrl= 1;
-       }
-       else ctrl= (G.qual & LR_CTRLKEY);
-
-       if(ctrl && (G.qual & LR_SHIFTKEY)) {
-               if(fac3!= 0.0) *val= fac3*floor(*val/fac3 +.5);
-       }
-       else if(ctrl) {
-               if(fac2!= 0.0) *val= fac2*floor(*val/fac2 +.5);
-       }
-       else {
-               if(fac1!= 0.0) *val= fac1*floor(*val/fac1 +.5);
-       }
-}
-
-/* exported to transform.c */
-void compatible_eul(float *eul, float *oldrot)
-{
-       float dx, dy, dz;
-       
-       /* correct differences of about 360 degrees first */
-
-       dx= eul[0] - oldrot[0];
-       dy= eul[1] - oldrot[1];
-       dz= eul[2] - oldrot[2];
-
-       while( fabs(dx) > 5.1) {
-               if(dx > 0.0) eul[0] -= 2.0*M_PI; else eul[0]+= 2.0*M_PI;
-               dx= eul[0] - oldrot[0];
-       }
-       while( fabs(dy) > 5.1) {
-               if(dy > 0.0) eul[1] -= 2.0*M_PI; else eul[1]+= 2.0*M_PI;
-               dy= eul[1] - oldrot[1];
-       }
-       while( fabs(dz) > 5.1 ) {
-               if(dz > 0.0) eul[2] -= 2.0*M_PI; else eul[2]+= 2.0*M_PI;
-               dz= eul[2] - oldrot[2];
-       }
-       
-       /* is 1 of the axis rotations larger than 180 degrees and the other small? NO ELSE IF!! */      
-       if( fabs(dx) > 3.2 && fabs(dy)<1.6 && fabs(dz)<1.6 ) {
-               if(dx > 0.0) eul[0] -= 2.0*M_PI; else eul[0]+= 2.0*M_PI;
-       }
-       if( fabs(dy) > 3.2 && fabs(dz)<1.6 && fabs(dx)<1.6 ) {
-               if(dy > 0.0) eul[1] -= 2.0*M_PI; else eul[1]+= 2.0*M_PI;
-       }
-       if( fabs(dz) > 3.2 && fabs(dx)<1.6 && fabs(dy)<1.6 ) {
-               if(dz > 0.0) eul[2] -= 2.0*M_PI; else eul[2]+= 2.0*M_PI;
-       }
-
-       return; /* <- intersting to find out who did that! */
-       
-       /* calc again */
-       dx= eul[0] - oldrot[0];
-       dy= eul[1] - oldrot[1];
-       dz= eul[2] - oldrot[2];
-
-       /* special case, tested for x-z  */
-       
-       if( (fabs(dx) > 3.1 && fabs(dz) > 1.5 ) || ( fabs(dx) > 1.5 && fabs(dz) > 3.1 ) ) {
-               if(dx > 0.0) eul[0] -= M_PI; else eul[0]+= M_PI;
-               if(eul[1] > 0.0) eul[1]= M_PI - eul[1]; else eul[1]= -M_PI - eul[1];
-               if(dz > 0.0) eul[2] -= M_PI; else eul[2]+= M_PI;
-               
-       }
-       else if( (fabs(dx) > 3.1 && fabs(dy) > 1.5 ) || ( fabs(dx) > 1.5 && fabs(dy) > 3.1 ) ) {
-               if(dx > 0.0) eul[0] -= M_PI; else eul[0]+= M_PI;
-               if(dy > 0.0) eul[1] -= M_PI; else eul[1]+= M_PI;
-               if(eul[2] > 0.0) eul[2]= M_PI - eul[2]; else eul[2]= -M_PI - eul[2];
-       }
-       else if( (fabs(dy) > 3.1 && fabs(dz) > 1.5 ) || ( fabs(dy) > 1.5 && fabs(dz) > 3.1 ) ) {
-               if(eul[0] > 0.0) eul[0]= M_PI - eul[0]; else eul[0]= -M_PI - eul[0];
-               if(dy > 0.0) eul[1] -= M_PI; else eul[1]+= M_PI;
-               if(dz > 0.0) eul[2] -= M_PI; else eul[2]+= M_PI;
-       }
-
-}
-
-void add_ipo_tob_poin(float *poin, float *old, float delta)
-{
-       if(poin) {
-               poin[0]= old[0]+delta;
-               poin[-3]= old[3]+delta;
-               poin[3]= old[6]+delta;
-       }
-}
-
-void restore_tob(TransOb *tob)
-{
-
-       if(tob->flag & TOB_IPO) {
-               add_ipo_tob_poin(tob->locx, tob->oldloc, 0.0);
-               add_ipo_tob_poin(tob->locy, tob->oldloc+1, 0.0);
-               add_ipo_tob_poin(tob->locz, tob->oldloc+2, 0.0);
-/* QUAT! */
-               add_ipo_tob_poin(tob->rotx, tob->oldrot+3, 0.0);
-               add_ipo_tob_poin(tob->roty, tob->oldrot+4, 0.0);
-               add_ipo_tob_poin(tob->rotz, tob->oldrot+5, 0.0);
-
-               add_ipo_tob_poin(tob->sizex, tob->oldsize, 0.0);
-               add_ipo_tob_poin(tob->sizey, tob->oldsize+1, 0.0);
-               add_ipo_tob_poin(tob->sizez, tob->oldsize+2, 0.0);
-
-       }
-       else {
-               if(tob->eff) VECCOPY(tob->eff, tob->oldeff);
-               if(tob->loc) VECCOPY(tob->loc, tob->oldloc);
-               if(tob->rot) VECCOPY(tob->rot, tob->oldrot);
-
-               QUATCOPY(tob->quat, tob->oldquat);
-               VECCOPY(tob->size, tob->oldsize);
-       }
-}
-
-int cylinder_intersect_test(void)
-{
-       EditMesh *em = G.editMesh;
-       extern float editbutsize;
-       float *oldloc, speed[3], s, t, labda, labdacor, dist, len, len2, axis[3], *base, rc[3], n[3], o[3];
-       EditVert *v1;
-       
-       v1= em->verts.first;
-
-       base= v1->co;
-       v1= v1->next;
-       VecSubf(axis, v1->co, base);
-       
-       v1= v1->next;
-       oldloc= v1->co;
-       v1= v1->next;
-       VecSubf(speed, v1->co, oldloc);
-       
-       VecSubf(rc, oldloc, base);
-       
-       /* the axis */
-       len2= Normalise(axis);
-       
-       Crossf(n, speed, axis);
-       len= Normalise(n);
-       if(len==0.0) return 0;
-       
-       dist= fabs( rc[0]*n[0] + rc[1]*n[1] + rc[2]*n[2] );
-       
-       if( dist>=editbutsize ) return 0;
-       
-       Crossf(o, rc, axis);
-       t= -(o[0]*n[0] + o[1]*n[1] + o[2]*n[2])/len;
-       
-       Crossf(o, n, axis);
-       s=  fabs(sqrt(editbutsize*editbutsize-dist*dist) / (o[0]*speed[0] + o[1]*speed[1] + o[2]*speed[2]));
-       
-       labdacor= t-s;
-       labda= t+s;
-
-       /* two cases with no intersection point */
-       if(labdacor>=1.0 && labda>=1.0) return 0;
-       if(labdacor<=0.0 && labda<=0.0) return 0;
-       
-       /* calc normal */
-       /* intersection: */
-       
-       rc[0]= oldloc[0] + labdacor*speed[0] - base[0];
-       rc[1]= oldloc[1] + labdacor*speed[1] - base[1];
-       rc[2]= oldloc[2] + labdacor*speed[2] - base[2];
-       
-       s= (rc[0]*axis[0] + rc[1]*axis[1] + rc[2]*axis[2]) ;
-       
-       if(s<0.0 || s>len2) return 0;
-       
-       n[0]= (rc[0] - s*axis[0]);
-       n[1]= (rc[1] - s*axis[1]);
-       n[2]= (rc[2] - s*axis[2]);
-
-       printf("var1: %f, var2: %f, var3: %f\n", labdacor, len2, s);    
-       printf("var1: %f, var2: %f, var3: %f\n", rc[0], rc[1], rc[2]);  
-       printf("var1: %f, var2: %f, var3: %f\n", n[0], n[1], n[2]);     
-
-       return 1;
-}
-
-int sphere_intersect_test(void)
-{
-       EditMesh *em = G.editMesh;
-       extern float editbutsize;
-       float *oldloc, speed[3], labda, labdacor, len, bsq, u, disc, *base, rc[3];
-       EditVert *v1;
-       
-       v1= em->verts.first;
-       base= v1->co;
-       
-       v1= v1->next;
-       oldloc= v1->co;
-       
-       v1= v1->next;
-       VecSubf(speed, v1->co, oldloc);
-       len= Normalise(speed);
-       if(len==0.0) return 0;
-       
-       VecSubf(rc, oldloc, base);
-       bsq= rc[0]*speed[0] + rc[1]*speed[1] + rc[2]*speed[2]; 
-       u= rc[0]*rc[0] + rc[1]*rc[1] + rc[2]*rc[2] - editbutsize*editbutsize;
-
-       disc= bsq*bsq - u;
-       
-       if(disc>=0.0) {
-               disc= sqrt(disc);
-               labdacor= (-bsq - disc)/len;    /* entry point */
-               labda= (-bsq + disc)/len;
-               
-               printf("var1: %f, var2: %f, var3: %f\n", labdacor, labda, editbutsize);
-       }
-       else return 0;
-
-       /* intersection and normal */
-       rc[0]= oldloc[0] + labdacor*speed[0] - base[0];
-       rc[1]= oldloc[1] + labdacor*speed[1] - base[1];
-       rc[2]= oldloc[2] + labdacor*speed[2] - base[2];
-
-
-       return 1;
-}
-
-#ifndef CLOCKS_PER_SEC
-#define CLOCKS_PER_SEC 1000000
-#endif
-
-int my_clock(void)
-{
-       float ftime;
-       
-       ftime= (float)clock();
-       ftime*= 100.0/CLOCKS_PER_SEC;
-       
-       return (int)ftime;
-}
-
-static void view_editmove(unsigned char event)
-{
-       /* Regular:   Zoom in */
-       /* Shift:     Scroll up */
-       /* Ctrl:      Scroll right */
-       /* Alt-Shift: Rotate up */
-       /* Alt-Ctrl:  Rotate right */
-
-       switch(event) {
-               case WHEELUPMOUSE:
-
-                       if( G.qual & LR_SHIFTKEY ) {
-                               if( G.qual & LR_ALTKEY ) { 
-                                       G.qual &= ~LR_SHIFTKEY;
-                                       persptoetsen(PAD2);
-                                       G.qual |= LR_SHIFTKEY;
-                               } else {
-                                       persptoetsen(PAD2);
-                               }
-                       } else if( G.qual & LR_CTRLKEY ) {
-                               if( G.qual & LR_ALTKEY ) { 
-                                       G.qual &= ~LR_CTRLKEY;
-                                       persptoetsen(PAD4);
-                                       G.qual |= LR_CTRLKEY;
-                               } else {
-                                       persptoetsen(PAD4);
-                               }
-                       } else if(U.uiflag & USER_WHEELZOOMDIR) 
-                               persptoetsen(PADMINUS);
-                       else
-                               persptoetsen(PADPLUSKEY);
-
-                       break;
-               case WHEELDOWNMOUSE:
-                       if( G.qual & LR_SHIFTKEY ) {
-                               if( G.qual & LR_ALTKEY ) { 
-                                       G.qual &= ~LR_SHIFTKEY;
-                                       persptoetsen(PAD8);
-                                       G.qual |= LR_SHIFTKEY;
-                               } else {
-                                       persptoetsen(PAD8);
-                               }
-                       } else if( G.qual & LR_CTRLKEY ) {
-                               if( G.qual & LR_ALTKEY ) { 
-                                       G.qual &= ~LR_CTRLKEY;
-                                       persptoetsen(PAD6);
-                                       G.qual |= LR_CTRLKEY;
-                               } else {
-                                       persptoetsen(PAD6);
-                               }
-                       } else if(U.uiflag & USER_WHEELZOOMDIR) 
-                               persptoetsen(PADPLUSKEY);
-                       else
-                               persptoetsen(PADMINUS);
-                       
-                       break;
-       }
-}
-
-/* *********************** AXIS CONSTRAINT HELPER LINE *************** */
-
-static void constline(float *center, float *dir, char axis, float axismat[][3])
-{
-/*     extern void make_axis_color(char *col, char *col2, char axis);  // drawview.c
-*/
-       float v1[3], v2[3], v3[3];
-       char col[3], col2[3];
-       
-       if(G.obedit) mymultmatrix(G.obedit->obmat);     // sets opengl viewing
-
-       VecCopyf(v3, dir);
-       VecMulf(v3, G.vd->far);
-       
-       VecSubf(v2, center, v3);
-       VecAddf(v1, center, v3);
-
-       BIF_GetThemeColor3ubv(TH_GRID, col);
-       make_axis_color(col, col2, axis);
-       glColor3ubv(col2);
-
-       setlinestyle(0);
-       glBegin(GL_LINE_STRIP); 
-               glVertex3fv(v1); 
-               glVertex3fv(v2); 
-       glEnd();
-       
-       if(axismat) {
-               float mat[4][4];
-               
-               Mat4CpyMat3(mat, axismat);
-               VecAddf(mat[3], mat[3], center);
-               
-               mymultmatrix(mat);
-               BIF_ThemeColor(TH_TEXT);
-               drawaxes(2.0);
-       }
-       
-       myloadmatrix(G.vd->viewmat);
-
-}
-
-
-#define XTRANS         0x01
-#define YTRANS         0x02
-#define ZTRANS         0x04
-#define TRANSLOCAL     0x80
-#define XTRANSLOCAL    (XTRANS|TRANSLOCAL)
-#define YTRANSLOCAL    (YTRANS|TRANSLOCAL)
-#define ZTRANSLOCAL    (ZTRANS|TRANSLOCAL)
-
-/* temporal storage for callback */
-struct constline_temp {
-       int mode, axismode, midtog;
-       float *centre, *vx, *vy, *vz;
-       float *imat;
-};
-
-static struct constline_temp cnst={0,0}; // init
-
-/* called while transform(), store the relevant values in struct  */
-static void set_constline_callback(int mode, int axismode, int midtog, 
-                                               float *centre, float imat[][3], float *vx, float *vy, float *vz)
-{
-       cnst.mode= mode;
-       cnst.axismode= axismode;
-       cnst.midtog= midtog;
-       cnst.centre= centre;
-       cnst.imat= (float *)imat;
-       cnst.vx= vx;
-       cnst.vy= vy;
-       cnst.vz= vz;
-}
-
-/* is called from drawview.c after drawing objects */
-void constline_callback(void)
-{
-       TransOb *tob;
-       int a;
-       
-       if(cnst.mode==0 || cnst.axismode==0) return;    // uninitialized or no helpline
-       
-       // check further:
-       if( (cnst.mode == 'C') || (cnst.mode == 'w') || (cnst.mode=='N') ) return; 
-       if( ((cnst.mode=='R')||(cnst.mode=='r')) && (cnst.midtog) ) return;
-               
-       if(G.obedit) {  // only one helpline in editmode
-               float matone[3][3];
-               Mat3One(matone);
-               
-               switch (cnst.axismode) {
-               case XTRANSLOCAL: constline(cnst.centre, cnst.vx, 'x', matone); break;
-               case YTRANSLOCAL: constline(cnst.centre, cnst.vy, 'y', matone); break;
-               case ZTRANSLOCAL: constline(cnst.centre, cnst.vz, 'z', matone); break;
-               case XTRANS: constline(cnst.centre, cnst.imat, 'x', NULL); break;
-               case YTRANS: constline(cnst.centre, cnst.imat+3, 'y', NULL); break;
-               case ZTRANS: constline(cnst.centre, cnst.imat+6, 'z', NULL); break;
-               }
-       }
-       else if(cnst.axismode < TRANSLOCAL) {   // for multiple objects one helpline...
-               switch (cnst.axismode) {
-               case XTRANS: constline(cnst.centre, cnst.vx, 'x', NULL); break;
-               case YTRANS: constline(cnst.centre, cnst.vy, 'y', NULL); break;
-               case ZTRANS: constline(cnst.centre, cnst.vz, 'z', NULL); break;
-               }
-       }
-       else {  // unless it's local transform
-               tob= transmain;
-               for(a=0; a<tottrans; a++, tob++) {
-                       switch (cnst.axismode) {
-                       case XTRANSLOCAL: constline(tob->loc, tob->axismat[0], 'x', tob->axismat); break;
-                       case YTRANSLOCAL: constline(tob->loc, tob->axismat[1], 'y', tob->axismat); break;
-                       case ZTRANSLOCAL: constline(tob->loc, tob->axismat[2], 'z', tob->axismat); break;
-                       }
-               }
-       }
-}
-
-/* *********************** END AXIS CONSTRAINT HELPER LINE *************** */
-/* *********************** TRANSFORM()  *************** */
-
-static char *transform_mode_to_string(int mode)
-{
-       switch(mode) {
-               case 'g':       return("Grab"); break;
-               case 's':       return("Scale"); break;
-               case 'r':       return("Rotate"); break;
-               case 'G':       return("Grab Proportional"); break;
-               case 'C':       return("Scale Proportional"); break;
-               case 'R':       return("Rotate Proportional"); break;
-               case 'S':       return("Shear"); break;
-               case 'N':       return("Shrink/Fatten"); break;
-               case 'w':       return("Warp"); break;
-               case 'd':       return("Duplicate"); break;
-                          case 'n':       return("Extrude"); break;
-                          case 'h':       return("Extrude"); break;
-               default:        return("Transform");
-       }
-}
-
-/* 
-'g' 'G' -> Grab / Grab with PET
-'n'     -> Grab with vert normal (after extrude)
-'r' 'R' -> Rotate / Rotate with PET
-'s' 'C' -> Scale / Scale with PET
-'S'            -> Shear
-'t'            -> Tilt
-'w'            -> Warp
-'N'            -> Shrink/Fatten
-*/
-void transform(int mode)
-{
-       short canceled = 0;
-       TransOb *tob;
-       TransVert *tv;
-       float *edge_creases=NULL;       /* edge transform isnt really supported... */
-       float vec[3], min[3], max[3], dvec[3], d_dvec[3], dvecp[3], rot0[3], rot1[3], rot2[3], axis[3];
-       float totmat[3][3], omat[3][3], imat[3][3], mat[3][3], tmat[3][3], phi, dphi;
-
-       float persinv[3][3], persmat[3][3], viewinv[4][4], imat4[4][4];
-       float *curs, dx1, dx2, dy1, dy2, eul[3], quat[4], rot[3], phi0, phi1, deler, rad = 0.0;
-       float sizefac, size[3], sizelo[3], smat[3][3], xref=1.0, yref=1.0, zref= 1.0;
-       float si, co, dist=0.0, startcircumfac = 0.0, circumfac, oldval[3];
-       int axismode=0, time, fast=0, a, midtog=0, firsttime=1, wrong= 0, cameragrab= 0, gridflag;
-       unsigned short event=0;
-       short mval[2], breakloop=0, doit, xn, yn, xc, yc, xo, yo = 0, val;
-       char str[100], *undostr;
-       int     keyflags = 0;
-
-       float addvec[3] = {0,0,0}; // for new typing code
-       short ax = 0, del = 0, typemode = 0; // also for new typing thingy
-       short pe[3] = {0,0,0}; // again for the same thing. Determines if the period key has been pressed.
-       short mi[3] = {1,1,1}; // same thing again. Determines whether or not the minus key has been pressed (in order to add or substract new numbers).
-       short numchange[3] = {0,0,0}; // Determines whether or not one axis recieved changes (mainly for scaling)
-
-       float vx[3] = {1,0,0}, vy[3] = {0,1,0}, vz[3] = {0,0,1};
-
-       if (mode % 'x' == 0)
-               axismode = XTRANSLOCAL;
-       else if (mode % 'X' == 0)
-               axismode = XTRANS;
-       else if (mode % 'y' == 0)
-               axismode = YTRANSLOCAL;
-       else if (mode % 'Y' == 0)
-               axismode = YTRANS;
-       else if (mode % 'z' == 0)
-               axismode = ZTRANSLOCAL;
-       else if (mode % 'Z' == 0)
-               axismode = ZTRANS;
-
-       if (mode % 'g' == 0)
-               mode = 'g';
-       else if (mode % 'r' == 0)
-               mode = 'r';
-       else if (mode % 's' == 0)
-               mode = 's';
-       
-       /* used in end of function */
-       undostr= transform_mode_to_string(mode);
-       
-       if(G.obedit && (G.f & G_PROPORTIONAL)) {
-               if(mode=='g') mode= 'G';
-               if(mode=='r') mode= 'R';
-               if(mode=='s') mode= 'C';
-       }
-       /* from duplicate or extrude routines */
-       if(mode=='d' || mode=='h') mode= 'g';
-
-       /* this can cause floating exception at dec alpha */
-       d_dvec[0]= d_dvec[1]= d_dvec[2]= 0.0;
-       dvec[0]= dvec[1]= dvec[2]= 0.0;
-
-       if(G.scene->id.lib) return;
-
-       if(mode=='t') {
-               if(G.obedit==0 || G.obedit->type!=OB_CURVE) return;
-       }
-       if(mode=='w' && G.obedit==0) return;
-
-       /* what data will be involved? */
-       if(G.obedit) {
-               if(mode=='N') vertexnormals(0);
-
-               /* min en max needed for warp */
-               if(mode=='G' || mode=='R' || mode=='C') make_trans_verts(min, max, 1);
-               else make_trans_verts(min, max, 0);
-       }
-       else if (G.obpose){
-
-               switch (G.obpose->type) {
-               case OB_ARMATURE:
-                       /* figure out which bones need calculating */
-                       figure_bone_nocalc(G.obpose);
-                       figure_pose_updating();
-                       make_trans_bones((char)mode);
-                       
-                       if(mode=='g' && tottrans==0) {
-                               mode= 'r';
-                               make_trans_bones((char)mode);
-                       }
-                       
-                       break;
-               }
-       }
-       else {
-               int opt= 0;
-               if (mode=='g' || mode=='G') opt= 'g';
-               else if (mode=='r' || mode=='R') opt= 'r';
-               else if (mode=='s' || mode=='S') opt= 's';
-
-               setbaseflags_for_editing(opt);
-               figure_pose_updating();
-               make_trans_objects();
-       }
-
-       if(tottrans==0) {
-               if(G.obedit==0) clearbaseflags_for_editing();
-               return;
-       }
-
-       if(G.obedit==0 && mode=='S') return;
-       
-       if(G.vd->around==V3D_LOCAL) {
-               if(G.obedit) {
-                       centre[0]= centre[1]= centre[2]= 0.0;
-               }
-
-       }
-       if(G.vd->around==V3D_CENTROID) {
-               VECCOPY(centre, centroid);
-       }
-       else if(G.vd->around==V3D_CURSOR) {
-               curs= give_cursor();
-               VECCOPY(centre, curs);
-
-               if(G.obedit) {
-                       VecSubf(centre, centre, G.obedit->obmat[3]);
-                       Mat3CpyMat4(mat, G.obedit->obmat);
-                       Mat3Inv(imat, mat);
-                       Mat3MulVecfl(imat, centre);
-               }
-
-       }
-
-       /* Always rotate around object centroid */
-       if (G.obpose){
-               VECCOPY (centre, centroid);
-       }
-
-       /* moving: is shown in drawobject() */
-       if(G.obedit) G.moving= 2;
-       else G.moving= 1;
-
-       areawinset(curarea->win);
-
-       /* the persinv is polluted with translation, do not use!! */
-       Mat3CpyMat4(persmat, G.vd->persmat);
-       Mat3Inv(persinv, persmat);
-
-       VECCOPY(rot0, persinv[0]);
-       Normalise(rot0);
-       VECCOPY(rot1, persinv[1]);
-       Normalise(rot1);
-       VECCOPY(rot2, persinv[2]);
-       Normalise(rot2);
-
-       /* init vars */
-
-       Mat4Invert(viewinv, G.vd->viewmat);
-
-       if(transvmain) {
-               VECCOPY(vec, centre);
-               Mat4MulVecfl(G.obedit->obmat, vec);
-               initgrabz(vec[0], vec[1], vec[2]);
-               project_short_noclip(vec, mval);
-       }
-       else {
-               /* voor panning from cameraview */
-               if( G.vd->camera==OBACT && G.vd->persp>1) {
-                       /* 6.0 = 6 grid units */
-                       centre[0]+= -6.0*rot2[0];
-                       centre[1]+= -6.0*rot2[1];
-                       centre[2]+= -6.0*rot2[2];
-               }
-
-               initgrabz(centre[0], centre[1], centre[2]);
-               project_short_noclip(centre, mval);
-
-               if( G.vd->camera==OBACT && G.vd->persp>1) {
-                       centre[0]+= 6.0*rot2[0];
-                       centre[1]+= 6.0*rot2[1];
-                       centre[2]+= 6.0*rot2[2];
-               }
-       }
-
-       VECCOPY(prop_cent, centre);
-
-       xc= mval[0];
-       yc= mval[1];
-
-       if(G.obedit) {
-               Mat3CpyMat4(omat, G.obedit->obmat);
-               Mat3Inv(imat, omat);
-
-               Mat4Invert(imat4, G.obedit->obmat);
-       }
-
-       else if(G.obpose) {
-               Mat3CpyMat4(omat, G.obpose->obmat);
-               Mat3Inv(imat, omat);
-
-               Mat4Invert(imat4, G.obpose->obmat);
-       }
-
-       else {
-               if(transmain) {
-                       if(OBACT &&  G.vd->persp>1 && G.vd->camera==OBACT) {
-                               cameragrab= 1;
-                               xc= curarea->winx/2;
-                               yc= curarea->winy/2;
-                       }
-               }
-       }
-
-       if((mode=='r' || mode=='s' || mode=='S') && xc==32000) {
-               error("Centre far out of view");
-               wrong= 1;
-       }
-
-       if(mode=='w' && G.obedit) {
-               Mat4MulVecfl(G.obedit->obmat, min);
-               Mat4MulVecfl(G.vd->viewmat, min);
-               Mat4MulVecfl(G.obedit->obmat, max);
-               Mat4MulVecfl(G.vd->viewmat, max);
-
-               centre[0]= (min[0]+max[0])/2.0;
-               centre[1]= (min[1]+max[1])/2.0;
-               centre[2]= (min[2]+max[2])/2.0;
-
-                       /* cursor is centre */
-               curs= give_cursor();
-               VECCOPY(axis, curs);
-               Mat4MulVecfl(G.vd->viewmat, axis);
-               rad= sqrt( (axis[0]-centre[0])*(axis[0]-centre[0])+(axis[1]-centre[1])*(axis[1]-centre[1]) );
-               dist= max[0]-centre[0];
-               if(dist==0.0) wrong= 1;
-               else startcircumfac= (90*rad*M_PI)/(360.0*dist);
-       }
-
-       getmouseco_areawin(mval);
-       xn=xo= mval[0];
-       yn=yo= mval[1];
-       dx1= xc-xn;
-       dy1= yc-yn;
-       phi= phi0= phi1= 0.0;
-
-       sizefac= sqrt( (float)((yc-yn)*(yc-yn)+(xn-xc)*(xn-xc)) );
-       if(sizefac<2.0) sizefac= 2.0;
-
-       gridflag= U.flag;
-
-       while(wrong==0 && breakloop==0) {
-
-               getmouseco_areawin(mval);
-               if(mval[0]!=xo || mval[1]!=yo || firsttime) {
-                       if(firsttime) {
-
-                               /* not really nice, but who cares! */
-                               oldval[0]= oldval[1]= oldval[2]= MAXFLOAT;
-
-                               /* proportional precalc */
-                               if(mode=='G' || mode=='R' || mode=='C') {
-                                       if(transvmain) {
-                                               tv= transvmain;
-                                               for(a=0; a<tottrans; a++, tv++) {
-                                                       set_proportional_weight(tv, min, max);
-                                               }
-                                       }
-                               }
-                       }
-                       firsttime= 0;
-
-                       if(mode=='g' || mode=='G' || mode=='n') {
-                               float dot; /* for grab along normal */
-                               char gmode[10] = "";
-
-                               keyflags |= KEYFLAG_LOC;
-
-                               if (axismode==XTRANSLOCAL) strcpy(gmode, "Local X: ");
-                               if (axismode==YTRANSLOCAL) strcpy(gmode, "Local Y: ");
-                               if (axismode==ZTRANSLOCAL) strcpy(gmode, "Local Z: ");
-                               if (axismode==XTRANS) strcpy(gmode, "X Axis: ");
-                               if (axismode==YTRANS) strcpy(gmode, "Y Axis: ");
-                               if (axismode==ZTRANS) strcpy(gmode, "Z Axis: ");
-
-                               if(axismode) {
-                                       if(cameragrab) {
-                                               dx1= 0.002*(mval[1]-yn)*G.vd->grid;
-                                               dvec[0]-= dx1*G.vd->viewinv[2][0];
-                                               dvec[1]-= dx1*G.vd->viewinv[2][1];
-                                               dvec[2]-= dx1*G.vd->viewinv[2][2];
-                                               firsttime= 1;   /* so it keeps going */
-                                       }
-                                       else {
-                                               window_to_3d(dvec, mval[0]-xn, mval[1]-yn);
-                                               if(axismode & XTRANS) dvec[1]=dvec[2]= 0.0;
-                                               if(axismode & YTRANS) dvec[0]=dvec[2]= 0.0;
-                                               if(axismode & ZTRANS) dvec[0]=dvec[1]= 0.0;
-                                       }
-                               }
-                               else window_to_3d(dvec, mval[0]-xn, mval[1]-yn);
-
-                               if (typemode){
-                                       dvec[0] = addvec[0];
-                                       dvec[1] = addvec[1];
-                                       dvec[2] = addvec[2];
-                                       if(axismode == XTRANS) dvec[1]=dvec[2]= 0.0;
-                                       if(axismode == YTRANS) dvec[0]=dvec[2]= 0.0;
-                                       if(axismode == ZTRANS) dvec[0]=dvec[1]= 0.0;
-                               }
-
-                               /* grids */
-                               if(G.qual & LR_SHIFTKEY) {
-                                       dvec[0]= 0.1*(dvec[0]-d_dvec[0])+d_dvec[0];
-                                       dvec[1]= 0.1*(dvec[1]-d_dvec[1])+d_dvec[1];
-                                       dvec[2]= 0.1*(dvec[2]-d_dvec[2])+d_dvec[2];
-                               }
-                               if (mode != 'n') {
-                                       apply_keyb_grid(dvec, 0.0, G.vd->grid, 0.1*G.vd->grid, gridflag & USER_AUTOGRABGRID);
-                                       apply_keyb_grid(dvec+1, 0.0, G.vd->grid, 0.1*G.vd->grid, gridflag & USER_AUTOGRABGRID);
-                                       apply_keyb_grid(dvec+2, 0.0, G.vd->grid, 0.1*G.vd->grid, gridflag & USER_AUTOGRABGRID);
-                               }
-
-                               if(dvec[0]!=oldval[0] ||dvec[1]!=oldval[1] ||dvec[2]!=oldval[2]) {
-                                       VECCOPY(oldval, dvec);
-
-                                       /* speedup for vertices */
-                                       if (G.obedit) {
-                                               VECCOPY(dvecp, dvec);
-                                               if (axismode&TRANSLOCAL && typemode) {
-                                                       if(axismode==XTRANSLOCAL) dvecp[1]=dvecp[2]=0;
-                                                       if(axismode==YTRANSLOCAL) dvecp[0]=dvecp[2]=0;
-                                                       if(axismode==ZTRANSLOCAL) dvecp[0]=dvecp[1]=0;
-                                                       VECCOPY(dvec, dvecp);
-                                               }
-                                               else {
-                                                       Mat3MulVecfl(imat, dvecp);
-                                                       if(axismode==XTRANSLOCAL) dvecp[1]=dvecp[2]=0;
-                                                       if(axismode==YTRANSLOCAL) dvecp[0]=dvecp[2]=0;
-                                                       if(axismode==ZTRANSLOCAL) dvecp[0]=dvecp[1]=0;
-                                                       if(axismode&TRANSLOCAL){
-                                                               VECCOPY(dvec, dvecp);
-                                                               Mat3MulVecfl(omat, dvec);
-                                                       }
-                                               }
-                                       }
-
-                                       if(mode=='n') {
-                                               if (typemode){
-                                                       dot = addvec[0];
-                                               }
-                                               else {
-                                                       tv= transvmain;
-                                                       if(tv->nor) {
-                                                               dot= tv->nor[0]*dvecp[0] + tv->nor[1]*dvecp[1] + tv->nor[2]*dvecp[2];
-                                                               apply_keyb_grid(&dot, 0.0, G.vd->grid, 0.1*G.vd->grid, gridflag & USER_AUTOGRABGRID);
-                                                               /* do not change dvec here, for d_dvec (hold shift) to keep working */
-                                                       }
-                                               }
-                                       }
-
-                                       /* apply */
-                                       tob= transmain;
-                                       tv= transvmain;
-
-                                       for(a=0; a<tottrans; a++, tob++, tv++) {
-
-                                               if(transmain) {
-                                                       VECCOPY(dvecp, dvec);
-                                                       if(axismode & TRANSLOCAL)
-                                                               Mat3MulVecfl(tob->axismat, dvecp);
-
-                                                       if(transmode==TRANS_TEX) Mat3MulVecfl(tob->obinv, dvecp);
-
-                                                       if(tob->flag & TOB_IKA) {
-                                                               VecAddf(tob->eff, tob->oldeff, dvecp);
-                                                       }
-                                                       else
-                                                               Mat3MulVecfl(tob->parinv, dvecp);
-
-                                                       if(tob->flag & TOB_IPO) {
-                                                               add_ipo_tob_poin(tob->locx, tob->oldloc, dvecp[0]);
-                                                               add_ipo_tob_poin(tob->locy, tob->oldloc+1, dvecp[1]);
-                                                               add_ipo_tob_poin(tob->locz, tob->oldloc+2, dvecp[2]);
-                                                       }
-                                                       else if(tob->loc) {
-                                                               VecAddf(tob->loc, tob->oldloc, dvecp);
-                                                       }
-                                               }
-                                               else {
-                                                       if(mode=='G') {
-                                                               tv->loc[0]= tv->oldloc[0]+tv->fac*dvecp[0];
-                                                               tv->loc[1]= tv->oldloc[1]+tv->fac*dvecp[1];
-                                                               tv->loc[2]= tv->oldloc[2]+tv->fac*dvecp[2];
-                                                       }
-                                                       else if(mode=='n' && tv->nor) {
-                                                               //float dot; /* dot product dvec with normal */
-                                                               
-                                                               //dot= tv->nor[0]*dvecp[0] + tv->nor[1]*dvecp[1] + tv->nor[2]*dvecp[2];
-                                                               tv->loc[0]= tv->oldloc[0]+dot*tv->nor[0];
-                                                               tv->loc[1]= tv->oldloc[1]+dot*tv->nor[1];
-                                                               tv->loc[2]= tv->oldloc[2]+dot*tv->nor[2];
-                                                       }
-                                                       else VecAddf(tv->loc, tv->oldloc, dvecp);
-                                               }
-
-                                       }
-
-                                       tv= transvmain;
-
-                                       if(mode=='n' && tv->nor) {
-                                               if (typemode)
-                                                       sprintf(str, "D: >%.4f< Along faces normal", dot);
-                                               else
-                                                       sprintf(str, "D: %.4f Along faces normal", dot);
-                                       }
-                                       else {
-                                               if (typemode){
-                                                       switch (ax){
-                                                       case 0:
-                                                               sprintf(str, "%sDx: >%.4f<   Dy: %.4f  Dz: %.4f", gmode, dvec[0], dvec[1], dvec[2]);
-                                                               break;
-                                                       case 1:
-                                                               sprintf(str, "%sDx: %.4f   Dy: >%.4f<  Dz: %.4f", gmode, dvec[0], dvec[1], dvec[2]);
-                                                               break;
-                                                       case 2:
-                                                               sprintf(str, "%sDx: %.4f   Dy: %.4f  Dz: >%.4f<", gmode, dvec[0], dvec[1], dvec[2]);
-                                                       }
-                                               }
-                                               else
-                                                       sprintf(str, "%sDx: %.4f   Dy: %.4f  Dz: %.4f", gmode, dvec[0], dvec[1], dvec[2]);
-                                       }
-                                       headerprint(str);
-
-                                       time= my_clock();
-
-                                       if(G.obedit) calc_trans_verts();
-                                       special_trans_update(keyflags);
-
-                                       if (cameragrab && midtog)
-                                               set_constline_callback(mode, ZTRANSLOCAL, midtog, centre, imat, vx, vy, vz);
-                                       else
-                                               set_constline_callback(mode, axismode, midtog, centre, imat, vx, vy, vz);
-
-                                       if(fast==0) {
-                                               force_draw(0);
-                                               time= my_clock()-time;
-                                               if(time>50) fast= 1;
-                                       }
-                                       else {
-                                               scrarea_do_windraw(curarea);
-                                               screen_swapbuffers();
-                                       }
-                               }
-                       }
-                       else if(mode=='r' || mode=='t' || mode=='R') {
-                               int turntable = 0;
-                               doit= 0;
-                               keyflags |= KEYFLAG_ROT;
-                               dx2= xc-mval[0];
-                               dy2= yc-mval[1];
-
-                               if(midtog && (mode=='r' || mode=='R')) {
-                                       turntable = 1;
-                                       phi0+= .007*(float)(dy2-dy1);
-                                       phi1+= .007*(float)(dx1-dx2);
-
-                                       apply_keyb_grid(&phi0, 0.0, (5.0/180)*M_PI, (1.0/180)*M_PI, gridflag & USER_AUTOROTGRID);
-                                       apply_keyb_grid(&phi1, 0.0, (5.0/180)*M_PI, (1.0/180)*M_PI, gridflag & USER_AUTOROTGRID);
-
-                                       if(typemode){
-                                               VecRotToMat3(rot0, addvec[1]*M_PI/180.0, smat);
-                                               VecRotToMat3(rot1, addvec[2]*M_PI/180.0, totmat);
-
-                                               Mat3MulMat3(mat, smat, totmat);
-                                               doit= 1;
-                                       }
-                                       else if(oldval[0]!=phi0 || oldval[1]!=phi1){
-                                               VecRotToMat3(rot0, phi0, smat);
-                                               VecRotToMat3(rot1, phi1, totmat);
-
-                                               Mat3MulMat3(mat, smat, totmat);
-                                               dx1= dx2;
-                                               dy1= dy2;
-                                               oldval[0]= phi0;
-                                               oldval[1]= phi1;
-                                               doit= 1;
-                                       }
-                               }
-                               else {
-                                       deler= sqrt( (dx1*dx1+dy1*dy1)*(dx2*dx2+dy2*dy2));
-                                       if(deler>1.0) {
-
-                                               dphi= (dx1*dx2+dy1*dy2)/deler;
-                                               dphi= saacos(dphi);
-                                               if( (dx1*dy2-dx2*dy1)>0.0 ) dphi= -dphi;
-
-                                               if(G.qual & LR_SHIFTKEY) phi+= dphi/30.0;
-                                               else phi+= dphi;
-
-                                               apply_keyb_grid(&phi, 0.0, (5.0/180)*M_PI, (1.0/180)*M_PI, gridflag & USER_AUTOROTGRID);
-
-                                               if(axismode) {
-                                                       if(axismode==XTRANS) vec[0]= -1.0; else vec[0]= 0.0;
-                                                       if(axismode==YTRANS) vec[1]= 1.0; else vec[1]= 0.0;
-                                                       if(axismode==ZTRANS) vec[2]= -1.0; else vec[2]= 0.0;
-                                                       if (G.obedit){
-                                                               if (axismode == XTRANSLOCAL) VECCOPY(vec, G.obedit->obmat[0]);
-                                                               if (axismode == YTRANSLOCAL) VECCOPY(vec, G.obedit->obmat[1]);
-                                                               if (axismode == ZTRANSLOCAL) VECCOPY(vec, G.obedit->obmat[2]);
-                                                               if (axismode & TRANSLOCAL) VecMulf(vec, -1.0);
-                                                       }
-                                               }
-
-                                               if(typemode){
-                                                       doit= 1;
-                                                       if(axismode) {
-                                                               VecRotToMat3(vec, addvec[0]*M_PI/180.0, mat);
-                                                       }
-                                                       else VecRotToMat3(rot2, addvec[0]*M_PI/180.0, mat);
-                                               }
-                                               else if(oldval[2]!=phi) {
-                                                       dx1= dx2;
-                                                       dy1= dy2;
-                                                       oldval[2]= phi;
-                                                       doit= 1;
-                                                       if(axismode) {
-                                                               VecRotToMat3(vec, phi, mat);
-                                                       }
-                                                       else VecRotToMat3(rot2, phi, mat);
-                                               }
-                                       }
-
-                               }
-                               
-                               if(doit) {
-                                       /* apply */
-                                       tob= transmain;
-                                       tv= transvmain;
-
-                                       for(a=0; a<tottrans; a++, tob++, tv++) {
-                                               if(transmain) {
-                                                       /* rotation in three steps:
-                                                        * 1. editrot correction for parent
-                                                        * 2. distill from this the euler. Always do this step because MatToEul is pretty weak
-                                                        * 3. multiply with its own rotation, calculate euler.
-                                                        */
-
-                                                       if ((G.vd->flag & V3D_ALIGN)==0) {
-
-                                                       /* Roll around local axis */
-                                                       if (mode=='r' || mode=='R'){
-
-                                                               if (tob && axismode && (turntable == 0)){
-                                                                       if (axismode == XTRANSLOCAL){
-                                                                               VECCOPY(vec, tob->axismat[0]);
-                                                                       }
-                                                                       if (axismode == YTRANSLOCAL){
-                                                                               VECCOPY(vec, tob->axismat[1]);
-                                                                       }
-                                                                       if (axismode == ZTRANSLOCAL){
-                                                                               VECCOPY(vec, tob->axismat[2]);
-                                                                       }
-                                                                       /* Correct the vector */
-                                                                               if(cameragrab==0) {     // because viewmat changes continious then
-                                                                                       if ((axismode & TRANSLOCAL) && ((G.vd->viewmat[0][2] * vec[0]+G.vd->viewmat[1][2] * vec[1]+G.vd->viewmat[2][2] * vec[2])>0)){
-                                                                                               vec[0]*=-1;
-                                                                                               vec[1]*=-1;
-                                                                                               vec[2]*=-1;
-                                                                                       }
-                                                                               }
-
-                                                                       if (typemode)
-                                                                               VecRotToMat3(vec, addvec[0] * M_PI / 180.0, mat);
-                                                                       else
-                                                                               VecRotToMat3(vec, phi, mat);
-
-                                                               }
-                                                       }
-                                                       Mat3MulSerie(smat, tob->parmat, mat, tob->parinv, 0, 0, 0, 0, 0);
-
-                                                       /* 2 */
-                                                       if( (tob->ob->transflag & OB_QUAT) == 0 && tob->rot){
-                                                               Mat3ToEul(smat, eul);
-                                                               EulToMat3(eul, smat);
-                                                       }
-
-                                                       /* 3 */
-                                                       /* we now work with rot+drot */
-
-                                                       if(tob->ob->transflag & OB_QUAT || !tob->rot) {
-
-                                                               /* drot+rot TO DO! */
-                                                               Mat3ToQuat(smat, quat); // Original
-                                                               QuatMul(tob->quat, quat, tob->oldquat);
-
-                                                               if(tob->flag & TOB_IPO) {
-
-                                                                       if(tob->flag & TOB_IPODROT) {
-                                                                               /* VecSubf(rot, eul, tob->oldrot); */
-                                                                       }
-                                                                       else {
-                                                                               /* VecSubf(rot, eul, tob->olddrot); */
-                                                                       }
-
-                                                                       /* VecMulf(rot, 9.0/M_PI_2); */
-                                                                       /* VecSubf(rot, rot, tob->oldrot+3); */
-
-                                                                       /* add_ipo_tob_poin(tob->rotx, tob->oldrot+3, rot[0]); */
-                                                                       /* add_ipo_tob_poin(tob->roty, tob->oldrot+4, rot[1]); */
-                                                                       /* add_ipo_tob_poin(tob->rotz, tob->oldrot+5, rot[2]); */
-
-                                                               }
-                                                               else {
-                                                                       /* QuatSub(tob->quat, quat, tob->oldquat); */
-                                                               }
-                                                       }
-                                                       else {
-                                                               VecAddf(eul, tob->oldrot, tob->olddrot);
-                                                               EulToMat3(eul, tmat);
-
-                                                               Mat3MulMat3(totmat, smat, tmat);
-
-                                                               Mat3ToEul(totmat, eul);
-
-                                                               /* Eul is not allowed to differ too much from old eul.
-                                                                * This has only been tested for dx && dz
-                                                                */
-
-                                                               compatible_eul(eul, tob->oldrot);
-
-                                                               if(tob->flag & TOB_IPO) {
-
-                                                                       if(tob->flag & TOB_IPODROT) {
-                                                                               VecSubf(rot, eul, tob->oldrot);
-                                                                       }
-                                                                       else {
-                                                                               VecSubf(rot, eul, tob->olddrot);
-                                                                       }
-
-                                                                       VecMulf(rot, 9.0/M_PI_2);
-                                                                       VecSubf(rot, rot, tob->oldrot+3);
-
-
-                                                                       add_ipo_tob_poin(tob->rotx, tob->oldrot+3, rot[0]);
-                                                                       add_ipo_tob_poin(tob->roty, tob->oldrot+4, rot[1]);
-                                                                       add_ipo_tob_poin(tob->rotz, tob->oldrot+5, rot[2]);
-
-                                                               }
-                                                               else {
-                                                                       VecSubf(tob->rot, eul, tob->olddrot);
-                                                               }
-
-                                                               /* See if we've moved */
-                                                               if (!VecCompare (tob->loc, tob->oldloc, 0.01)){
-                                                                       keyflags |= KEYFLAG_LOC;
-                                                               }
-
-                                                       }
-                                               }
-
-                                                       if(G.vd->around!=V3D_LOCAL && (!G.obpose))  {
-                                                               float vec[3];   // make local, the other vec stores rot axis
-
-                                                               /* translation */
-                                                               VecSubf(vec, tob->obvec, centre);
-                                                               Mat3MulVecfl(mat, vec);
-                                                               VecAddf(vec, vec, centre);
-                                                               /* vec now is the location where the object has to be */
-                                                               VecSubf(vec, vec, tob->obvec);
-                                                               Mat3MulVecfl(tob->parinv, vec);
-
-                                                               if(tob->flag & TOB_IPO) {
-                                                                       add_ipo_tob_poin(tob->locx, tob->oldloc, vec[0]);
-                                                                       add_ipo_tob_poin(tob->locy, tob->oldloc+1, vec[1]);
-                                                                       add_ipo_tob_poin(tob->locz, tob->oldloc+2, vec[2]);
-                                                               }
-                                                               else if(tob->loc) {
-                                                                       VecAddf(tob->loc, tob->oldloc, vec);
-                                                               }
-                                                       }
-                                               }
-                                               else {
-                                                       if(mode=='t') {
-                                                               if(tv->val) *(tv->val)= tv->oldval-phi;
-                                                       }
-                                                       else {
-
-                                                               if(mode=='R') {
-
-                                                                       if(midtog) {
-                                                                               if (typemode){
-                                                                                       VecRotToMat3(rot0, tv->fac*addvec[1] * M_PI / 180.0, smat);
-                                                                                       VecRotToMat3(rot1, tv->fac*addvec[2] * M_PI / 180.0, totmat);
-                                                                               }
-                                                                               else{
-                                                                                       VecRotToMat3(rot0, tv->fac*phi0, smat);
-                                                                                       VecRotToMat3(rot1, tv->fac*phi1, totmat);
-                                                                               }
-
-                                                                               Mat3MulMat3(mat, smat, totmat);
-                                                                       }
-                                                                       else {
-                                                                               if (typemode)
-                                                                                       VecRotToMat3(rot2, tv->fac*addvec[0] * M_PI / 180.0, mat);
-                                                                               else
-                                                                                       VecRotToMat3(rot2, tv->fac*phi, mat);
-                                                                       }
-
-                                                               }
-
-                                                               Mat3MulMat3(totmat, mat, omat);
-                                                               Mat3MulMat3(smat, imat, totmat);
-
-                                                               VecSubf(vec, tv->oldloc, centre);
-                                                               Mat3MulVecfl(smat, vec);
-
-                                                               VecAddf(tv->loc, vec, centre);
-                                                       }
-                                               }
-                                       }
-
-
-                                       if(midtog){
-                                               if (typemode){
-                                                       if (ax == 1)
-                                                               sprintf(str, "Rotx: >%.2f<  Roty: %.2f", addvec[1], addvec[2]);
-                                                       if (ax == 2)
-                                                               sprintf(str, "Rotx: %.2f  Roty: >%.2f<", addvec[1], addvec[2]);
-                                               }
-                                               else
-                                                       sprintf(str, "Rotx: %.2f  Roty: %.2f", 180.0*phi0/M_PI, 180.0*phi1/M_PI);
-                                       }
-                                       else if(axismode) {
-                                               if (typemode){
-                                                       if(axismode==XTRANS) sprintf(str, "Rot X: >%.2f<", addvec[0]);
-                                                       else if(axismode==YTRANS) sprintf(str, "Rot Y: >%.2f<", addvec[0]);
-                                                       else if(axismode==ZTRANS) sprintf(str, "Rot Z: >%.2f<", addvec[0]);
-                                                       else if(axismode==XTRANSLOCAL) sprintf(str, "Local Rot X: >%.2f<", addvec[0]);
-                                                       else if(axismode==YTRANSLOCAL) sprintf(str, "Local Rot Y: >%.2f<", addvec[0]);
-                                                       else if(axismode==ZTRANSLOCAL) sprintf(str, "Local Rot Z: >%.2f<", addvec[0]);
-                                               }
-                                               else{
-                                                       if(axismode==XTRANS) sprintf(str, "Rot X: %.2f", 180.0*phi/M_PI);
-                                                       else if(axismode==YTRANS) sprintf(str, "Rot Y: %.2f", 180.0*phi/M_PI);
-                                                       else if(axismode==ZTRANS) sprintf(str, "Rot Z: %.2f", 180.0*phi/M_PI);
-                                                       else if(axismode==XTRANSLOCAL) sprintf(str, "Local Rot X: %.2f", 180.0*phi/M_PI);
-                                                       else if(axismode==YTRANSLOCAL) sprintf(str, "Local Rot Y: %.2f", 180.0*phi/M_PI);
-                                                       else if(axismode==ZTRANSLOCAL) sprintf(str, "Local Rot Z: %.2f", 180.0*phi/M_PI);
-                                               }
-                                       }
-                                       else{
-                                               if (typemode)
-                                                       sprintf(str, "Rot: >%.2f<", addvec[0]);
-                                               else
-                                                       sprintf(str, "Rot: %.2f", 180.0*phi/M_PI);
-                                       }
-                                       headerprint(str);
-
-                                       time= my_clock();
-
-                                       if(G.obedit) calc_trans_verts();
-                                       special_trans_update(keyflags);
-
-                                       set_constline_callback(mode, axismode, midtog, centre, imat, vx, vy, vz);
-
-                                       if(fast==0) {
-                                               force_draw(0);
-                                               time= my_clock()-time;
-                                               if(time>50) fast= 1;
-                                       }
-                                       else {
-                                               scrarea_do_windraw(curarea);
-                                               screen_swapbuffers();
-                                       }
-                                       if(tottrans>1 || G.vd->around==V3D_CURSOR) helpline(centre);
-                                       else if (G.obpose) helpline (centre);
-                               }
-                       }
-                       else if(mode=='s' || mode=='S' || mode=='C' || mode=='N') {
-                               keyflags |= KEYFLAG_SIZE;
-
-                               if(mode=='S') {
-                                       size[0]= 1.0-(float)(xn-mval[0])*0.005;
-                                       size[1]= 1.0-(float)(yn-mval[1])*0.005;
-                                       size[2]= 1.0;
-                               }
-                               else size[0]=size[1]=size[2]= (sqrt( (float)((yc-mval[1])*(yc-mval[1])+(mval[0]-xc)*(mval[0]-xc)) ))/sizefac;
-
-                               if (mode=='s') {
-                                       if (typemode){
-                                               if (numchange[0]) size[0] = addvec[0]; else size[0] = 1;
-                                               if (numchange[1]) size[1] = addvec[1]; else size[1] = 1;
-                                               if (numchange[2]) size[2] = addvec[2]; else size[2] = 1;
-                                       }
-                               }
-                               else {
-                                       if (typemode){
-                                               if (numchange[0])
-                                                       size[0] = size[1] = size[2] = addvec[0];
-                                               else
-                                                       size[0] = size[1] = size[2] = 1;
-                                       }
-                               }
-
-                               if(axismode && mode=='s') {
-                                       /* shear has no axismode */
-                                       if (!(G.obedit)){
-                                               if(axismode==XTRANS) axismode = XTRANSLOCAL;
-                                               if(axismode==YTRANS) axismode = YTRANSLOCAL;
-                                               if(axismode==ZTRANS) axismode = ZTRANSLOCAL;
-                                       }
-                                       if(axismode==XTRANS) size[1]=size[2]= 1.0;
-                                       if(axismode==YTRANS) size[0]=size[2]= 1.0;
-                                       if(axismode==ZTRANS) size[1]=size[0]= 1.0;
-                                       if(axismode==XTRANSLOCAL) size[1]=size[2]= 1.0;
-                                       if(axismode==YTRANSLOCAL) size[0]=size[2]= 1.0;
-                                       if(axismode==ZTRANSLOCAL) size[1]=size[0]= 1.0;
-                               }
-
-/* X en Y flip, there are 2 methods: at  |**| removing comments makes flips local
-
-                               if(transvmain) {
-
-                                               // x flip
-                                       val= test_midtog_proj(mval[0]+10, mval[1], mval);
-                                       size[val]*= xref;
-                                               // y flip
-                                       val= test_midtog_proj(mval[0], mval[1]+10, mval);
-                                       size[val]*= yref;
-
-                               } */
-
-
-                               /* grid */
-                               apply_keyb_grid(size, 0.0, 0.1, 0.01, gridflag & USER_AUTOSIZEGRID);
-                               apply_keyb_grid(size+1, 0.0, 0.1, 0.01, gridflag & USER_AUTOSIZEGRID);
-                               apply_keyb_grid(size+2, 0.0, 0.1, 0.01, gridflag & USER_AUTOSIZEGRID);
-
-                               if(transmain) {
-                                       size[0]= MINSIZE(size[0], 0.001);
-                                       size[1]= MINSIZE(size[1], 0.001);
-                                       size[2]= MINSIZE(size[2], 0.001);
-                               }
-
-                               if(size[0]!=oldval[0] ||size[1]!=oldval[1] ||size[2]!=oldval[2]) {
-                                       VECCOPY(oldval, size);
-
-                                       SizeToMat3(size, mat);
-
-                                       /* apply */
-                                       tob= transmain;
-                                       tv= transvmain;
-
-                                       for(a=0; a<tottrans; a++, tob++, tv++) {
-                                               if(transmain) {
-                                                       /* size local with respect to parent AND own rotation */
-                                                       /* local wrt parent: */
-
-                                                       if ((G.vd->flag & V3D_ALIGN)==0) {
-
-                                                       Mat3MulSerie(smat, tob->parmat, mat, tob->parinv, 0, 0,0 ,0, 0);
-
-                                                       /* local wrt own rotation: */
-                                                       Mat3MulSerie(totmat, tob->obmat, smat, tob->obinv, 0, 0, 0,0 ,0);
-
-                                                       /* XXX this can yield garbage in case of inverted sizes (< 0.0)
-                                                                                                       */
-                                                       if(!midtog) {
-                                                               sizelo[0]= size[0];
-                                                               sizelo[1]= size[1];
-                                                               sizelo[2]= size[2];
-                                                       } else {
-                                                       /* in this case the previous calculation of the size is wrong */
-                                                               sizelo[0]= totmat[0][0];
-                                                               sizelo[1]= totmat[1][1];
-                                                               sizelo[2]= totmat[2][2];
-                                                               apply_keyb_grid(sizelo, 0.0, 0.1, 0.01, gridflag & USER_AUTOSIZEGRID);
-                                                               apply_keyb_grid(sizelo+1, 0.0, 0.1, 0.01, gridflag & USER_AUTOSIZEGRID);
-                                                               apply_keyb_grid(sizelo+2, 0.0, 0.1, 0.01, gridflag & USER_AUTOSIZEGRID);
-                                                       }
-
-                                                               /* x flip */
-    /**/                                               /* sizelo[0]*= xref; */
-                                                               /* y flip */
-    /**/                                               /* sizelo[1]*= yref; */
-                                                               /* z flip */
-    /**/                                               /* sizelo[2]*= zref; */
-
-
-                                                       /* what you see is what you want; not what you get! */
-                                                       /* correction for delta size */
-                                                       if(tob->flag & TOB_IPO) {
-                                                               /* calculate delta size (equal for size and dsize) */
-
-                                                               vec[0]= (tob->oldsize[0]+tob->olddsize[0])*(sizelo[0] -1.0);
-                                                               vec[1]= (tob->oldsize[1]+tob->olddsize[1])*(sizelo[1] -1.0);
-                                                               vec[2]= (tob->oldsize[2]+tob->olddsize[2])*(sizelo[2] -1.0);
-
-                                                               add_ipo_tob_poin(tob->sizex, tob->oldsize+3, vec[0]);
-                                                               add_ipo_tob_poin(tob->sizey, tob->oldsize+4, vec[1]);
-                                                               add_ipo_tob_poin(tob->sizez, tob->oldsize+5, vec[2]);
-
-                                                       }
-                                                       else {
-                                                               tob->size[0]= (tob->oldsize[0]+tob->olddsize[0])*sizelo[0] -tob->olddsize[0];
-                                                               tob->size[1]= (tob->oldsize[1]+tob->olddsize[1])*sizelo[1] -tob->olddsize[1];
-                                                               tob->size[2]= (tob->oldsize[2]+tob->olddsize[2])*sizelo[2] -tob->olddsize[2];
-                                                       }
-                                                       } else {
-                                                               sizelo[0]= size[0];
-                                                               sizelo[1]= size[1];
-                                                               sizelo[2]= size[2];
-                                                       }
-
-                                                       if(G.vd->around!=V3D_LOCAL && !G.obpose) {
-                                                               /* translation */
-                                                               VecSubf(vec, tob->obvec, centre);
-                                                               Mat3MulVecfl(mat, vec);
-                                                               VecAddf(vec, vec, centre);
-                                                               /* vec is the location where the object has to be */
-                                                               VecSubf(vec, vec, tob->obvec);
-                                                               Mat3MulVecfl(tob->parinv, vec);
-
-                                                               if(tob->flag & TOB_IPO) {
-                                                                       add_ipo_tob_poin(tob->locx, tob->oldloc, vec[0]);
-                                                                       add_ipo_tob_poin(tob->locy, tob->oldloc+1, vec[1]);
-                                                                       add_ipo_tob_poin(tob->locz, tob->oldloc+2, vec[2]);
-                                                               }
-                                                               else if(tob->loc) {
-                                                                       if(transmode==TRANS_TEX) ;
-                                                                       else  VecAddf(tob->loc, tob->oldloc, vec);
-                                                               }
-                                                       }
-                                               }
-                                               else {  /* vertices */
-
-                                                       /* for print */
-                                                       VECCOPY(sizelo, size);
-
-                                                       if(mode=='C') {
-                                                               size[0]= tv->fac*size[0]+ 1.0-tv->fac;;
-                                                               size[1]= tv->fac*size[1]+ 1.0-tv->fac;;
-                                                               size[2]= tv->fac*size[2]+ 1.0-tv->fac;;
-                                                               SizeToMat3(size, mat);
-                                                               VECCOPY(size, oldval);
-                                                       }
-
-                                                       if(mode=='S') { /* shear */
-                                                               Mat3One(tmat);
-                                                               tmat[0][0]= tmat[2][2]= tmat[1][1]= 1.0;
-                                                               tmat[1][0]= size[0]-1.0;
-
-                                                               Mat3MulMat3(totmat, persmat, omat);
-                                                               Mat3MulMat3(mat, tmat, totmat);
-                                                               Mat3MulMat3(totmat, persinv, mat);
-                                                               Mat3MulMat3(smat, imat, totmat);
-                                                       }
-                                                       else {
-                                                               if (axismode & TRANSLOCAL)
-                                                                       Mat3CpyMat3(smat, mat);
-                                                               else {
-                                                                       Mat3MulMat3(totmat, imat, mat);
-                                                                       Mat3MulMat3(smat, totmat, omat);
-                                                               }
-                                                       }
-
-                                                       if(mode=='N' && tv->nor!=NULL) {
-                                              &