Stage two of the giant animation recode project; Ipo/Action/NLA cleanup
[blender.git] / source / blender / src / editobject.c
index 8a0de0e48ec55c9a299049d698329c6bf3c6ec40..d46c06bd4b9ecd39d24e73a5bfa9fafbb59b5536 100644 (file)
@@ -81,6 +81,7 @@
 #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 "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_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"
 
 /* --------------------------------- */
 
-Base *dupfontbase;
-
 void add_object_draw(int type) /* for toolbox or menus, only non-editmode stuff */
 {
        Object *ob;
@@ -182,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... */
@@ -241,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;
        
@@ -250,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);
@@ -279,7 +278,7 @@ void delete_obj(int ok)
        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;
@@ -291,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;
        
@@ -302,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;
@@ -340,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;
        
@@ -356,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;
@@ -370,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;
@@ -410,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;
        
@@ -450,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;
@@ -468,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++;
 
@@ -491,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++;
@@ -502,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");
 
@@ -541,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");
@@ -554,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);
@@ -565,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);
                                
@@ -606,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 */
@@ -627,35 +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");
 }
 
@@ -799,7 +869,7 @@ void clear_parent(void)
                        if(mode==1 || mode==2) {
                                par= base->object->parent;
                                base->object->parent= NULL;
-                               base->object->recalc |= OB_RECALC_OB;
+                               base->object->recalc |= OB_RECALC;
                                
                                if(mode==2) {
                                        base->object->track= NULL;
@@ -808,14 +878,14 @@ void clear_parent(void)
                        }
                        else if(mode==3) {
                                Mat4One(base->object->parentinv);
-                               base->object->recalc |= OB_RECALC_OB;
+                               base->object->recalc |= OB_RECALC;
                        }
                }
                base= base->next;
        }
 
        DAG_scene_sort(G.scene);
-       DAG_scene_flush_update(G.scene);
+       DAG_scene_flush_update(G.scene, screen_view3d_layers());
        allqueue(REDRAWVIEW3D, 0);
        allqueue(REDRAWOOPS, 0);
        
@@ -870,62 +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);
-                       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);
-                       }
-                       else if(mode=='g') {
-                               memset(ob->loc, 0, 3*sizeof(float));
-                               memset(ob->dloc, 0, 3*sizeof(float));
+                       if(ob->flag & OB_POSEMODE) {
+                               // no test if we got armature; could be in future...
+                               clear_armature(ob, mode);
                        }
-                       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);
                                }
-                       }
-                       
-                       ob->recalc |= OB_RECALC_OB;
-                       
+                               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);
+                                       }
+                               }
+                               
+                               ob->recalc |= OB_RECALC_OB;
+                       }                       
                }
                base= base->next;
        }
        
        allqueue(REDRAWVIEW3D, 0);
-       DAG_scene_flush_update(G.scene);
+       DAG_scene_flush_update(G.scene, screen_view3d_layers());
        BIF_undo_push(str);
 }
 
@@ -1120,10 +1183,8 @@ void make_parent(void)
 {
        Base *base;
        Object *par;
-       short qual, mode=0;
-       char *bonestr=NULL;
        Bone    *bone=NULL;
-       int     bonenr;
+       short qual, mode=0;
 
        if(G.scene->id.lib) return;
        if(G.obedit) {
@@ -1136,7 +1197,19 @@ 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;
 
@@ -1153,7 +1226,7 @@ void make_parent(void)
                        mode= PAROBJECT;
                        if((cu->flag & CU_PATH)==0) {
                                cu->flag |= CU_PATH|CU_FOLLOW;
-                               makeDispList(par);  // force creation of path data
+                               makeDispListCurveTypes(par, 0);  // force creation of path data
                        }
                        else cu->flag |= CU_FOLLOW;
                }
@@ -1194,57 +1267,58 @@ void make_parent(void)
                }
        }
        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(par);
+                       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);
 
-                               bone=get_indexed_bone(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) {
@@ -1282,11 +1356,11 @@ void make_parent(void)
                                }
                                else {
                                        
-                                       base->object->recalc |= OB_RECALC_OB;
+                                       base->object->recalc |= OB_RECALC_OB|OB_RECALC_DATA;
                                        
                                        /* the ifs below are horrible code (ton) */
                                        
-                                       if (par->type==OB_ARMATURE){
+                                       if (par->type==OB_ARMATURE) {
                                                base->object->partype= mode;
                                                if (bone)
                                                        strcpy (base->object->parsubstr, bone->name);
@@ -1297,7 +1371,7 @@ 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 {
@@ -1334,7 +1408,6 @@ void make_parent(void)
                                        
                                        if(par->type==OB_ARMATURE && mode == PARSKEL){
                                                verify_defgroups(base->object);
-                                               base->object->recalc |= OB_RECALC_DATA;
                                        }
                                }
                        }
@@ -1345,7 +1418,7 @@ void make_parent(void)
        allqueue(REDRAWOOPS, 0);
        
        DAG_scene_sort(G.scene);
-       DAG_scene_flush_update(G.scene);
+       DAG_scene_flush_update(G.scene, screen_view3d_layers());
        
        BIF_undo_push("make Parent");
 }
@@ -1359,13 +1432,14 @@ void enter_editmode(void)
        Mesh *me;
        int ok= 0;
        bArmature *arm;
-       Curve *cu;
        
        if(G.scene->id.lib) return;
        base= BASACT;
        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;
        
@@ -1401,20 +1475,6 @@ void enter_editmode(void)
                allqueue (REDRAWVIEW3D,0);
        }
        else if(ob->type==OB_FONT) {
-               cu= ob->data;
-               if ((cu->flag & CU_FAST)==0) { 
-                       base->flag |= SELECT;
-                       ob->flag |= SELECT;
-                       G.qual |= LR_ALTKEY;    /* patch to make sure we get a linked duplicate */
-                       adduplicate(1);
-                       G.qual &= ~LR_ALTKEY;
-                       dupfontbase = BASACT;
-                       BASACT->flag &= ~SELECT;
-                       BASACT->object->flag &= ~SELECT;
-                       set_active_base(base);
-                       base->flag |= SELECT;
-                       base->object->flag |= SELECT;
-               }
                G.obedit= ob;
                ok= 1;
                make_editText();
@@ -1447,15 +1507,11 @@ void enter_editmode(void)
        }
        else G.obedit= NULL;
 
-       if (G.obpose)
-               exit_posemode (1);
-       
        scrarea_queue_headredraw(curarea);
 }
 
 void exit_editmode(int freedata)       /* freedata==0 at render, 1= freedata, 2= do undo buffer too */
 {
-       Base *oldbase;
        Object *ob;
 
        if(G.obedit==NULL) return;
@@ -1477,8 +1533,6 @@ 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();
@@ -1508,33 +1562,14 @@ void exit_editmode(int freedata)        /* freedata==0 at render, 1= freedata, 2= do un
        if(freedata) G.obedit= NULL;
 
        /* total remake of softbody data */
-       if(ob->softflag & OB_SB_ENABLE) {
-               SoftBody *sb= ob->soft;
-               
-               if(sb->keys) {
-                       if( okee("Erase Baked SoftBody") )
-                               sbObjectToSoftbody(ob);
+       if(modifiers_isSoftbodyEnabled(ob)) {
+               if (ob->soft && ob->soft->keys) {
+                       notice("Erased Baked SoftBody");
                }
-               else sbObjectToSoftbody(ob);
-       }
-       DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
 
-       // evil HACK!
-       if ((ob->type == OB_FONT) && (freedata)) {
-               Curve *cu= ob->data;
-               if ((cu->flag & CU_FAST)==0) {
-                       oldbase = BASACT;
-                       BASACT->flag &= ~SELECT;
-                       BASACT->object->flag &= ~SELECT;
-                       set_active_base(dupfontbase);
-                       BASACT->flag |= SELECT;
-                       BASACT->object->flag |= SELECT;
-                       delete_obj(1);
-                       oldbase->flag |= SELECT;
-                       oldbase->object->flag |= SELECT;
-                       set_active_base(oldbase);
-               }
+               sbObjectToSoftbody(ob);
        }
+       DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
 
        if(freedata) {
                setcursor_space(SPACE_VIEW3D, CURSOR_STD);
@@ -1703,8 +1738,6 @@ void docentre(int centremode)
                                                        ob= ob->id.next;
                                                }
                                        }
-                                       /* DO: check all users... */
-                                       tex_space_mesh(me);
                                }
                                else if ELEM(base->object->type, OB_CURVE, OB_SURF) {
                                                                        
@@ -1788,14 +1821,13 @@ void docentre(int centremode)
 
                                        allqueue(REDRAWBUTSEDIT, 0);
                                }
-                               base->object->recalc |= OB_RECALC_DATA;
+                               DAG_object_flush_update(G.scene, base->object, OB_RECALC_OB|OB_RECALC_DATA);
                        }
                }
                base= base->next;
        }
 
        allqueue(REDRAWVIEW3D, 0);
-       DAG_scene_flush_update(G.scene);
        BIF_undo_push("Do Centre");     
 }
 
@@ -1881,7 +1913,7 @@ void split_font()
                text_to_curve(OBACT, 0);        // pass 1: only one letter, adapt position
                text_to_curve(OBACT, 0);        // pass 2: remake
                freedisplist(&OBACT->disp);
-               makeDispList(OBACT);
+               makeDispListCurveTypes(OBACT, 0);
                
                OBACT->flag &= ~SELECT;
                BASACT->flag &= ~SELECT;
@@ -1893,18 +1925,20 @@ void split_font()
 
 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.obpose) {
-               pose_special_editmenu();
-       }
-       else 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;
                        
@@ -1940,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;
                        
@@ -1959,19 +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;
-                       Object *ob= OBACT;
                        
                        // Get the active object mesh.
                        Mesh *me= get_mesh(ob);
 
-                       // If the active object is a mesh...
+                       // 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.
@@ -1979,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) {
+                                       for(base= FIRSTBASE; base; base= base->next) {
                                                if TESTBASELIB(base) {
-                                                       if(base->object != OBACT) base_select= 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");
                                                }
@@ -2010,7 +2068,7 @@ void special_editmenu(void)
 
                                allqueue(REDRAWVIEW3D, 0);
                        }
-                       else if (OBACT->type == OB_FONT) {
+                       else if (ob->type == OB_FONT) {
                                nr= pupmenu("Split %t|Characters%x1");
                                if (nr > 0) {
                                        switch(nr) {
@@ -2022,30 +2080,39 @@ void special_editmenu(void)
        }
        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:
@@ -2067,7 +2134,25 @@ 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;
+               }
                
                DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
                
@@ -2089,6 +2174,13 @@ void special_editmenu(void)
                
                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();
        allqueue(REDRAWVIEW3D, 0);
@@ -2129,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;
@@ -2155,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) {
@@ -2229,7 +2311,10 @@ void convertmenu(void)
                                        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;
                                                }
                                        }
@@ -2242,7 +2327,7 @@ void convertmenu(void)
                                        cu= ob->data;
                                        
                                        dl= cu->disp.first;
-                                       if(dl==0) makeDispList(ob);             // force creation
+                                       if(dl==0) makeDispListCurveTypes(ob, 0);                // force creation
 
                                        nurbs_to_mesh(ob); /* also does users */
 
@@ -2251,7 +2336,7 @@ void convertmenu(void)
                                        enter_editmode();
                                        exit_editmode(1); // freedata, but no undo
                                        BASACT= basact;
-                               }
+                               }
                        }
                        else if(ob->type==OB_MBALL) {
                        
@@ -2264,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;
@@ -2286,7 +2372,6 @@ void convertmenu(void)
                                                }
                                                
                                                mball_to_mesh(&ob->disp, ob1->data);
-                                               tex_space_mesh(me);
                                        }
                                }
                        }
@@ -2296,12 +2381,14 @@ void convertmenu(void)
                        free_and_unlink_base(basedel);  
                basedel = NULL;                         
        }
-       
+
        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
@@ -2309,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 (md) {
+               SubsurfModifierData *smd = (SubsurfModifierData*) md;
 
-       if (level == -1) {
-               me->flag ^= ME_SUBSURF;
+               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);   // no dependency?
+       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;
@@ -2391,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;
        
@@ -2425,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
@@ -2446,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");
@@ -2455,6 +2632,10 @@ void copy_attr_menu()
 
        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;
        
@@ -2466,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;
@@ -2491,6 +2673,10 @@ void copy_attr(short event)
                copymenu_logicbricks(ob);
                return;
        }
+       else if(event==24) {
+               copymenu_modifiers(ob);
+               return;
+       }
 
        base= FIRSTBASE;
        while(base) {
@@ -2545,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);
                                        }
@@ -2601,6 +2787,24 @@ void copy_attr(short event)
                                                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 */
                                        PartEff *pa1, *pa2;
                                        char *p1, *p2;
@@ -2629,14 +2833,19 @@ void copy_attr(short event)
                                }
                                else if(event==21){
                                        if (base->object->type==OB_MESH) {
-                                               Mesh *targetme= base->object->data;
-                                               Mesh *sourceme= ob->data;
+                                               ModifierData *md = modifiers_findByType(ob, eModifierType_Subsurf);
 
-                                               targetme->flag= (targetme->flag&~ME_SUBSURF) | (sourceme->flag&ME_SUBSURF);
-                                               targetme->subsurftype = sourceme->subsurftype;
-                                               targetme->subdiv= sourceme->subdiv;
-                                               targetme->subdivr= sourceme->subdivr;
-                                               base->object->recalc |= OB_RECALC_DATA;
+                                               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) {
@@ -2649,15 +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);
-
-                                       base->object->activecon = 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);
+
+                                       if (!modifiers_findByType(base->object, eModifierType_Softbody)) {
+                                               BLI_addhead(&base->object->modifiers, modifier_new(eModifierType_Softbody));
+                                       }
                                }
                        }
                }
@@ -2665,7 +2876,7 @@ void copy_attr(short event)
        }
        
        allqueue(REDRAWVIEW3D, 0);
-       DAG_scene_flush_update(G.scene);
+       DAG_scene_flush_update(G.scene, screen_view3d_layers());
 
        if(event==20) {
                allqueue(REDRAWBUTSOBJECT, 0);
@@ -2818,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 */
@@ -2886,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");
 }
 
@@ -3306,6 +3521,14 @@ void std_rmouse_transform(void (*xf_func)(int, int))
                getmouseco_areawin(mval);
                if(abs(mval[0]-xo)+abs(mval[1]-yo) > 10) {
                        if(curarea->spacetype==SPACE_VIEW3D) {
+#ifdef TWEAK_MODE
+                               initTransform(TFM_TRANSLATION, CTX_TWEAK);
+#else
+                               initTransform(TFM_TRANSLATION, CTX_NONE);
+#endif
+                               Transform();
+                       }
+                       else if(curarea->spacetype==SPACE_IMAGE) {
                                initTransform(TFM_TRANSLATION, CTX_NONE);
                                Transform();
                        }
@@ -3319,8 +3542,10 @@ void std_rmouse_transform(void (*xf_func)(int, int))
                        PIL_sleep_ms(10);
                        timer++;
                        if(timer>=10*U.tb_rightmouse) {
-                               toolbox_n();
-                               return;
+                               if(curarea->spacetype==SPACE_VIEW3D) {
+                                       toolbox_n();
+                                       return;
+                               }
                        }
                }
        }
@@ -3337,6 +3562,10 @@ void rightmouse_transform(void)
 /* ************************************** */
 
 
+static void single_object_users__forwardModifierLinks(void *userData, Object *ob, Object **obpoin)
+{
+       ID_NEW(*obpoin);
+}
 void single_object_users(int flag)     
 {
        Base *base;
@@ -3378,17 +3607,10 @@ void single_object_users(int flag)
                                                relink_constraints(&chan->constraints);
                                        }
                                }
-                               if(base->object->hooks.first) {
-                                       ObHook *hook= base->object->hooks.first;
-                                       while(hook) {
-                                               ID_NEW(hook->parent);
-                                               hook= hook->next;
-                                       }
-                               }
+                               modifiers_foreachObjectLink(base->object, single_object_users__forwardModifierLinks, NULL);
                                
                                ID_NEW(ob->parent);
                                ID_NEW(ob->track);
-                               
                        }
                }
                base= base->next;
@@ -3469,7 +3691,9 @@ void single_obdata_users(int flag)
                                        ob->data= copy_lattice(ob->data);
                                        break;
                                case OB_ARMATURE:
-                                       ob->data=copy_armature(ob->data);
+                                       ob->recalc |= OB_RECALC_DATA;
+                                       ob->data= copy_armature(ob->data);
+                                       armature_rebuild_pose(ob, ob->data);
                                        break;
                                default:
                                        printf("ERROR single_obdata_users: %s\n", id->name);
@@ -3489,8 +3713,7 @@ void single_obdata_users(int flag)
                                        id_us_plus(id->newid);
                                }
                                else {
-                                       ob->action=copy_action(ob->action);
-                                       ob->activecon=NULL;
+                                       ob->action= copy_action(ob->action);
                                        id->us--;
                                        id->newid=(ID *)ob->action;
                                }
@@ -3905,7 +4128,10 @@ void make_local(void)
        BIF_undo_push("Make local");
 }
 
-
+static void adduplicate__forwardModifierLinks(void *userData, Object *ob, Object **obpoin)
+{
+       ID_NEW(*obpoin);
+}
 void adduplicate(int noTrans)
 /* dtrans is 3 x 3xfloat dloc, drot en dsize */
 {
@@ -3913,6 +4139,7 @@ void adduplicate(int noTrans)
        Object *ob, *obn;
        Material ***matarar, *ma, *mao;
        ID *id;
+       Ipo *ipo;
        bConstraintChannel *chan;
        int a, didit, dupflag;
        
@@ -3928,155 +4155,164 @@ void adduplicate(int noTrans)
                if TESTBASELIB(base) {
                
                        ob= base->object;
-                       obn= copy_object(ob);
-                       obn->recalc |= OB_RECALC_OB;
-                       
-                       basen= MEM_mallocN(sizeof(Base), "duplibase");
-                       *basen= *base;
-                       BLI_addhead(&G.scene->base, basen);     /* addhead: prevent eternal loop */
-                       basen->object= obn;
-                       base->flag &= ~SELECT;
-                       basen->flag &= ~OB_FROMGROUP;
-                       
-                       if(BASACT==base) BASACT= basen;
+                       if(ob->flag & OB_POSEMODE) {
+                               ; // nothing?
+                       }
+                       else {
+                               obn= copy_object(ob);
+                               obn->recalc |= OB_RECALC;
+                               
+                               basen= MEM_mallocN(sizeof(Base), "duplibase");
+                               *basen= *base;
+                               BLI_addhead(&G.scene->base, basen);     /* addhead: prevent eternal loop */
+                               basen->object= obn;
+                               base->flag &= ~SELECT;
+                               basen->flag &= ~OB_FROMGROUP;
+                               
+                               if(BASACT==base) BASACT= basen;
 
-                       /* duplicates using userflags */
-                       
-                       if(dupflag & USER_DUP_IPO) {
-                               id= (ID *)obn->ipo;
-                               if(id) {
-                                       ID_NEW_US( obn->ipo)
-                                               else obn->ipo= copy_ipo(obn->ipo);
-                                       id->us--;
-                               }
-                               /* Handle constraint ipos */
-                               for (chan=obn->constraintChannels.first; chan; chan=chan->next){
-                                       id= (ID *)chan->ipo;
+                               /* duplicates using userflags */
+                               
+                               if(dupflag & USER_DUP_IPO) {
+                                       id= (ID *)obn->ipo;
                                        if(id) {
-                                               ID_NEW_US( chan->ipo)
-                                                       else chan->ipo= copy_ipo(chan->ipo);
+                                               ID_NEW_US( obn->ipo)
+                                               else obn->ipo= copy_ipo(obn->ipo);
                                                id->us--;
                                        }
-                               }
-                       }
-                       if(dupflag & USER_DUP_ACT){
-                               id= (ID *)obn->action;
-                               if (id){
-                                       ID_NEW_US(obn->action)
-                                               else{
-                                               obn->action= copy_action(obn->action);
-                                               obn->activecon=NULL;
+                                       /* Handle constraint ipos */
+                                       for (chan=obn->constraintChannels.first; chan; chan=chan->next){
+                                               id= (ID *)chan->ipo;
+                                               if(id) {
+                                                       ID_NEW_US( chan->ipo)
+                                                       else chan->ipo= copy_ipo(chan->ipo);
+                                                       id->us--;
+                                               }
                                        }
-                                       id->us--;
                                }
-                       }
-                       if(dupflag & USER_DUP_MAT) {
-                               for(a=0; a<obn->totcol; a++) {
-                                       id= (ID *)obn->mat[a];
-                                       if(id) {
-                                               ID_NEW_US(obn->mat[a])
-                                               else obn->mat[a]= copy_material(obn->mat[a]);
+                               if(dupflag & USER_DUP_ACT){
+                                       id= (ID *)obn->action;
+                                       if (id){
+                                               ID_NEW_US(obn->action)
+                                               else{
+                                                       obn->action= copy_action(obn->action);
+                                               }
                                                id->us--;
                                        }
                                }
-                       }
-                       
-                       id= obn->data;
-                       didit= 0;
-                       
-                       switch(obn->type) {
-                       case OB_MESH:
-                               if(dupflag & USER_DUP_MESH) {
-                                       ID_NEW_US2( obn->data )
-                                       else {
-                                               obn->data= copy_mesh(obn->data);
-                                               didit= 1;
+                               if(dupflag & USER_DUP_MAT) {
+                                       for(a=0; a<obn->totcol; a++) {
+                                               id= (ID *)obn->mat[a];
+                                               if(id) {
+                                                       ID_NEW_US(obn->mat[a])
+                                                       else obn->mat[a]= copy_material(obn->mat[a]);
+                                                       id->us--;
+                                               }
                                        }
-                                       id->us--;
                                }
-                               break;
-                       case OB_CURVE:
-                               if(dupflag & USER_DUP_CURVE) {
-                                       ID_NEW_US2(obn->data )
-                                       else {
-                                               obn->data= copy_curve(obn->data);
-                                               didit= 1;
+                               
+                               id= obn->data;
+                               didit= 0;
+                               
+                               switch(obn->type) {
+                               case OB_MESH:
+                                       if(dupflag & USER_DUP_MESH) {
+                                               ID_NEW_US2( obn->data )
+                                               else {
+                                                       obn->data= copy_mesh(obn->data);
+                                                       didit= 1;
+                                               }
+                                               id->us--;
                                        }
-                                       id->us--;
-                               }
-                               break;
-                       case OB_SURF:
-                               if(dupflag & USER_DUP_SURF) {
-                                       ID_NEW_US2( obn->data )
-                                       else {
-                                               obn->data= copy_curve(obn->data);
-                                               didit= 1;
+                                       break;
+                               case OB_CURVE:
+                                       if(dupflag & USER_DUP_CURVE) {
+                                               ID_NEW_US2(obn->data )
+                                               else {
+                                                       obn->data= copy_curve(obn->data);
+                                                       didit= 1;
+                                               }
+                                               id->us--;
                                        }
-                                       id->us--;
-                               }
-                               break;
-                       case OB_FONT:
-                               if(dupflag & USER_DUP_FONT) {
-                                       ID_NEW_US2( obn->data )
-                                       else {
-                                               obn->data= copy_curve(obn->data);
-                                               didit= 1;
+                                       break;
+                               case OB_SURF:
+                                       if(dupflag & USER_DUP_SURF) {
+                                               ID_NEW_US2( obn->data )
+                                               else {
+                                                       obn->data= copy_curve(obn->data);
+                                                       didit= 1;
+                                               }
+                                               id->us--;
                                        }
-                                       id->us--;
-                               }
-                               break;
-                       case OB_MBALL:
-                               if(dupflag & USER_DUP_MBALL) {
-                                       ID_NEW_US2(obn->data )
-                                       else {
-                                               obn->data= copy_mball(obn->data);
-                                               didit= 1;
+                                       break;
+                               case OB_FONT:
+                                       if(dupflag & USER_DUP_FONT) {
+                                               ID_NEW_US2( obn->data )
+                                               else {
+                                                       obn->data= copy_curve(obn->data);
+                                                       didit= 1;
+                                               }
+                                               id->us--;
                                        }
-                                       id->us--;
-                               }
-                               break;
-                       case OB_LAMP:
-                               if(dupflag & USER_DUP_LAMP) {
+                                       break;
+                               case OB_MBALL:
+                                       if(dupflag & USER_DUP_MBALL) {
+                                               ID_NEW_US2(obn->data )
+                                               else {
+                                                       obn->data= copy_mball(obn->data);
+                                                       didit= 1;
+                                               }
+                                               id->us--;
+                                       }
+                                       break;
+                               case OB_LAMP:
+                                       if(dupflag & USER_DUP_LAMP) {
+                                               ID_NEW_US2(obn->data )
+                                               else obn->data= copy_lamp(obn->data);
+                                               id->us--;
+                                       }
+                                       break;
+
+                               case OB_ARMATURE:
+                                       obn->recalc |= OB_RECALC_DATA;
+                                       if(obn->pose) obn->pose->flag |= POSE_RECALC;
+                                       
+                                       if(dupflag & USER_DUP_ARM) {
+                                               ID_NEW_US2(obn->data )
+                                               else {
+                                                       obn->data= copy_armature(obn->data);
+                                                       armature_rebuild_pose(obn, obn->data);
+                                                       didit= 1;
+                                               }
+                                               id->us--;
+                                       }
+                                       
+                                       break;
+                                       
+                               /* always dupli's */
+                               case OB_LATTICE:
                                        ID_NEW_US2(obn->data )
-                                       else obn->data= copy_lamp(obn->data);
+                                       else obn->data= copy_lattice(obn->data);
                                        id->us--;
-                               }
-                               break;
-
-                       case OB_ARMATURE:
-                               if(dupflag & USER_DUP_ARM) {
+                                       break;
+                               case OB_CAMERA:
                                        ID_NEW_US2(obn->data )
-                                       else {
-                                               obn->data= copy_armature(obn->data);
-                                               didit= 1;
-                                       }
+                                       else obn->data= copy_camera(obn->data);
                                        id->us--;
+                                       break;
                                }
-                               break;
-                       /* always dupli's */
-               
-                       case OB_LATTICE:
-                               ID_NEW_US2(obn->data )
-                               else obn->data= copy_lattice(obn->data);
-                               id->us--;
-                               break;
-                       case OB_CAMERA:
-                               ID_NEW_US2(obn->data )
-                               else obn->data= copy_camera(obn->data);
-                               id->us--;
-                               break;
-                       }
-                       
-                       if(dupflag & USER_DUP_MAT) {
-                               matarar= give_matarar(obn);
-                               if(didit && matarar) {
-                                       for(a=0; a<obn->totcol; a++) {
-                                               id= (ID *)(*matarar)[a];
-                                               if(id) {
-                                                       ID_NEW_US( (*matarar)[a] )
-                                                       else (*matarar)[a]= copy_material((*matarar)[a]);
-                                                       
-                                                       id->us--;
+                               
+                               if(dupflag & USER_DUP_MAT) {
+                                       matarar= give_matarar(obn);
+                                       if(didit && matarar) {
+                                               for(a=0; a<obn->totcol; a++) {
+                                                       id= (ID *)(*matarar)[a];
+                                                       if(id) {
+                                                               ID_NEW_US( (*matarar)[a] )
+                                                               else (*matarar)[a]= copy_material((*matarar)[a]);
+                                                               
+                                                               id->us--;
+                                                       }
                                                }
                                        }
                                }
@@ -4090,7 +4326,6 @@ void adduplicate(int noTrans)
        base= FIRSTBASE;
        while(base) {
                if TESTBASELIB(base) {
-                       
                        relink_constraints(&base->object->constraints);
                        if (base->object->pose){
                                bPoseChannel *chan;
@@ -4098,20 +4333,28 @@ void adduplicate(int noTrans)
                                        relink_constraints(&chan->constraints);
                                }
                        }
-                       if(base->object->hooks.first) {
-                               ObHook *hook= base->object->hooks.first;
-                               while(hook) {
-                                       ID_NEW(hook->parent);
-                                       hook= hook->next;
-                               }
-                       }
+                       modifiers_foreachObjectLink(base->object, adduplicate__forwardModifierLinks, NULL);
                        ID_NEW(base->object->parent);
                        ID_NEW(base->object->track);
                        
                }
                base= base->next;
        }
-
+       
+       /* ipos */
+       ipo= G.main->ipo.first;
+       while(ipo) {
+               if(ipo->id.lib==NULL && ipo->id.newid) {
+                       IpoCurve *icu;
+                       for(icu= ipo->curve.first; icu; icu= icu->next) {
+                               if(icu->driver) {
+                                       ID_NEW(icu->driver->ob);
+                               }
+                       }
+               }
+               ipo= ipo->id.next;
+       }
+       
        /* materials */
        if( dupflag & USER_DUP_MAT) {
                mao= G.main->mat.first;
@@ -4144,7 +4387,7 @@ void adduplicate(int noTrans)
        }
 
        DAG_scene_sort(G.scene);
-       DAG_scene_flush_update(G.scene);
+       DAG_scene_flush_update(G.scene, screen_view3d_layers());
        set_sca_new_poins();
 
        clear_id_newpoins();
@@ -4249,6 +4492,7 @@ void selectlinks(int nr)
                }
                base= base->next;
        }
+       
        allqueue(REDRAWVIEW3D, 0);
        allqueue(REDRAWDATASELECT, 0);
        allqueue(REDRAWOOPS, 0);
@@ -4262,8 +4506,6 @@ void image_aspect(void)
        Object *ob;
        Material *ma;
        Tex *tex;
-       Mesh *me;
-       Curve *cu;
        float x, y, space;
        int a, b, done;
        
@@ -4283,14 +4525,16 @@ void image_aspect(void)
                                                if(ma->mtex[b] && ma->mtex[b]->tex) {
                                                        tex= ma->mtex[b]->tex;
                                                        if(tex->type==TEX_IMAGE && tex->ima && tex->ima->ibuf) {
+
                                                                /* texturespace */
                                                                space= 1.0;
                                                                if(ob->type==OB_MESH) {
-                                                                       me= ob->data;
-                                                                       space= me->size[0]/me->size[1];
+                                                                       float size[3];
+                                                                       mesh_get_texspace(ob->data, NULL, NULL, size);
+                                                                       space= size[0]/size[1];
                                                                }
                                                                else if ELEM3(ob->type, OB_CURVE, OB_FONT, OB_SURF) {
-                                                                       cu= ob->data;
+                                                                       Curve *cu= ob->data;
                                                                        space= cu->size[0]/cu->size[1];
                                                                }
                                                        
@@ -4301,6 +4545,7 @@ void image_aspect(void)
                                                                else ob->size[1]= ob->size[0]*y/x;
                                                                
                                                                done= 1;
+                                                               DAG_object_flush_update(G.scene, ob, OB_RECALC_OB);                                                             
                                                        }
                                                }
                                                if(done) break;