2.5
[blender-staging.git] / source / blender / editors / object / object_edit.c
index 4e32c6ace8119bf52703d7f2b741b52115f727f0..c6cbbf90b79a5abc904f9049c379df65c853a764 100644 (file)
@@ -98,7 +98,6 @@
 #include "BKE_material.h"
 #include "BKE_mball.h"
 #include "BKE_mesh.h"
-#include "BKE_multires.h"
 #include "BKE_nla.h"
 #include "BKE_object.h"
 #include "BKE_particle.h"
 #include "BKE_modifier.h"
 
 #include "ED_anim_api.h"
+#include "ED_armature.h"
+#include "ED_mesh.h"
+#include "ED_object.h"
 #include "ED_screen.h"
 #include "ED_types.h"
 #include "ED_util.h"
 #include "RNA_access.h"
 #include "RNA_define.h"
 
+/* for menu/popup icons etc etc*/
+#include "UI_interface.h"
+#include "UI_resources.h"
+
 #include "WM_api.h"
 #include "WM_types.h"
 
 #include "object_intern.h"     // own include
 
 /* ************* XXX **************** */
-#define EM_WAITCURSOR 0
 static void allqueue() {}
 static void BIF_undo_push() {}
 static void error() {}
@@ -175,8 +180,8 @@ void ED_base_object_activate(bContext *C, Base *base)
        Base *tbase;
        
        /* activating a non-mesh, should end a couple of modes... */
-       //      if(base && base->object->type!=OB_MESH)
-       // XXX          exit_paint_modes();
+       if(base && base->object->type!=OB_MESH)
+               ED_view3d_exit_paint_modes(C);
        
        /* sets scene->basact */
        BASACT= base;
@@ -194,7 +199,7 @@ void ED_base_object_activate(bContext *C, Base *base)
                                DAG_object_flush_update(scene, tbase->object, OB_RECALC_DATA);
                        }
                }
-               WM_event_add_notifier(C, NC_SCENE|ND_OB_ACTIVE, base->object);
+               WM_event_add_notifier(C, NC_SCENE|ND_OB_ACTIVE, scene);
        }
        else
                WM_event_add_notifier(C, NC_SCENE|ND_OB_ACTIVE, NULL);
@@ -230,35 +235,54 @@ int object_data_is_libdata(Object *ob)
 
 
 
-void exit_paint_modes(void)
+/* exported */
+void ED_object_base_init_from_view(Scene *scene, View3D *v3d, Base *base)
 {
-#if 0
-       if(G.f & G_VERTEXPAINT) set_vpaint();
-       if(G.f & G_TEXTUREPAINT) set_texturepaint();
-       if(G.f & G_WEIGHTPAINT) set_wpaint();
-       if(G.f & G_SCULPTMODE) set_sculptmode();
-       if(G.f & G_PARTICLEEDIT) PE_set_particle_edit();
-
-       G.f &= ~(G_VERTEXPAINT+G_TEXTUREPAINT+G_WEIGHTPAINT+G_SCULPTMODE+G_PARTICLEEDIT);
-#endif
+       Object *ob= base->object;
+       
+       if (scene==NULL)
+               return;
+       
+       if (v3d==NULL) {
+               base->lay = scene->lay;
+               VECCOPY(ob->loc, scene->cursor);
+       } 
+       else {
+               if (v3d->localview) {
+                       base->lay= ob->lay= v3d->layact | v3d->lay;
+                       VECCOPY(ob->loc, v3d->cursor);
+               } 
+               else {
+                       base->lay= ob->lay= v3d->layact;
+                       VECCOPY(ob->loc, scene->cursor);
+               }
+               
+               if (U.flag & USER_ADD_VIEWALIGNED) {
+                       v3d->viewquat[0]= -v3d->viewquat[0];
+                       
+                       QuatToEul(v3d->viewquat, ob->rot);
+                       v3d->viewquat[0]= -v3d->viewquat[0];
+               }
+       }
 }
 
+
 void add_object_draw(Scene *scene, View3D *v3d, int type)      /* for toolbox or menus, only non-editmode stuff */
 {
        Object *ob;
        
-       exit_paint_modes();
+//     ED_view3d_exit_paint_modes(C);
 
-// XXX if (G.obedit) exit_editmode(EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); /* freedata, and undo */
-       ob= add_object(type);
+// XXX if (obedit) ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); /* freedata, and undo */
+       ob= add_object(scene, type);
 //     ED_base_object_activate(C, BASACT);
-       base_init_from_view3d(BASACT, v3d);
+       ED_object_base_init_from_view(scene, v3d, BASACT);
        
        /* only undo pushes on objects without editmode... */
        if(type==OB_EMPTY) BIF_undo_push("Add Empty");
        else if(type==OB_LAMP) {
                BIF_undo_push("Add Lamp");
-               reshadeall_displist();  /* only frees */
+               reshadeall_displist(scene);     /* only frees */
        }
        else if(type==OB_LATTICE) BIF_undo_push("Add Lattice");
        else if(type==OB_CAMERA) BIF_undo_push("Add Camera");
@@ -280,9 +304,9 @@ void add_objectLamp(Scene *scene, View3D *v3d, short type)
 {
        Lamp *la;
 
-       if(G.obedit==0) {
+       if(scene->obedit==NULL) { // XXX get from context
                add_object_draw(scene, v3d, OB_LAMP);
-               base_init_from_view3d(BASACT, v3d);
+               ED_object_base_init_from_view(scene, v3d, BASACT);
        }
        
        la = BASACT->object->data;
@@ -293,27 +317,20 @@ void add_objectLamp(Scene *scene, View3D *v3d, short type)
 
 /* remove base from a specific scene */
 /* note: now unlinks constraints as well */
-void free_and_unlink_base_from_scene(Scene *scene, Base *base)
+void ED_base_object_free_and_unlink(Scene *scene, Base *base)
 {
        BLI_remlink(&scene->base, base);
        free_libblock_us(&G.main->object, base->object);
+       if(scene->basact==base) scene->basact= NULL;
        MEM_freeN(base);
 }
 
-/* remove base from the current scene */
-void free_and_unlink_base(Scene *scene, Base *base)
-{
-       if (base==BASACT)
-               BASACT= NULL;
-       free_and_unlink_base_from_scene(scene, base);
-}
-
 void delete_obj(Scene *scene, View3D *v3d, int ok)
 {
        Base *base, *nbase;
        int islamp= 0;
        
-       if(G.obedit) return;
+       if(scene->obedit) return; // XXX get from context
        if(scene->id.lib) return;
 
        for(base= FIRSTBASE; base; base= nbase) {
@@ -332,7 +349,7 @@ void delete_obj(Scene *scene, View3D *v3d, int ok)
                                }
                        }
                        
-                       exit_paint_modes();
+//                     ED_view3d_exit_paint_modes(C);
 
                        if(base->object->type==OB_LAMP) islamp= 1;
 
@@ -344,19 +361,18 @@ void delete_obj(Scene *scene, View3D *v3d, int ok)
                                        if (scene != scene && !(scene->id.lib)) {
                                                base_other= object_in_scene( base->object, scene );
                                                if (base_other) {
-                                                       if (base_other == scene->basact) scene->basact= NULL;   /* in case the object was active */
-                                                       free_and_unlink_base_from_scene( scene, base_other );
+                                                       ED_base_object_free_and_unlink( scene, base_other );
                                                }
                                        }
                                }
                        }
                        
                        /* remove from current scene only */
-                       free_and_unlink_base(scene, base);
+                       ED_base_object_free_and_unlink(scene, base);
                }
        }
 
-       if(islamp) reshadeall_displist();       /* only frees displist */
+       if(islamp) reshadeall_displist(scene);  /* only frees displist */
 
 // XXX redraw_test_buttons(OBACT);
        allqueue(REDRAWVIEW3D, 0);
@@ -374,9 +390,8 @@ void delete_obj(Scene *scene, View3D *v3d, int ok)
        BIF_undo_push("Delete object(s)");
 }
 
-static int return_editmesh_indexar(int *tot, int **indexar, float *cent)
+static int return_editmesh_indexar(EditMesh *em, int *tot, int **indexar, float *cent)
 {
-       EditMesh *em = G.editMesh;
        EditVert *eve;
        int *index, nr, totvert=0;
        
@@ -403,16 +418,15 @@ static int return_editmesh_indexar(int *tot, int **indexar, float *cent)
        return totvert;
 }
 
-static int return_editmesh_vgroup(char *name, float *cent)
+static int return_editmesh_vgroup(Object *obedit, EditMesh *em, char *name, float *cent)
 {
-       EditMesh *em = G.editMesh;
        MDeformVert *dvert;
        EditVert *eve;
        int i, totvert=0;
        
        cent[0]= cent[1]= cent[2]= 0.0;
        
-       if(G.obedit->actdef) {
+       if(obedit->actdef) {
                
                /* find the vertices */
                for(eve= em->verts.first; eve; eve= eve->next) {
@@ -420,7 +434,7 @@ static int return_editmesh_vgroup(char *name, float *cent)
 
                        if(dvert) {
                                for(i=0; i<dvert->totweight; i++){
-                                       if(dvert->dw[i].def_nr == (G.obedit->actdef-1)) {
+                                       if(dvert->dw[i].def_nr == (obedit->actdef-1)) {
                                                totvert++;
                                                VecAddf(cent, cent, eve->co);
                                        }
@@ -428,7 +442,7 @@ static int return_editmesh_vgroup(char *name, float *cent)
                        }
                }
                if(totvert) {
-                       bDeformGroup *defGroup = BLI_findlink(&G.obedit->defbase, G.obedit->actdef-1);
+                       bDeformGroup *defGroup = BLI_findlink(&obedit->defbase, obedit->actdef-1);
                        strcpy(name, defGroup->name);
                        VecMulf(cent, 1.0f/(float)totvert);
                        return 1;
@@ -438,9 +452,10 @@ static int return_editmesh_vgroup(char *name, float *cent)
        return 0;
 }      
 
-static void select_editmesh_hook(HookModifierData *hmd)
+static void select_editmesh_hook(Object *ob, HookModifierData *hmd)
 {
-       EditMesh *em = G.editMesh;
+       Mesh *me= ob->data;
+       EditMesh *em= me->edit_mesh;
        EditVert *eve;
        int index=0, nr=0;
        
@@ -588,7 +603,7 @@ static int return_editcurve_indexar(int *tot, int **indexar, float *cent)
        return totvert;
 }
 
-static void apply_obmat(Object *ob)
+void ED_object_apply_obmat(Object *ob)
 {
        float mat[3][3], imat[3][3], tmat[3][3];
        
@@ -612,17 +627,20 @@ static void apply_obmat(Object *ob)
        
 }
 
-int hook_getIndexArray(int *tot, int **indexar, char *name, float *cent_r)
+int hook_getIndexArray(Object *obedit, int *tot, int **indexar, char *name, float *cent_r)
 {
        *indexar= NULL;
        *tot= 0;
        name[0]= 0;
        
-       switch(G.obedit->type) {
+       switch(obedit->type) {
                case OB_MESH:
+               {
+                       Mesh *me= obedit->data;
                        /* check selected vertices first */
-                       if( return_editmesh_indexar(tot, indexar, cent_r)) return 1;
-                       else return return_editmesh_vgroup(name, cent_r);
+                       if( return_editmesh_indexar(me->edit_mesh, tot, indexar, cent_r)) return 1;
+                       else return return_editmesh_vgroup(obedit, me->edit_mesh, name, cent_r);
+               }
                case OB_CURVE:
                case OB_SURF:
                        return return_editcurve_indexar(tot, indexar, cent_r);
@@ -680,12 +698,13 @@ static void select_editcurve_hook(HookModifierData *hmd)
        }
 }
 
-void hook_select(HookModifierData *hmd) 
+void obedit_hook_select(Object *ob, 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);
+       
+       if(ob->type==OB_MESH) select_editmesh_hook(ob, hmd);
+       else if(ob->type==OB_LATTICE) select_editlattice_hook(hmd);
+       else if(ob->type==OB_CURVE) select_editcurve_hook(hmd);
+       else if(ob->type==OB_SURF) select_editcurve_hook(hmd);
 }
 
 
@@ -694,8 +713,9 @@ void add_hook(Scene *scene, View3D *v3d, int mode)
        ModifierData *md = NULL;
        HookModifierData *hmd = NULL;
        Object *ob=NULL;
+       Object *obedit= scene->obedit;  // XXX get from context
        
-       if(G.obedit==NULL) return;
+       if(obedit==NULL) return;
        
        /* preconditions */
        if(mode==2) { /* selected object */
@@ -718,7 +738,7 @@ void add_hook(Scene *scene, View3D *v3d, int mode)
                char *cp;
                
                /* make pupmenu with hooks */
-               for(md=G.obedit->modifiers.first; md; md= md->next) {
+               for(md=obedit->modifiers.first; md; md= md->next) {
                        if (md->type==eModifierType_Hook) 
                                maxlen+=32;
                }
@@ -734,7 +754,7 @@ void add_hook(Scene *scene, View3D *v3d, int mode)
                else if(mode==5) strcpy(cp, "Select %t|");
                else if(mode==6) strcpy(cp, "Clear Offset %t|");
                
-               for(md=G.obedit->modifiers.first; md; md= md->next) {
+               for(md=obedit->modifiers.first; md; md= md->next) {
                        if (md->type==eModifierType_Hook) {
                                strcat(cp, md->name);
                                strcat(cp, " |");
@@ -747,7 +767,7 @@ void add_hook(Scene *scene, View3D *v3d, int mode)
                if(nr<1) return;
                
                a= 1;
-               for(md=G.obedit->modifiers.first; md; md=md->next) {
+               for(md=obedit->modifiers.first; md; md=md->next) {
                        if (md->type==eModifierType_Hook) {
                                if(a==nr) break;
                                a++;
@@ -764,7 +784,7 @@ void add_hook(Scene *scene, View3D *v3d, int mode)
                int tot, ok, *indexar;
                char name[32];
                
-               ok = hook_getIndexArray(&tot, &indexar, name, cent);
+               ok = hook_getIndexArray(obedit, &tot, &indexar, name, cent);
                
                if(ok==0) {
                        error("Requires selected vertices or active Vertex Group");
@@ -774,14 +794,14 @@ void add_hook(Scene *scene, View3D *v3d, int mode)
                        if(mode==1) {
                                Base *base= BASACT, *newbase;
                                
-                               ob= add_object(OB_EMPTY);
+                               ob= add_object(scene, 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);
+                               VecMat4MulVecfl(ob->loc, obedit->obmat, cent);
                                
                                /* restore, add_object sets active */
                                BASACT= base;
@@ -790,14 +810,14 @@ void add_hook(Scene *scene, View3D *v3d, int mode)
                        
                        /* new hook */
                        if(mode==1 || mode==2) {
-                               ModifierData *md = G.obedit->modifiers.first;
+                               ModifierData *md = 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);
+                               BLI_insertlinkbefore(&obedit->modifiers, md, hmd);
                                sprintf(hmd->modifier.name, "Hook-%s", ob->id.name+2);
                        }
                        else if (hmd->indexar) MEM_freeN(hmd->indexar); /* reassign, hook was set */
@@ -813,28 +833,28 @@ void add_hook(Scene *scene, View3D *v3d, int mode)
                                /* vert x (obmat x hook->imat) x hook->obmat x ob->imat */
                                /*        (parentinv         )                          */
                                
-                               where_is_object(ob);
+                               where_is_object(scene, ob);
                                
                                Mat4Invert(ob->imat, ob->obmat);
                                /* apparently this call goes from right to left... */
-                               Mat4MulSerie(hmd->parentinv, ob->imat, G.obedit->obmat, NULL, 
+                               Mat4MulSerie(hmd->parentinv, ob->imat, obedit->obmat, NULL, 
                                                         NULL, NULL, NULL, NULL, NULL);
                        }
                }
        }
        else if(mode==3) { /* remove */
-               BLI_remlink(&G.obedit->modifiers, md);
+               BLI_remlink(&obedit->modifiers, md);
                modifier_free(md);
        }
        else if(mode==5) { /* select */
-               hook_select(hmd);
+               obedit_hook_select(obedit, hmd);
        }
        else if(mode==6) { /* clear offset */
-               where_is_object(ob);    /* ob is hook->parent */
+               where_is_object(scene, ob);     /* ob is hook->parent */
 
                Mat4Invert(ob->imat, ob->obmat);
                /* this call goes from right to left... */
-               Mat4MulSerie(hmd->parentinv, ob->imat, G.obedit->obmat, NULL, 
+               Mat4MulSerie(hmd->parentinv, ob->imat, obedit->obmat, NULL, 
                                         NULL, NULL, NULL, NULL, NULL);
        }
 
@@ -844,7 +864,7 @@ void add_hook(Scene *scene, View3D *v3d, int mode)
 
 /* use this when the loc/size/rot of the parent has changed but the children should stay in the same place
  * apply-size-rot or object center for eg */
-static void ignore_parent_tx( Object *ob ) 
+static void ignore_parent_tx(Scene *scene, Object *ob ) 
 {
        Object workob;
        Object *ob_child;
@@ -852,8 +872,8 @@ static void ignore_parent_tx( Object *ob )
        /* a change was made, adjust the children to compensate */
        for (ob_child=G.main->object.first; ob_child; ob_child=ob_child->id.next) {
                if (ob_child->parent == ob) {
-                       apply_obmat(ob_child);
-                       what_does_parent(ob_child, &workob);
+                       ED_object_apply_obmat(ob_child);
+                       what_does_parent(scene, ob_child, &workob);
                        Mat4Invert(ob_child->parentinv, workob.obmat);
                }
        }
@@ -862,11 +882,12 @@ static void ignore_parent_tx( Object *ob )
 
 void add_hook_menu(Scene *scene, View3D *v3d)
 {
+       Object *obedit= scene->obedit;  // XXX get from context
        int mode;
        
-       if(G.obedit==NULL) return;
+       if(obedit==NULL) return;
        
-       if(modifiers_findByType(G.obedit, eModifierType_Hook))
+       if(modifiers_findByType(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");
@@ -882,15 +903,15 @@ void add_hook_menu(Scene *scene, View3D *v3d)
        BIF_undo_push("Add hook");
 }
 
-void make_track(Scene *scene, View3D *v3d)
+void make_track(Scene *scene, View3D *v3d, short mode)
 {
        Base *base;
-       short mode=0;
+       /*short mode=0;*/
        
        if(scene->id.lib) return;
-       if(G.obedit) {
-               return;
-       }
+// XXX if(obedit) {
+//             return; 
+//     }
        if(BASACT==0) return;
 
        mode= pupmenu("Make Track %t|TrackTo Constraint %x1|LockTrack Constraint %x2|Old Track %x3");
@@ -989,7 +1010,7 @@ static int clear_parent_exec(bContext *C, wmOperator *op)
                if(RNA_enum_is_equal(op->ptr, "type", "CLEAR_KEEP_TRANSFORM")) {
                        ob->parent= NULL;
                        ob->track= NULL;
-                       apply_obmat(ob);
+                       ED_object_apply_obmat(ob);
                }
                if(RNA_enum_is_equal(op->ptr, "type", "CLEAR_INVERSE")) {
                        Mat4One(ob->parentinv);
@@ -1001,7 +1022,7 @@ static int clear_parent_exec(bContext *C, wmOperator *op)
        DAG_scene_sort(CTX_data_scene(C));
        ED_anim_dag_flush_update(C);
        
-       BIF_undo_push("Clear Parent");  
+       ED_undo_push(C,"Clear Parent"); 
        
        return OPERATOR_FINISHED;
 }
@@ -1018,181 +1039,670 @@ void OBJECT_OT_clear_parent(wmOperatorType *ot)
        ot->invoke= WM_menu_invoke;
        ot->exec= clear_parent_exec;
        
-       ot->poll= ED_operator_areaactive;       // XXX solve
+       ot->poll= ED_operator_object_active;
        ot->flag= OPTYPE_REGISTER;
        
        prop = RNA_def_property(ot->srna, "type", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_items(prop, prop_clear_parent_types);
 }
 
+/* ******************** clear track operator ******************* */
+
+
+static EnumPropertyItem prop_clear_track_types[] = {
+       {0, "CLEAR", "Clear Track", ""},
+       {1, "CLEAR_KEEP_TRANSFORM", "Clear and Keep Transformation (Clear Track)", ""},
+       {0, NULL, NULL, NULL}
+};
+
+/* note, poll should check for editable scene */
+static int object_clear_track_exec(bContext *C, wmOperator *op)
+{
+       if(CTX_data_edit_object(C)) return OPERATOR_CANCELLED;
+
+       CTX_DATA_BEGIN(C, Object*, ob, selected_objects) {
+               /*if(TESTBASELIB(v3d, base)) {*/
+                       ob->track= NULL;
+                       ob->recalc |= OB_RECALC;
+                       
+                       if(RNA_enum_is_equal(op->ptr, "type", "CLEAR_KEEP_TRANSFORM")) {
+                               ED_object_apply_obmat(ob);
+                       }                       
+               /*}*/
+       }
+       CTX_DATA_END;
+
+       DAG_scene_sort(CTX_data_scene(C));
+       ED_anim_dag_flush_update(C);
+
+       ED_undo_push(C,"Clear Track");  
+       
+       return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_clear_track(wmOperatorType *ot)
+{
+       PropertyRNA *prop;
+       
+       /* identifiers */
+       ot->name= "Clear track";
+       ot->idname= "OBJECT_OT_clear_track";
+       
+       /* api callbacks */
+       ot->invoke= WM_menu_invoke;
+       ot->exec= object_clear_track_exec;
+       
+       ot->poll= ED_operator_scene_editable;
+       ot->flag= OPTYPE_REGISTER;
+       
+       prop = RNA_def_property(ot->srna, "type", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_items(prop, prop_clear_track_types);
+}
+
+
 /* ***************************** */
+/* ****** Select by Type ****** */
+static EnumPropertyItem prop_select_object_types[] = {
+       {OB_EMPTY, "EMPTY", "Empty", ""},
+       {OB_MESH, "MESH", "Mesh", ""},
+       {OB_CURVE, "CURVE", "Curve", ""},
+       {OB_SURF, "SURFACE", "Surface", ""},
+       {OB_FONT, "TEXT", "Text", ""},
+       {OB_MBALL, "META", "Meta", ""},
+       {OB_LAMP, "LAMP", "Lamp", ""},
+       {OB_CAMERA, "CAMERA", "Camera", ""},
+       {OB_LATTICE, "LATTICE", "Lattice", ""},
+       {0, NULL, NULL, NULL}
+};
 
-void clear_track(Scene *scene, View3D *v3d)
+static int object_select_by_type_exec(bContext *C, wmOperator *op)
 {
-       Base *base;
-       int mode;
+       short obtype;
        
-       if(G.obedit) return;
-       if(scene->id.lib) return;
+       obtype = RNA_enum_get(op->ptr, "type");
+               
+       CTX_DATA_BEGIN(C, Base*, base, visible_bases) {
+               if(base->object->type==obtype) {
+                       ED_base_object_select(base, BA_SELECT);
+               }
+       }
+       CTX_DATA_END;
+       
+       /* undo? */
+       WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, CTX_data_scene(C));
+       
+       return OPERATOR_FINISHED;
+}
 
-       mode= pupmenu("OK? %t|Clear Track %x1| Clear Track and Keep Transform %x2");
+void OBJECT_OT_select_by_type(wmOperatorType *ot)
+{
+       PropertyRNA *prop;
+       
+       /* identifiers */
+       ot->name= "Select By Type";
+       ot->idname= "OBJECT_OT_select_by_type";
+       
+       /* api callbacks */
+       ot->invoke= WM_menu_invoke;
+       ot->exec= object_select_by_type_exec;
+       ot->poll= ED_operator_scene_editable;
+       
+       prop = RNA_def_property(ot->srna, "type", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_items(prop, prop_select_object_types);
 
-       if(mode<1) return;
+}
 
-       for(base= FIRSTBASE; base; base= base->next) {
-               if(TESTBASELIB(v3d, base)) {
-                       base->object->track= NULL;
-                       base->object->recalc |= OB_RECALC;
-                       
-                       if(mode==2) {
-                               apply_obmat(base->object);
-                       }                       
+/* ****** selection by layer *******/
+
+static int object_select_by_layer_exec(bContext *C, wmOperator *op)
+{
+       unsigned int layernum;
+       
+       layernum = RNA_int_get(op->ptr, "layer");
+               
+       CTX_DATA_BEGIN(C, Base*, base, visible_bases) {
+               if(base->lay == (1<< (layernum -1)))
+                       ED_base_object_select(base, BA_SELECT);
+       }
+       CTX_DATA_END;
+       
+       /* undo? */
+       WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, CTX_data_scene(C));
+       
+       return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_select_by_layer(wmOperatorType *ot)
+{
+       PropertyRNA *prop;
+       
+       /* identifiers */
+       ot->name= "Selection by layer";
+       ot->idname= "OBJECT_OT_select_by_layer";
+       
+       /* api callbacks */
+       /*ot->invoke = XXX - need a int grid popup*/
+       ot->exec= object_select_by_layer_exec;
+       ot->poll= ED_operator_scene_editable;
+       
+       prop = RNA_def_property(ot->srna, "layer", PROP_INT, PROP_UNSIGNED);
+       RNA_def_property_ui_range(prop, 1, 20,1, 1);
+       RNA_def_property_ui_text(prop, "layer", "The layer to select objects in");
+       RNA_def_property_int_default(prop, 2);
+
+}
+
+/* ****** invert selection *******/
+static int object_select_invert_exec(bContext *C, wmOperator *op)
+{
+       CTX_DATA_BEGIN(C, Base*, base, visible_bases) {
+               if (base->flag & SELECT)
+                       ED_base_object_select(base, BA_DESELECT);
+               else
+                       ED_base_object_select(base, BA_SELECT);
+       }
+       CTX_DATA_END;
+       
+       /* undo? */
+       WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, CTX_data_scene(C));
+       
+       return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_select_invert(wmOperatorType *ot)
+{
+       
+       /* identifiers */
+       ot->name= "Invert selection";
+       ot->idname= "OBJECT_OT_select_invert";
+       
+       /* api callbacks */
+       ot->exec= object_select_invert_exec;
+       ot->poll= ED_operator_scene_editable;
+
+}
+/* ****** (de)select All *******/
+
+static int object_de_select_all_exec(bContext *C, wmOperator *op)
+{
+       
+       int a=0, ok=0; 
+       
+       CTX_DATA_BEGIN(C, Base*, base, visible_bases) {
+               if (base->flag & SELECT) {
+                       ok= a= 1;
+                       break;
                }
+               else ok=1;
        }
+       CTX_DATA_END;
+       
+       if (!ok) return OPERATOR_PASS_THROUGH;
+       
+       CTX_DATA_BEGIN(C, Base*, base, visible_bases) {
+               if (a) ED_base_object_select(base, BA_DESELECT);
+               else ED_base_object_select(base, BA_SELECT);
+       }
+       CTX_DATA_END;
+       
+       /* undo? */
+       WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, CTX_data_scene(C));
+       
+       return OPERATOR_FINISHED;
+}
 
-       DAG_scene_sort(scene);
-       allqueue(REDRAWVIEW3D, 0);
-       allqueue(REDRAWOOPS, 0);
+void OBJECT_OT_de_select_all(wmOperatorType *ot)
+{
        
-       BIF_undo_push("Clear Track");   
+       /* identifiers */
+       ot->name= "deselect all";
+       ot->idname= "OBJECT_OT_de_select_all";
+       
+       /* api callbacks */
+       ot->exec= object_de_select_all_exec;
+       ot->poll= ED_operator_scene_editable;
+
 }
+/* ****** random selection *******/
 
-void clear_object(Scene *scene, View3D *v3d, char mode)
+static int object_select_random_exec(bContext *C, wmOperator *op)
+{      
+       int percent;
+       
+       percent = RNA_int_get(op->ptr, "percent");
+               
+       CTX_DATA_BEGIN(C, Base*, base, visible_bases) {
+               if ((!base->flag & SELECT && (BLI_frand() * 100) < percent)) {
+                               ED_base_object_select(base, BA_SELECT);
+               }
+       }
+       CTX_DATA_END;
+       
+       /* undo? */
+       WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, CTX_data_scene(C));
+       
+       return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_select_random(wmOperatorType *ot)
 {
-       Base *base;
-       Object *ob;
+       PropertyRNA *prop;
+       
+       /* identifiers */
+       ot->name= "Random selection";
+       ot->idname= "OBJECT_OT_select_random";
+       
+       /* api callbacks */
+       /*ot->invoke= object_select_random_invoke XXX - need a number popup ;*/
+       ot->exec = object_select_random_exec;
+       ot->poll= ED_operator_scene_editable;
+       
+       prop = RNA_def_property(ot->srna, "percent", PROP_INT, PROP_NONE);
+       RNA_def_property_ui_range(prop, 1, 100,1, 1);
+       RNA_def_property_ui_text(prop, "Percent", "Max persentage that will be selected");
+       RNA_def_property_int_default(prop, 50);
+}
+
+/* ******** Clear object Translation *********** */
+
+static int object_clear_location_exec(bContext *C, wmOperator *op)
+{
+       Scene *scene= CTX_data_scene(C);
+       int armature_clear= 0;
+
+       CTX_DATA_BEGIN(C, Object*, ob, selected_objects) {
+               if ((ob->flag & OB_POSEMODE)) {
+                       /* only clear pose transforms if:
+                        *      - with a mesh in weightpaint mode, it's related armature needs to be cleared
+                        *      - with clearing transform of object being edited at the time
+                        */
+                       if ((G.f & G_WEIGHTPAINT) || (ob==OBACT)) {
+// XXX                         clear_armature(ob, mode);
+                               armature_clear= 1;      /* silly system to prevent another dag update, so no action applied */
+                       }
+               }
+               else if((G.f & G_WEIGHTPAINT)==0) {
+                       if ((ob->protectflag & OB_LOCK_LOCX)==0)
+                               ob->loc[0]= ob->dloc[0]= 0.0f;
+                       if ((ob->protectflag & OB_LOCK_LOCY)==0)
+                               ob->loc[1]= ob->dloc[1]= 0.0f;
+                       if ((ob->protectflag & OB_LOCK_LOCZ)==0)
+                               ob->loc[2]= ob->dloc[2]= 0.0f;
+               }
+               ob->recalc |= OB_RECALC_OB;
+       }
+       CTX_DATA_END;
+
+       if(armature_clear==0) /* in this case flush was done */
+               ED_anim_dag_flush_update(C);    
+       ED_undo_push(C,"Clear Location");
+       
+       WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
+       
+       return OPERATOR_FINISHED;
+}
+
+
+void OBJECT_OT_clear_location(wmOperatorType *ot)
+{
+       
+       /* identifiers */
+       ot->name= "Clear Object Location";
+       ot->idname= "OBJECT_OT_clear_location";
+       
+       /* api callbacks */
+       ot->invoke= WM_operator_confirm;
+       ot->exec= object_clear_location_exec;
+       ot->poll= ED_operator_object_active;
+}
+
+static int object_clear_rotation_exec(bContext *C, wmOperator *op)
+{
+       Scene *scene= CTX_data_scene(C);
+       int armature_clear= 0;
+
+       CTX_DATA_BEGIN(C, Object*, ob, selected_objects) {
+               if ((ob->flag & OB_POSEMODE)) {
+                       /* only clear pose transforms if:
+                        *      - with a mesh in weightpaint mode, it's related armature needs to be cleared
+                        *      - with clearing transform of object being edited at the time
+                        */
+                       if ((G.f & G_WEIGHTPAINT) || (ob==OBACT)) {
+// XXX                         clear_armature(ob, mode);
+                               armature_clear= 1;      /* silly system to prevent another dag update, so no action applied */
+                       }
+               }
+               else if((G.f & G_WEIGHTPAINT)==0) {
+                       /* eulers can only get cleared if they are not protected */
+                       if ((ob->protectflag & OB_LOCK_ROTX)==0)
+                               ob->rot[0]= ob->drot[0]= 0.0f;
+                       if ((ob->protectflag & OB_LOCK_ROTY)==0)
+                               ob->rot[1]= ob->drot[1]= 0.0f;
+                       if ((ob->protectflag & OB_LOCK_ROTZ)==0)
+                               ob->rot[2]= ob->drot[2]= 0.0f;
+               }
+               ob->recalc |= OB_RECALC_OB;
+       }
+       CTX_DATA_END;
+
+       if(armature_clear==0) /* in this case flush was done */
+               ED_anim_dag_flush_update(C);    
+       ED_undo_push(C,"Clear Rotation");
+       
+       WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
+       
+       return OPERATOR_FINISHED;
+}
+
+
+void OBJECT_OT_clear_rotation(wmOperatorType *ot)
+{
+       
+       /* identifiers */
+       ot->name= "Clear Object Rotation";
+       ot->idname= "OBJECT_OT_clear_rotation";
+       
+       /* api callbacks */
+       ot->invoke= WM_operator_confirm;
+       ot->exec= object_clear_rotation_exec;
+       ot->poll= ED_operator_object_active;
+}
+
+static int object_clear_scale_exec(bContext *C, wmOperator *op)
+{
+       Scene *scene= CTX_data_scene(C);
+       int armature_clear= 0;
+
+       CTX_DATA_BEGIN(C, Object*, ob, selected_objects) {
+               if ((ob->flag & OB_POSEMODE)) {
+                       /* only clear pose transforms if:
+                        *      - with a mesh in weightpaint mode, it's related armature needs to be cleared
+                        *      - with clearing transform of object being edited at the time
+                        */
+                       if ((G.f & G_WEIGHTPAINT) || (ob==OBACT)) {
+// XXX                         clear_armature(ob, mode);
+                               armature_clear= 1;      /* silly system to prevent another dag update, so no action applied */
+                       }
+               }
+               else if((G.f & G_WEIGHTPAINT)==0) {
+                       if ((ob->protectflag & OB_LOCK_SCALEX)==0) {
+                               ob->dsize[0]= 0.0f;
+                               ob->size[0]= 1.0f;
+                       }
+                       if ((ob->protectflag & OB_LOCK_SCALEY)==0) {
+                               ob->dsize[1]= 0.0f;
+                               ob->size[1]= 1.0f;
+                       }
+                       if ((ob->protectflag & OB_LOCK_SCALEZ)==0) {
+                               ob->dsize[2]= 0.0f;
+                               ob->size[2]= 1.0f;
+                       }
+               }
+               ob->recalc |= OB_RECALC_OB;
+       }
+       CTX_DATA_END;
+       
+       if(armature_clear==0) /* in this case flush was done */
+               ED_anim_dag_flush_update(C);    
+       ED_undo_push(C,"Clear Scale");
+       
+       WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, CTX_data_scene(C));
+       
+       return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_clear_scale(wmOperatorType *ot)
+{
+       
+       /* identifiers */
+       ot->name= "Clear Object Scale";
+       ot->idname= "OBJECT_OT_clear_scale";
+       
+       /* api callbacks */
+       ot->invoke= WM_operator_confirm;
+       ot->exec= object_clear_scale_exec;
+       ot->poll= ED_operator_object_active;
+}
+
+static int object_clear_origin_exec(bContext *C, wmOperator *op)
+{
+       Scene *scene= CTX_data_scene(C);
        float *v1, *v3, mat[3][3];
        int armature_clear= 0;
-       char *str=NULL;
+
+       CTX_DATA_BEGIN(C, Object*, ob, selected_objects) {
+               if ((ob->flag & OB_POSEMODE)) {
+                       /* only clear pose transforms if:
+                        *      - with a mesh in weightpaint mode, it's related armature needs to be cleared
+                        *      - with clearing transform of object being edited at the time
+                        */
+                       if ((G.f & G_WEIGHTPAINT) || (ob==OBACT)) {
+// XXX                         clear_armature(ob, mode);
+                               armature_clear= 1;      /* silly system to prevent another dag update, so no action applied */
+                       }
+               }
+               else if((G.f & G_WEIGHTPAINT)==0) {
+                       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;
+       }
+       CTX_DATA_END;
+
+       if(armature_clear==0) /* in this case flush was done */
+               ED_anim_dag_flush_update(C);    
+       ED_undo_push(C,"Clear origin");
        
-       if(G.obedit) return;
-       if(scene->id.lib) return;
+       WM_event_add_notifier(C, NC_SCENE|ND_TRANSFORM, CTX_data_scene(C));
        
-       if(mode=='r') str= "Clear rotation";
-       else if(mode=='g') str= "Clear location";
-       else if(mode=='s') str= "Clear scale";
-       else if(mode=='o') str= "Clear origin";
-       else return;
+       return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_clear_origin(wmOperatorType *ot)
+{
+
+       /* identifiers */
+       ot->name= "Clear Object Origin";
+       ot->idname= "OBJECT_OT_clear_origin";
        
-       for(base= FIRSTBASE; base; base= base->next) {
-               if(TESTBASELIB(v3d, base)) {
-                       ob= base->object;
-                       
-                       if ((ob->flag & OB_POSEMODE)) {
-                               /* only clear pose transforms if:
-                                *      - with a mesh in weightpaint mode, it's related armature needs to be cleared
-                                *      - with clearing transform of object being edited at the time
-                                */
-                               if ((G.f & G_WEIGHTPAINT) || (ob==OBACT)) {
-// XXX                                 clear_armature(ob, mode);
-                                       armature_clear= 1;      /* silly system to prevent another dag update, so no action applied */
+       /* api callbacks */
+       ot->invoke= WM_operator_confirm;
+       ot->exec= object_clear_origin_exec;
+       ot->poll= ED_operator_object_active;
+}
+
+/* ********* clear/set restrict view *********/
+static int object_clear_restrictview_exec(bContext *C, wmOperator *op)
+{
+       ScrArea *sa= CTX_wm_area(C);
+       View3D *v3d= sa->spacedata.first;
+       Scene *scene= CTX_data_scene(C);
+       Base *base;
+       int changed = 0;
+       
+       /* XXX need a context loop to handle such cases */
+       for(base = FIRSTBASE; base; base=base->next){
+               if((base->lay & v3d->lay) && base->object->restrictflag & OB_RESTRICT_VIEW) {
+                       base->flag |= SELECT;
+                       base->object->flag = base->flag;
+                       base->object->restrictflag &= ~OB_RESTRICT_VIEW; 
+                       changed = 1;
+               }
+       }
+       if (changed) {
+               ED_undo_push(C,"Unhide Objects");
+               DAG_scene_sort(scene);
+               WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene);
+       }
+
+       return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_clear_restrictview(wmOperatorType *ot)
+{
+       
+       /* identifiers */
+       ot->name= "Clear restrict view";
+       ot->idname= "OBJECT_OT_clear_restrictview";
+       
+       /* api callbacks */
+       ot->invoke= WM_operator_confirm;
+       ot->exec= object_clear_restrictview_exec;
+       ot->poll= ED_operator_view3d_active;
+}
+
+static EnumPropertyItem prop_set_restrictview_types[] = {
+       {0, "SELECTED", "Selected", ""},
+       {1, "UNSELECTED", "Unselected ", ""},
+       {0, NULL, NULL, NULL}
+};
+
+static int object_set_restrictview_exec(bContext *C, wmOperator *op)
+{
+       Scene *scene= CTX_data_scene(C);
+       
+       short changed = 0, changed_act = 0;
+       
+       CTX_DATA_BEGIN(C, Base*, base, visible_bases) {
+               if(RNA_enum_is_equal(op->ptr, "type", "SELECTED")){
+                       if (base->flag & SELECT){
+                               base->flag &= ~SELECT;
+                               base->object->flag = base->flag;
+                               base->object->restrictflag |= OB_RESTRICT_VIEW;
+                               changed = 1;
+                               if (base==BASACT) {
+                                       BASACT= NULL;
+                                       changed_act = 1;
                                }
                        }
-                       else if((G.f & G_WEIGHTPAINT)==0) {
-                               /* only clear transforms of 'normal' (not armature) object if:
-                                *      - not in weightpaint mode or editmode
-                                *      - if that object's transform locks are not enabled (this is done on a per-channel basis)
-                                */
-                               if (mode=='r') {
-                                       /* eulers can only get cleared if they are not protected */
-                                       if ((ob->protectflag & OB_LOCK_ROTX)==0)
-                                               ob->rot[0]= ob->drot[0]= 0.0f;
-                                       if ((ob->protectflag & OB_LOCK_ROTY)==0)
-                                               ob->rot[1]= ob->drot[1]= 0.0f;
-                                       if ((ob->protectflag & OB_LOCK_ROTZ)==0)
-                                               ob->rot[2]= ob->drot[2]= 0.0f;
-                                       
-                                       /* quats here are not really used anymore anywhere, so it probably doesn't 
-                                        * matter to not clear them whether the euler-based rotation is used
-                                        */
-                                       /*QuatOne(ob->quat);
-                                       QuatOne(ob->dquat);*/
-                                       
+               }
+               else if (RNA_enum_is_equal(op->ptr, "type", "UNSELECTED")){
+                       if (!(base->flag & SELECT)){
+                               base->object->restrictflag |= OB_RESTRICT_VIEW;
+                               changed = 1;
+                       }
+               }       
+       }
+       CTX_DATA_END;
 
-                               }
-                               else if (mode=='g') {
-                                       if ((ob->protectflag & OB_LOCK_LOCX)==0)
-                                               ob->loc[0]= ob->dloc[0]= 0.0f;
-                                       if ((ob->protectflag & OB_LOCK_LOCY)==0)
-                                               ob->loc[1]= ob->dloc[1]= 0.0f;
-                                       if ((ob->protectflag & OB_LOCK_LOCZ)==0)
-                                               ob->loc[2]= ob->dloc[2]= 0.0f;
-                                       
-                               }
-                               else if (mode=='s') {
-                                       if ((ob->protectflag & OB_LOCK_SCALEX)==0) {
-                                               ob->dsize[0]= 0.0f;
-                                               ob->size[0]= 1.0f;
-                                       }
-                                       if ((ob->protectflag & OB_LOCK_SCALEY)==0) {
-                                               ob->dsize[1]= 0.0f;
-                                               ob->size[1]= 1.0f;
-                                       }
-                                       if ((ob->protectflag & OB_LOCK_SCALEZ)==0) {
-                                               ob->dsize[2]= 0.0f;
-                                               ob->size[2]= 1.0f;
-                                       }
-                               }
-                               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;
-                       }                       
+       if (changed) {
+               if(RNA_enum_is_equal(op->ptr, "type", "SELECTED")) ED_undo_push(C,"Hide Selected Objects");
+               else if(RNA_enum_is_equal(op->ptr, "type", "UNSELECTED")) ED_undo_push(C,"Hide Unselected Objects");
+               DAG_scene_sort(scene);
+               
+               WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, CTX_data_scene(C));
+               
+               if (changed_act) { /* these spaces depend on the active object */
+                       WM_event_add_notifier(C, NC_SCENE|ND_OB_ACTIVE, CTX_data_scene(C));
                }
        }
+
+       return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_set_restrictview(wmOperatorType *ot)
+{
+       PropertyRNA *prop;
+       
+       /* identifiers */
+       ot->name= "Set restrict view";
+       ot->idname= "OBJECT_OT_set_restrictview";
+       
+       /* api callbacks */
+       ot->invoke= WM_menu_invoke;
+       ot->exec= object_set_restrictview_exec;
+       ot->poll= ED_operator_view3d_active;
+       
+       prop = RNA_def_property(ot->srna, "type", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_items(prop, prop_set_restrictview_types);
+       
+}
+/* ************* Slow Parent ******************* */
+static int object_set_slowparent_exec(bContext *C, wmOperator *op)
+{
+
+       CTX_DATA_BEGIN(C, Base*, base, visible_bases) {
+                               
+               if(base->object->parent) base->object->partype |= PARSLOW;
+               base->object->recalc |= OB_RECALC_OB;
+               
+       }
+       CTX_DATA_END;
+
+       ED_anim_dag_flush_update(C);    
+       ED_undo_push(C,"Set Slow Parent");
+       
+       WM_event_add_notifier(C, NC_SCENE, CTX_data_scene(C));
+       
+       return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_set_slowparent(wmOperatorType *ot)
+{
        
-       allqueue(REDRAWVIEW3D, 0);
-       if(armature_clear==0) /* in this case flush was done */
-               ED_anim_dag_flush_update(C);    
-       BIF_undo_push(str);
+       /* identifiers */
+       ot->name= "Set Slow Parent";
+       ot->idname= "OBJECT_OT_set_slow_parent";
+       
+       /* api callbacks */
+       ot->invoke= WM_operator_confirm;
+       ot->exec= object_set_slowparent_exec;
+       ot->poll= ED_operator_view3d_active;
 }
 
-void reset_slowparents(Scene *scene, View3D *v3d)
+static int object_clear_slowparent_exec(bContext *C, wmOperator *op)
 {
-       /* back to original locations */
-       Base *base;
+       Scene *scene= CTX_data_scene(C);
 
-       for(base= FIRSTBASE; base; base= base->next) {
+       CTX_DATA_BEGIN(C, Base*, base, visible_bases) {
                if(base->object->parent) {
                        if(base->object->partype & PARSLOW) {
                                base->object->partype -= PARSLOW;
-                               where_is_object(base->object);
+                               where_is_object(scene, base->object);
                                base->object->partype |= PARSLOW;
+                               base->object->recalc |= OB_RECALC_OB;
                        }
                }
+               
        }
+       CTX_DATA_END;
+
+       ED_anim_dag_flush_update(C);    
+       ED_undo_push(C,"Clear Slow Parent");
+       
+       WM_event_add_notifier(C, NC_SCENE, CTX_data_scene(C));
+       
+       return OPERATOR_FINISHED;
 }
 
-void set_slowparent(Scene *scene, View3D *v3d)
+void OBJECT_OT_clear_slowparent(wmOperatorType *ot)
 {
-       Base *base;
-
-       if( okee("Set slow parent")==0 ) return;
-
-       for(base= FIRSTBASE; base; base= base->next) {
-               if(TESTBASELIB(v3d, base)) {
-                       if(base->object->parent) base->object->partype |= PARSLOW;
-               }
-       }
-       BIF_undo_push("Slow parent");
+       
+       /* identifiers */
+       ot->name= "Clear Slow Parent";
+       ot->idname= "OBJECT_OT_clear_slow_parent";
+       
+       /* api callbacks */
+       ot->invoke= WM_operator_confirm;
+       ot->exec= object_clear_slowparent_exec;
+       ot->poll= ED_operator_view3d_active;
 }
+/* ******************** **************** */
 
 // XXX
 #define BEZSELECTED_HIDDENHANDLES(bezt)   ((G.f & G_HIDDENHANDLES) ? (bezt)->f2 & SELECT : BEZSELECTED(bezt))
-void make_vertex_parent(Scene *scene, View3D *v3d)
+/* only in edit mode */
+void make_vertex_parent(Scene *scene, Object *obedit, View3D *v3d)
 {
-       EditMesh *em = G.editMesh;
        EditVert *eve;
        Base *base;
        Nurb *nu;
@@ -1203,8 +1713,10 @@ void make_vertex_parent(Scene *scene, View3D *v3d)
        
        /* we need 1 to 3 selected vertices */
        
-       if(G.obedit->type==OB_MESH) {
-               eve= em->verts.first;
+       if(obedit->type==OB_MESH) {
+               Mesh *me= obedit->data;
+               
+               eve= me->edit_mesh->verts.first;
                while(eve) {
                        if(eve->f & 1) {
                                if(v1==0) v1= nr;
@@ -1217,7 +1729,7 @@ void make_vertex_parent(Scene *scene, View3D *v3d)
                        eve= eve->next;
                }
        }
-       else if(ELEM(G.obedit->type, OB_SURF, OB_CURVE)) {
+       else if(ELEM(obedit->type, OB_SURF, OB_CURVE)) {
                extern ListBase editNurb;
                nu= editNurb.first;
                while(nu) {
@@ -1254,7 +1766,7 @@ void make_vertex_parent(Scene *scene, View3D *v3d)
                        nu= nu->next;
                }
        }
-       else if(G.obedit->type==OB_LATTICE) {
+       else if(obedit->type==OB_LATTICE) {
                
                a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
                bp= editLatt->def;
@@ -1304,7 +1816,7 @@ void make_vertex_parent(Scene *scene, View3D *v3d)
                                                ob->par3= v3-1;
 
                                                /* inverse parent matrix */
-                                               what_does_parent(ob, &workob);
+                                               what_does_parent(scene, ob, &workob);
                                                Mat4Invert(ob->parentinv, workob.obmat);
                                        }
                                        else {
@@ -1312,7 +1824,7 @@ void make_vertex_parent(Scene *scene, View3D *v3d)
                                                ob->par1= v1-1;
 
                                                /* inverse parent matrix */
-                                               what_does_parent(ob, &workob);
+                                               what_does_parent(scene, ob, &workob);
                                                Mat4Invert(ob->parentinv, workob.obmat);
                                        }
                                }
@@ -1385,7 +1897,7 @@ void make_proxy(Scene *scene)
                Base *newbase, *oldbase= BASACT;
                char name[32];
                
-               newob= add_object(OB_EMPTY);
+               newob= add_object(scene, OB_EMPTY);
                if(gob)
                        strcpy(name, gob->id.name+2);
                else
@@ -1452,12 +1964,12 @@ oldcode()
 // XXX                                                 create_vgroups_from_armature(base->object, par);
 
                        base->object->partype= PAROBJECT;
-                       what_does_parent(base->object);
+                       what_does_parent(scene, base->object);
                        Mat4One (base->object->parentinv);
                        base->object->partype= mode;
                }
                else
-                       what_does_parent(base->object, &workob);
+                       what_does_parent(scene, base->object, &workob);
                Mat4Invert(base->object->parentinv, workob.obmat);
        }
 }
@@ -1499,6 +2011,7 @@ static int test_parent_loop(Object *par, Object *ob)
 
 static int make_parent_exec(bContext *C, wmOperator *op)
 {
+       Scene *scene= CTX_data_scene(C);
        Object *par= CTX_data_active_object(C);
        bPoseChannel *pchan= NULL;
        int partype= RNA_enum_get(op->ptr, "type");
@@ -1514,7 +2027,7 @@ static int make_parent_exec(bContext *C, wmOperator *op)
                        
                        if((cu->flag & CU_PATH)==0) {
                                cu->flag |= CU_PATH|CU_FOLLOW;
-                               makeDispListCurveTypes(par, 0);  /* force creation of path data */
+                               makeDispListCurveTypes(scene, par, 0);  /* force creation of path data */
                        }
                        else cu->flag |= CU_FOLLOW;
                        
@@ -1543,7 +2056,7 @@ static int make_parent_exec(bContext *C, wmOperator *op)
                                Object workob;
                                
                                /* apply transformation of previous parenting */
-                               apply_obmat(ob);
+                               ED_object_apply_obmat(ob);
                                
                                ob->parent= par;
                                
@@ -1558,7 +2071,7 @@ static int make_parent_exec(bContext *C, wmOperator *op)
                                }
                                
                                /* calculate inverse parent matrix */
-                               what_does_parent(ob, &workob);
+                               what_does_parent(scene, ob, &workob);
                                Mat4Invert(ob->parentinv, workob.obmat);
                                
                                ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA;
@@ -1625,55 +2138,232 @@ void OBJECT_OT_make_parent(wmOperatorType *ot)
        ot->invoke= make_parent_invoke;
        ot->exec= make_parent_exec;
        
-       ot->poll= ED_operator_areaactive;       // XXX solve
+       ot->poll= ED_operator_object_active;
        ot->flag= OPTYPE_REGISTER;
        
        prop = RNA_def_property(ot->srna, "type", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_items(prop, prop_make_parent_types);
 }
 
-/* *******************  ***************** */
+/* *** make track ***** */
+static EnumPropertyItem prop_make_track_types[] = {
+       {1, "TRACKTO", "TrackTo Constraint", ""},
+       {2, "LOCKTRACK", "LockTrack Constraint", ""},
+       {3, "OLDTRACK", "Old Track", ""},
+       {0, NULL, NULL, NULL}
+};
 
-void enter_editmode(Scene *scene, View3D *v3d, int wc)
+static int make_track_exec(bContext *C, wmOperator *op)
 {
+       Scene *scene= CTX_data_scene(C);
+       ScrArea *sa= CTX_wm_area(C);
+       View3D *v3d= sa->spacedata.first;
        Base *base;
+       
+       if(scene->id.lib) return OPERATOR_CANCELLED;
+
+       if(RNA_enum_is_equal(op->ptr, "type", "TRACKTO")){
+               bConstraint *con;
+               bTrackToConstraint *data;
+
+               for(base= FIRSTBASE; base; base= base->next) {
+                       if(TESTBASELIB(v3d, base)) {
+                               if(base!=BASACT) {
+// XXX                                 con = add_new_constraint(CONSTRAINT_TYPE_TRACKTO);
+                                       strcpy (con->name, "AutoTrack");
+
+                                       data = con->data;
+                                       data->tar = BASACT->object;
+                                       base->object->recalc |= OB_RECALC;
+                                       
+                                       /* Lamp and Camera track differently by default */
+                                       if (base->object->type == OB_LAMP || base->object->type == OB_CAMERA) {
+                                               data->reserved1 = TRACK_nZ;
+                                               data->reserved2 = UP_Y;
+                                       }
+
+// XXX                                 add_constraint_to_object(con, base->object);
+                               }
+                       }
+               }
+
+       }
+       else if(RNA_enum_is_equal(op->ptr, "type", "LOCKTRACK")){
+               bConstraint *con;
+               bLockTrackConstraint *data;
+
+               for(base= FIRSTBASE; base; base= base->next) {
+                       if(TESTBASELIB(v3d, base)) {
+                               if(base!=BASACT) {
+// XXX                                 con = add_new_constraint(CONSTRAINT_TYPE_LOCKTRACK);
+                                       strcpy (con->name, "AutoTrack");
+
+                                       data = con->data;
+                                       data->tar = BASACT->object;
+                                       base->object->recalc |= OB_RECALC;
+                                       
+                                       /* Lamp and Camera track differently by default */
+                                       if (base->object->type == OB_LAMP || base->object->type == OB_CAMERA) {
+                                               data->trackflag = TRACK_nZ;
+                                               data->lockflag = LOCK_Y;
+                                       }
+
+// XXX                                 add_constraint_to_object(con, base->object);
+                               }
+                       }
+               }
+
+       }
+       else if(RNA_enum_is_equal(op->ptr, "type", "OLDTRACK")){
+               for(base= FIRSTBASE; base; base= base->next) {
+                       if(TESTBASELIB(v3d, base)) {
+                               if(base!=BASACT) {
+                                       base->object->track= BASACT->object;
+                                       base->object->recalc |= OB_RECALC;
+                               }
+                       }
+               }
+       }
+       DAG_scene_sort(CTX_data_scene(C));
+       ED_anim_dag_flush_update(C);    
+       
+       BIF_undo_push("make track");
+       
+       return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_make_track(wmOperatorType *ot)
+{
+       PropertyRNA *prop;
+       
+       /* identifiers */
+       ot->name= "Make Track";
+       ot->idname= "OBJECT_OT_make_track";
+       
+       /* api callbacks */
+       ot->invoke= WM_menu_invoke;
+       ot->exec= make_track_exec;
+       
+       ot->poll= ED_operator_scene_editable;
+       ot->flag= OPTYPE_REGISTER;
+       
+       prop = RNA_def_property(ot->srna, "type", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_items(prop, prop_make_track_types);
+}
+
+
+/* ******************* toggle editmode operator  ***************** */
+
+void ED_object_exit_editmode(bContext *C, int flag)
+{
+       Scene *scene= CTX_data_scene(C);
        Object *ob;
-       Mesh *me;
-       bArmature *arm;
+       Object *obedit= CTX_data_edit_object(C);
+       int freedata = flag & EM_FREEDATA;
+       
+       if(obedit==NULL) return;
+       
+       if(flag & EM_WAITCURSOR) waitcursor(1);
+       if(obedit->type==OB_MESH) {
+               Mesh *me= obedit->data;
+               
+//             if(EM_texFaceCheck())
+               
+//             if(retopo_mesh_paint_check())
+//                     retopo_end_okee();
+               
+               if(G.totvert>MESH_MAX_VERTS) {
+                       error("Too many vertices");
+                       return;
+               }
+               load_editMesh(scene, obedit);
+               
+               if(freedata) free_editMesh(me->edit_mesh);
+               
+               if(G.f & G_WEIGHTPAINT)
+                       mesh_octree_table(obedit, NULL, NULL, 'e');
+       }
+       else if (obedit->type==OB_ARMATURE) {   
+               ED_armature_from_edit(scene, obedit);
+               if(freedata)
+                       ED_armature_edit_free(obedit);
+       }
+       else if(ELEM(obedit->type, OB_CURVE, OB_SURF)) {
+//             extern ListBase editNurb;
+//             load_editNurb();
+//             if(freedata) freeNurblist(&editNurb);
+       }
+       else if(obedit->type==OB_FONT && freedata) {
+//             load_editText();
+       }
+       else if(obedit->type==OB_LATTICE) {
+//             load_editLatt();
+//             if(freedata) free_editLatt();
+       }
+       else if(obedit->type==OB_MBALL) {
+//             extern ListBase editelems;
+//             load_editMball();
+//             if(freedata) BLI_freelistN(&editelems);
+       }
+       
+       ob= obedit;
+       
+       /* for example; displist make is different in editmode */
+       if(freedata) obedit= NULL;
+       scene->obedit= obedit; // XXX for context
+       
+       /* also flush ob recalc, doesn't take much overhead, but used for particles */
+       DAG_object_flush_update(scene, ob, OB_RECALC_OB|OB_RECALC_DATA);
+       
+       if(obedit==NULL) // XXX && (flag & EM_FREEUNDO)) 
+               ED_undo_push(C, "Editmode");
+       
+       if(flag & EM_WAITCURSOR) waitcursor(0);
+       
+       WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, ob);
+
+}
+
+
+void ED_object_enter_editmode(bContext *C, int flag)
+{
+       Scene *scene= CTX_data_scene(C);
+       Base *base= CTX_data_active_base(C);
+       Object *ob= base->object;
+       ScrArea *sa= CTX_wm_area(C);
+       View3D *v3d= NULL;
        int ok= 0;
        
        if(scene->id.lib) return;
-       base= BASACT;
-       if(base==0) return;
+       if(base==NULL) return;
+       
+       if(sa->spacetype==SPACE_VIEW3D)
+               v3d= sa->spacedata.first;
+       
        if((v3d==NULL || (base->lay & v3d->lay))==0) return;
        
-       strcpy(G.editModeTitleExtra, "");
-
-       ob= base->object;
-       if(ob->data==0) return;
+       if(ob->data==NULL) return;
        
        if (object_data_is_libdata(ob)) {
                error_libdata();
                return;
        }
        
-       if(wc) waitcursor(1);
+       if(flag & EM_WAITCURSOR) waitcursor(1);
        
        if(ob->type==OB_MESH) {
-               me= get_mesh(ob);
-               if( me==0 ) return;
+               Mesh *me= ob->data;
+               
                if(me->pv) mesh_pmv_off(ob, me);
                ok= 1;
-               G.obedit= ob;
-// XXX         make_editMesh();
-               allqueue(REDRAWBUTSLOGIC, 0);
-               /*if(G.f & G_FACESELECT) allqueue(REDRAWIMAGE, 0);*/
-// XXX         if (EM_texFaceCheck())
-//                     allqueue(REDRAWIMAGE, 0);
+               scene->obedit= ob;      // context sees this
                
+               make_editMesh(scene, ob);
+
+               WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_MESH, ob);
        }
-       if (ob->type==OB_ARMATURE){
-               arm= base->object->data;
+       else if (ob->type==OB_ARMATURE){
+               bArmature *arm= base->object->data;
                if (!arm) return;
                /*
                 * The function object_data_is_libdata make a problem here, the
@@ -1688,143 +2378,93 @@ void enter_editmode(Scene *scene, View3D *v3d, int wc)
                        return;
                }
                ok=1;
-               G.obedit=ob;
-// XXX         make_editArmature();
+               scene->obedit= ob;
+               ED_armature_to_edit(ob);
                /* to ensure all goes in restposition and without striding */
-               DAG_object_flush_update(scene, G.obedit, OB_RECALC);
+               DAG_object_flush_update(scene, ob, OB_RECALC);
 
-               allqueue (REDRAWVIEW3D,0);
+               WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_ARMATURE, ob);
        }
        else if(ob->type==OB_FONT) {
-               G.obedit= ob;
-               ok= 1;
+               scene->obedit= ob; // XXX for context
+//             ok= 1;
 // XXX         make_editText();
        }
        else if(ob->type==OB_MBALL) {
-               G.obedit= ob;
-               ok= 1;
+               scene->obedit= ob; // XXX for context
+//             ok= 1;
 // XXX         make_editMball();
        }
        else if(ob->type==OB_LATTICE) {
-               G.obedit= ob;
-               ok= 1;
+               scene->obedit= ob; // XXX for context
+//             ok= 1;
 // XXX         make_editLatt();
        }
        else if(ob->type==OB_SURF || ob->type==OB_CURVE) {
-               ok= 1;
-               G.obedit= ob;
+//             ok= 1;
+               scene->obedit= ob; // XXX for context
 // XXX         make_editNurb();
        }
-       allqueue(REDRAWBUTSEDIT, 0);
-       allqueue(REDRAWOOPS, 0);
        
        if(ok) {
-       
-               allqueue(REDRAWVIEW3D, 1);
-               DAG_object_flush_update(scene, G.obedit, OB_RECALC_DATA);
-               
+               DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+       }
+       else {
+               scene->obedit= NULL; // XXX for context
+               WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, ob);
        }
-       else G.obedit= NULL;
-       
-       if(wc) waitcursor(0);
        
+       if(flag & EM_WAITCURSOR) waitcursor(0);
 }
 
-void exit_editmode(Scene *scene, int flag)     /* freedata==0 at render, 1= freedata, 2= do undo buffer too */
+static int toggle_editmode_exec(bContext *C, wmOperator *op)
 {
-#if 0
-       Object *ob;
-       int freedata = flag; // XXX & EM_FREEDATA;
        
-       if(G.obedit==NULL) return;
-
-       if(flag & EM_WAITCURSOR) waitcursor(1);
-       if(G.obedit->type==OB_MESH) {
-
-               
-               if(EM_texFaceCheck())
-                       allqueue(REDRAWIMAGE, 0);
-               
-               if(retopo_mesh_paint_check())
-                       retopo_end_okee();
-
-               if(G.totvert>MESH_MAX_VERTS) {
-                       error("Too many vertices");
-                       return;
-               }
-               load_editMesh();
-
-               if(freedata) free_editMesh(G.editMesh);
-               
-               if(G.f & G_WEIGHTPAINT)
-                       mesh_octree_table(G.obedit, NULL, 'e');
-       }
-       else if (G.obedit->type==OB_ARMATURE){  
-               load_editArmature();
-               if (freedata) free_editArmature();
-       }
-       else if(ELEM(G.obedit->type, OB_CURVE, OB_SURF)) {
-               extern ListBase editNurb;
-               load_editNurb();
-               if(freedata) freeNurblist(&editNurb);
-       }
-       else if(G.obedit->type==OB_FONT && freedata) {
-               load_editText();
-       }
-       else if(G.obedit->type==OB_LATTICE) {
-               load_editLatt();
-               if(freedata) free_editLatt();
-       }
-       else if(G.obedit->type==OB_MBALL) {
-               extern ListBase editelems;
-               load_editMball();
-               if(freedata) BLI_freelistN(&editelems);
-       }
-
-       ob= G.obedit;
+       if(!CTX_data_edit_object(C))
+               ED_object_enter_editmode(C, EM_WAITCURSOR);
+       else
+               ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR);
        
-       /* for example; displist make is different in editmode */
-       if(freedata) G.obedit= NULL;
+       return OPERATOR_FINISHED;
+}
 
-       if(ob->type==OB_MESH && get_mesh(ob)->mr)
-               multires_edge_level_update(ob, get_mesh(ob));
+void OBJECT_OT_toggle_editmode(wmOperatorType *ot)
+{
        
-       /* also flush ob recalc, doesn't take much overhead, but used for particles */
-       DAG_object_flush_update(scene, ob, OB_RECALC_OB|OB_RECALC_DATA);
-
-       allqueue(REDRAWVIEW3D, 1);
-       allqueue(REDRAWBUTSALL, 0);
-       allqueue(REDRAWACTION, 0);
-       allqueue(REDRAWNLA, 0);
-       allqueue(REDRAWIPO, 0);
-       allqueue(REDRAWOOPS, 0);
-
-       if(G.obedit==NULL && (flag & EM_FREEUNDO)) 
-               BIF_undo_push("Editmode");
+       /* identifiers */
+       ot->name= "Toggle Editmode";
+       ot->idname= "OBJECT_OT_toggle_editmode";
        
-       if(flag & EM_WAITCURSOR) waitcursor(0);
-#endif
+       /* api callbacks */
+       ot->exec= toggle_editmode_exec;
+       
+       ot->poll= ED_operator_object_active;
+       ot->flag= OPTYPE_REGISTER;
 }
 
+/* *************************** */
+
+
 void check_editmode(int type)
 {
+       Object *obedit= NULL; // XXX
        
-       if (G.obedit==0 || G.obedit->type==type) return;
+       if (obedit==NULL || obedit->type==type) return;
 
-// XXX exit_editmode(EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); /* freedata, and undo */
+// XXX ED_object_exit_editmode(C, EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); /* freedata, and undo */
 }
 
 /* 0 == do center, 1 == center new, 2 == center cursor */
 
 void docenter(Scene *scene, View3D *v3d, int centermode)
 {
-       EditMesh *em = G.editMesh;
        Base *base;
        Object *ob;
        Mesh *me, *tme;
        Curve *cu;
 /*     BezTriple *bezt;
        BPoint *bp; */
+       Object *obedit= NULL; // XXX
        Nurb *nu, *nu1;
        EditVert *eve;
        float cent[3], centn[3], min[3], max[3], omat[3][3];
@@ -1838,12 +2478,14 @@ void docenter(Scene *scene, View3D *v3d, int centermode)
        
        cent[0]= cent[1]= cent[2]= 0.0;
        
-       if(G.obedit) {
+       if(obedit) {
 
                INIT_MINMAX(min, max);
        
-               if(G.obedit->type==OB_MESH) {
-                       for(eve= em->verts.first; eve; eve= eve->next) {
+               if(obedit->type==OB_MESH) {
+                       Mesh *me= obedit->data;
+                       
+                       for(eve= me->edit_mesh->verts.first; eve; eve= eve->next) {
                                if(v3d->around==V3D_CENTROID) {
                                        total++;
                                        VECADD(cent, cent, eve->co);
@@ -1862,13 +2504,13 @@ void docenter(Scene *scene, View3D *v3d, int centermode)
                                cent[2]= (min[2]+max[2])/2.0f;
                        }
                        
-                       for(eve= em->verts.first; eve; eve= eve->next) {
+                       for(eve= me->edit_mesh->verts.first; eve; eve= eve->next) {
                                VecSubf(eve->co, eve->co, cent);                        
                        }
                        
 // XXX                 recalc_editnormals();
                        tot_change++;
-                       DAG_object_flush_update(scene, G.obedit, OB_RECALC_DATA);
+                       DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
                }
        }
        
@@ -1890,7 +2532,7 @@ void docenter(Scene *scene, View3D *v3d, int centermode)
                                if(base->object->id.lib) {
                                        tot_lib_error++;
                                }
-                               else if(G.obedit==0 && (me=get_mesh(base->object)) ) {
+                               else if(obedit==0 && (me=get_mesh(base->object)) ) {
                                        if (me->id.lib) {
                                                tot_lib_error++;
                                        } else {
@@ -1937,8 +2579,8 @@ void docenter(Scene *scene, View3D *v3d, int centermode)
                                                        base->object->loc[1]+= centn[1];
                                                        base->object->loc[2]+= centn[2];
                                                        
-                                                       where_is_object(base->object);
-                                                       ignore_parent_tx(base->object);
+                                                       where_is_object(scene, base->object);
+                                                       ignore_parent_tx(scene, base->object);
                                                        
                                                        /* other users? */
                                                        ob= G.main->object.first;
@@ -1958,8 +2600,8 @@ void docenter(Scene *scene, View3D *v3d, int centermode)
                                                                                ob->loc[1]+= centn[1];
                                                                                ob->loc[2]+= centn[2];
                                                                                
-                                                                               where_is_object(ob);
-                                                                               ignore_parent_tx(ob);
+                                                                               where_is_object(scene, ob);
+                                                                               ignore_parent_tx(scene, ob);
                                                                                
                                                                                if(tme && (tme->flag & ME_ISDONE)==0) {
                                                                                        mvert= tme->mvert;
@@ -1992,10 +2634,10 @@ void docenter(Scene *scene, View3D *v3d, int centermode)
                                else if (ELEM(base->object->type, OB_CURVE, OB_SURF)) {
                                        
                                        /* totally weak code here... (ton) */
-                                       if(G.obedit==base->object) {
+                                       if(obedit==base->object) {
                                                extern ListBase editNurb;
                                                nu1= editNurb.first;
-                                               cu= G.obedit->data;
+                                               cu= obedit->data;
                                        }
                                        else {
                                                cu= base->object->data;
@@ -2046,7 +2688,7 @@ void docenter(Scene *scene, View3D *v3d, int centermode)
                                                        nu= nu->next;
                                                }
                                
-                                               if(centermode && G.obedit==0) {
+                                               if(centermode && obedit==0) {
                                                        Mat3CpyMat4(omat, base->object->obmat);
                                                        
                                                        Mat3MulVecfl(omat, cent);
@@ -2054,14 +2696,14 @@ void docenter(Scene *scene, View3D *v3d, int centermode)
                                                        base->object->loc[1]+= cent[1];
                                                        base->object->loc[2]+= cent[2];
                                                        
-                                                       where_is_object(base->object);
-                                                       ignore_parent_tx(base->object);
+                                                       where_is_object(scene, base->object);
+                                                       ignore_parent_tx(scene, base->object);
                                                }
                                                
                                                tot_change++;
-                                               if(G.obedit) {
+                                               if(obedit) {
                                                        if (centermode==0) {
-                                                               DAG_object_flush_update(scene, G.obedit, OB_RECALC_DATA);
+                                                               DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
                                                        }
                                                        break;
                                                }
@@ -2104,10 +2746,10 @@ void docenter(Scene *scene, View3D *v3d, int centermode)
 // XXX                                         docenter_armature(base->object, centermode);
                                                tot_change++;
                                                
-                                               where_is_object(base->object);
-                                               ignore_parent_tx(base->object);
+                                               where_is_object(scene, base->object);
+                                               ignore_parent_tx(scene, base->object);
                                                
-                                               if(G.obedit) 
+                                               if(obedit) 
                                                        break;
                                        }
                                }
@@ -2139,7 +2781,7 @@ void docenter_new(Scene *scene, View3D *v3d)
 {
        if(scene->id.lib) return;
 
-       if(G.obedit) {
+       if(scene->obedit) { // XXX get from context
                error("Unable to center new in Edit Mode");
        }
        else {
@@ -2151,7 +2793,7 @@ void docenter_cursor(Scene *scene, View3D *v3d)
 {
        if(scene->id.lib) return;
 
-       if(G.obedit) {
+       if(scene->obedit) { // XXX get from context
                error("Unable to center cursor in Edit Mode");
        }
        else {
@@ -2202,7 +2844,7 @@ void movetolayer(Scene *scene, View3D *v3d)
                        }
                }
        }
-       if(islamp) reshadeall_displist();       /* only frees */
+       if(islamp) reshadeall_displist(scene);  /* only frees */
        
        /* warning, active object may be hidden now */
        
@@ -2348,13 +2990,14 @@ void special_editmenu(Scene *scene, View3D *v3d)
 {
 // XXX static short numcuts= 2;
        Object *ob= OBACT;
+       Object *obedit= NULL; // XXX
        float fac;
        int nr,ret;
        short randfac;
        
        if(ob==NULL) return;
        
-       if(G.obedit==NULL) {
+       if(obedit==NULL) {
                
                if(ob->flag & OB_POSEMODE) {
 // XXX                 pose_special_editmenu();
@@ -2467,7 +3110,7 @@ void special_editmenu(Scene *scene, View3D *v3d)
                                break;
                        }
                        
-                       DAG_object_flush_update(scene, G.obedit, OB_RECALC_DATA);
+                       DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
                        
                        if(nr>0) waitcursor(0);
 #endif
@@ -2546,7 +3189,7 @@ void special_editmenu(Scene *scene, View3D *v3d)
                        }                       
                }
        }
-       else if(G.obedit->type==OB_MESH) {
+       else if(obedit->type==OB_MESH) {
                /* This is all that is needed, since all other functionality is in Ctrl+ V/E/F but some users didnt like, so for now have the old/big menu */
                /*
                nr= pupmenu("Subdivide Mesh%t|Subdivide%x1|Subdivide Multi%x2|Subdivide Multi Fractal%x3|Subdivide Smooth%x4");
@@ -2666,12 +3309,12 @@ void special_editmenu(Scene *scene, View3D *v3d)
                }
                
                
-               DAG_object_flush_update(scene, G.obedit, OB_RECALC_DATA);
+               DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
                
                if(nr>0) waitcursor(0);
                
        }
-       else if(ELEM(G.obedit->type, OB_CURVE, OB_SURF)) {
+       else if(ELEM(obedit->type, OB_CURVE, OB_SURF)) {
 
                nr= pupmenu("Specials%t|Subdivide%x1|Switch Direction%x2|Set Goal Weight%x3|Set Radius%x4|Smooth%x5|Smooth Radius%x6");
                
@@ -2695,9 +3338,9 @@ void special_editmenu(Scene *scene, View3D *v3d)
 // XXX                 smoothradiusNurb();
                        break;
                }
-               DAG_object_flush_update(scene, G.obedit, OB_RECALC_DATA);
+               DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
        }
-       else if(G.obedit->type==OB_ARMATURE) {
+       else if(obedit->type==OB_ARMATURE) {
                nr= pupmenu("Specials%t|Subdivide %x1|Subdivide Multi%x2|Switch Direction%x7|Flip Left-Right Names%x3|%l|AutoName Left-Right%x4|AutoName Front-Back%x5|AutoName Top-Bottom%x6");
 //             if(nr==1)
 // XXX                 subdivide_armature(1);
@@ -2714,7 +3357,7 @@ void special_editmenu(Scene *scene, View3D *v3d)
 //             else if(nr == 7)
 // XXX                 switch_direction_armature();
        }
-       else if(G.obedit->type==OB_LATTICE) {
+       else if(obedit->type==OB_LATTICE) {
                static float weight= 1.0f;
                { // XXX
 // XXX         if(fbutton(&weight, 0.0f, 1.0f, 10, 10, "Set Weight")) {
@@ -2733,7 +3376,7 @@ void special_editmenu(Scene *scene, View3D *v3d)
        
 }
 
-static void curvetomesh(Object *ob) 
+static void curvetomesh(Scene *scene, Object *ob) 
 {
        Curve *cu;
        DispList *dl;
@@ -2742,7 +3385,7 @@ static void curvetomesh(Object *ob)
        cu= ob->data;
        
        dl= cu->disp.first;
-       if(dl==0) makeDispListCurveTypes(ob, 0);                /* force creation */
+       if(dl==0) makeDispListCurveTypes(scene, ob, 0);         /* force creation */
 
        nurbs_to_mesh(ob); /* also does users */
        if (ob->type != OB_MESH) {
@@ -2756,6 +3399,7 @@ void convertmenu(Scene *scene, View3D *v3d)
 {
        Base *base, *basen=NULL, *basact, *basedel=NULL;
        Object *obact, *ob, *ob1;
+       Object *obedit= NULL; // XXX
        Curve *cu;
        Nurb *nu;
        MetaBall *mb;
@@ -2767,7 +3411,7 @@ void convertmenu(Scene *scene, View3D *v3d)
        obact= OBACT;
        if (obact == NULL) return;
        if(!obact->flag & SELECT) return;
-       if(G.obedit) return;
+       if(obedit) return;
        
        basact= BASACT; /* will be restored */
                
@@ -2835,7 +3479,7 @@ void convertmenu(Scene *scene, View3D *v3d)
                                G.totmesh++;
 
                                /* make new mesh data from the original copy */
-                               dm= mesh_get_derived_final(ob1, CD_MASK_MESH);
+                               dm= mesh_get_derived_final(scene, ob1, CD_MASK_MESH);
                                /* dm= mesh_create_derived_no_deform(ob1, NULL);        this was called original (instead of get_derived). man o man why! (ton) */
                                
                                DM_to_mesh(dm, ob1->data);
@@ -2890,18 +3534,18 @@ void convertmenu(Scene *scene, View3D *v3d)
                                        }                                       
                                }
                                if (nr==3) {
-                                       curvetomesh(ob);
+                                       curvetomesh(scene, ob);
                                }
                        }
                        else if(ELEM(ob->type, OB_CURVE, OB_SURF)) {
                                if(nr==1) {
-                                       curvetomesh(ob);
+                                       curvetomesh(scene, ob);
                                }
                        }
                        else if(ob->type==OB_MBALL) {
                        
                                if(nr==1 || nr == 2) {
-                                       ob= find_basis_mball(ob);
+                                       ob= find_basis_mball(scene, ob);
                                        
                                        if(ob->disp.first && !(ob->flag&OB_DONE)) {
                                                basedel = base;
@@ -2949,9 +3593,7 @@ void convertmenu(Scene *scene, View3D *v3d)
                        }
                }
                if(basedel != NULL && nr == 2) {
-                       if(basedel==basact)
-                               basact= NULL;
-                       free_and_unlink_base(scene, basedel);   
+                       ED_base_object_free_and_unlink(scene, basedel); 
                }
                basedel = NULL;                         
        }
@@ -2963,8 +3605,8 @@ void convertmenu(Scene *scene, View3D *v3d)
        /* texspace and normals */
        if(!basen) BASACT= base;
 
-       enter_editmode(scene, v3d, EM_WAITCURSOR);
-// XXX exit_editmode(EM_FREEDATA|EM_WAITCURSOR); /* freedata, but no undo */
+// XXX ED_object_enter_editmode(C, 0);
+// XXX exit_editmode(C, EM_FREEDATA|EM_WAITCURSOR); /* freedata, but no undo */
        BASACT= basact;
 
        allqueue(REDRAWVIEW3D, 0);
@@ -3077,8 +3719,8 @@ void flip_subdivison(Scene *scene, View3D *v3d, int level)
                mode= eModifierMode_Render|eModifierMode_Realtime;
        
        if(level == -1) {
-               if (G.obedit) {
-                       object_has_subdivision_particles(G.obedit, &havesubdiv, &havepart, 0);                  
+               if (scene->obedit) { // XXX get from context
+                       object_has_subdivision_particles(scene->obedit, &havesubdiv, &havepart, 0);                     
                } else {
                        for(base= scene->base.first; base; base= base->next) {
                                if(((level==-1) && (TESTBASE(v3d, base))) || (TESTBASELIB(v3d, base))) {
@@ -3100,8 +3742,8 @@ void flip_subdivison(Scene *scene, View3D *v3d, int level)
        else if(havepart)
                particles= 1;
 
-       if (G.obedit) { 
-               object_flip_subdivison_particles(scene, G.obedit, &set, level, mode, particles, 0);
+       if (scene->obedit) {     // XXX get from context
+               object_flip_subdivison_particles(scene, scene->obedit, &set, level, mode, particles, 0);
        } else {
                for(base= scene->base.first; base; base= base->next) {
                        if(((level==-1) && (TESTBASE(v3d, base))) || (TESTBASELIB(v3d, base))) {
@@ -3378,7 +4020,7 @@ void copy_attr(Scene *scene, View3D *v3d, short event)
 
        if(!(ob=OBACT)) return;
        
-       if(G.obedit) {
+       if(scene->obedit) { // XXX get from context
                /* obedit_copymenu(); */
                return;
        }
@@ -3491,7 +4133,7 @@ void copy_attr(Scene *scene, View3D *v3d, short event)
                                                cu1->vfontbi= cu->vfontbi;
                                                id_us_plus((ID *)cu1->vfontbi);                                         
 
-                                               text_to_curve(base->object, 0);         /* needed? */
+                                               text_to_curve(scene, base->object, 0);          /* needed? */
 
                                                
                                                strcpy(cu1->family, cu->family);
@@ -3630,7 +4272,7 @@ void copy_attr_menu(Scene *scene, View3D *v3d)
        
        if(!(ob=OBACT)) return;
        
-       if (G.obedit) {
+       if (scene->obedit) { // XXX get from context
 //             if (ob->type == OB_MESH)
 // XXX                 mesh_copy_menu();
                return;
@@ -3793,7 +4435,7 @@ void make_links(Scene *scene, View3D *v3d, short event)
                                        obt->ipo= ob->ipo;
                                        if(obt->ipo) {
                                                id_us_plus((ID *)obt->ipo);
-                                               do_ob_ipo(obt);
+                                               do_ob_ipo(scene, obt);
                                        }
                                }
                                else if(event==6) {
@@ -3957,13 +4599,13 @@ static void apply_objects_internal(Scene *scene, View3D *v3d, int apply_scale, i
                                        ob->rot[0]= ob->rot[1]= ob->rot[2]= 0.0f;
                                /*QuatOne(ob->quat);*/ /* Quats arnt used yet */
                                
-                               where_is_object(ob);
+                               where_is_object(scene, ob);
                                
                                /* texspace and normals */
                                BASACT= base;
-                               enter_editmode(scene, v3d, EM_WAITCURSOR);
+// XXX                         ED_object_enter_editmode(C, 0);
                                BIF_undo_push("Applied object");        /* editmode undo itself */
-// XXX                         exit_editmode(EM_FREEDATA|EM_WAITCURSOR); /* freedata, but no undo */
+// XXX                         ED_object_exit_editmode(C, EM_FREEDATA|EM_WAITCURSOR); /* freedata, but no undo */
                                BASACT= basact;
                                
                                change = 1;
@@ -3987,7 +4629,7 @@ static void apply_objects_internal(Scene *scene, View3D *v3d, int apply_scale, i
                                        ob->rot[0]= ob->rot[1]= ob->rot[2]= 0.0;
                                /*QuatOne(ob->quat); (not used anymore)*/
                                
-                               where_is_object(ob);
+                               where_is_object(scene, ob);
                                
                                change = 1;
                        }
@@ -4033,13 +4675,13 @@ static void apply_objects_internal(Scene *scene, View3D *v3d, int apply_scale, i
                                        ob->rot[0]= ob->rot[1]= ob->rot[2]= 0.0;
                                /*QuatOne(ob->quat); (quats arnt used anymore)*/
                                
-                               where_is_object(ob);
+                               where_is_object(scene, ob);
                                
                                /* texspace and normals */
                                BASACT= base;
-                               enter_editmode(scene, v3d, EM_WAITCURSOR);
+// XXX                         ED_object_enter_editmode(C, 0);
                                BIF_undo_push("Applied object");        /* editmode undo itself */
-// XXX                         exit_editmode(EM_FREEDATA|EM_WAITCURSOR); /* freedata, but no undo */
+// XXX                         ED_object_exit_editmode(C, EM_FREEDATA|EM_WAITCURSOR); /* freedata, but no undo */
                                BASACT= basact;
                                
                                change = 1;
@@ -4047,7 +4689,7 @@ static void apply_objects_internal(Scene *scene, View3D *v3d, int apply_scale, i
                                continue;
                        }
                        
-                       ignore_parent_tx(ob);
+                       ignore_parent_tx(scene, ob);
                }
        }
        if (change) {
@@ -4085,12 +4727,12 @@ void apply_objects_visual_tx( Scene *scene, View3D *v3d )
        for (base= FIRSTBASE; base; base= base->next) {
                if(TESTBASELIB(v3d, base)) {
                        ob= base->object;
-                       where_is_object(ob);
+                       where_is_object(scene, ob);
                        VECCOPY(ob->loc, ob->obmat[3]);
                        Mat4ToSize(ob->obmat, ob->size);
                        Mat4ToEul(ob->obmat, ob->rot);
                        
-                       where_is_object(ob);
+                       where_is_object(scene, ob);
                        
                        change = 1;
                }
@@ -4252,7 +4894,7 @@ void make_object_duplilist_real(Scene *scene, View3D *v3d, Base *base)
                ob->transflag &= ~OB_DUPLI;     
                
                Mat4CpyMat4(ob->obmat, dob->mat);
-               apply_obmat(ob);
+               ED_object_apply_obmat(ob);
        }
        
        copy_object_set_idnew(scene, v3d, 0);
@@ -4292,7 +4934,7 @@ void apply_object(Scene *scene, View3D *v3d)
        int shift= 0;
        
        if(scene->id.lib) return;
-       if(G.obedit) return;
+       if(scene->obedit) return; // XXX get from context
        
        if(shift) {
                ob= OBACT;
@@ -5322,7 +5964,7 @@ void image_aspect(Scene *scene, View3D *v3d)
        float x, y, space;
        int a, b, done;
        
-       if(G.obedit) return;
+       if(scene->obedit) return; // XXX get from context
        if(scene->id.lib) return;
        
        for(base= FIRSTBASE; base; base= base->next) {
@@ -5575,7 +6217,7 @@ void texspace_edit(Scene *scene, View3D *v3d)
         * texspacedraw is set:
         */
        
-       if(G.obedit) return;
+       if(scene->obedit) return; // XXX get from context
        
        for(base= FIRSTBASE; base; base= base->next) {
                if(TESTBASELIB(v3d, base)) {
@@ -5665,7 +6307,7 @@ void hookmenu(Scene *scene, View3D *v3d)
                                                float *curs = give_cursor(scene, v3d);
                                                float bmat[3][3], imat[3][3];
                                                
-                                               where_is_object(ob);
+                                               where_is_object(scene, ob);
                                        
                                                Mat3CpyMat4(bmat, ob->obmat);
                                                Mat3Inv(imat, bmat);
@@ -5694,55 +6336,3 @@ void hookmenu(Scene *scene, View3D *v3d)
                allqueue(REDRAWBUTSEDIT, 0);
        }       
 }
-
-void hide_objects(Scene *scene, View3D *v3d, int select)
-{
-       Base *base;
-       short changed = 0, changed_act = 0;
-       for(base = FIRSTBASE; base; base=base->next){
-               if ((base->lay & v3d->lay) && TESTBASELIB(v3d, base)==select) {
-                       base->flag &= ~SELECT;
-                       base->object->flag = base->flag;
-                       base->object->restrictflag |= OB_RESTRICT_VIEW;
-                       changed = 1;
-                       if (base==BASACT) {
-                               BASACT= NULL;
-                               changed_act = 1;
-                       }
-               }
-       }
-       if (changed) {
-               if(select) BIF_undo_push("Hide Selected Objects");
-               else if(select) BIF_undo_push("Hide Unselected Objects");
-               DAG_scene_sort(scene);
-               allqueue(REDRAWVIEW3D,0);
-               allqueue(REDRAWOOPS,0);
-               allqueue(REDRAWDATASELECT,0);
-               if (changed_act) { /* these spaces depend on the active object */
-                       allqueue(REDRAWBUTSALL,0);
-                       allqueue(REDRAWIPO,0);
-                       allqueue(REDRAWACTION,0);
-               }
-       }
-}
-
-void show_objects(Scene *scene, View3D *v3d)
-{
-       Base *base;
-       int changed = 0;
-       
-       for(base = FIRSTBASE; base; base=base->next){
-               if((base->lay & v3d->lay) && base->object->restrictflag & OB_RESTRICT_VIEW) {
-                       base->flag |= SELECT;
-                       base->object->flag = base->flag;
-                       base->object->restrictflag &= ~OB_RESTRICT_VIEW; 
-                       changed = 1;
-               }
-       }
-       if (changed) {
-               BIF_undo_push("Unhide Objects");
-               DAG_scene_sort(scene);
-               allqueue(REDRAWVIEW3D,0);
-               allqueue(REDRAWOOPS,0);
-       }
-}