2.5: Curve edit mode. Transform works again, and editcurve.c is
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Wed, 11 Feb 2009 23:02:21 +0000 (23:02 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Wed, 11 Feb 2009 23:02:21 +0000 (23:02 +0000)
partly operatorized though nothing hooked up yet.

source/blender/editors/curve/curve_intern.h
source/blender/editors/curve/curve_ops.c
source/blender/editors/curve/editcurve.c
source/blender/editors/mesh/editmesh_mods.c
source/blender/editors/mesh/editmesh_tools.c
source/blender/editors/screen/screen_ops.c
source/blender/editors/transform/transform_conversions.c
source/blender/editors/transform/transform_generics.c

index a77300f29f58b7211686f067db78e21b33192981..ba01c1207e74d9d62acb33f079e29827346cc138 100644 (file)
@@ -38,5 +38,38 @@ char *ED_lorem;
 /* editfont.c */
 void FONT_OT_textedit(struct wmOperatorType *ot);
 
+/* editcurve.c */
+void CURVE_OT_separate(struct wmOperatorType *ot);
+void CURVE_OT_switch_direction(struct wmOperatorType *ot);
+void CURVE_OT_set_weight(struct wmOperatorType *ot);
+void CURVE_OT_set_radius(struct wmOperatorType *ot);
+void CURVE_OT_smooth(struct wmOperatorType *ot);
+void CURVE_OT_smooth_curve_radius(struct wmOperatorType *ot);
+void CURVE_OT_de_select_first(struct wmOperatorType *ot);
+void CURVE_OT_de_select_last(struct wmOperatorType *ot);
+void CURVE_OT_de_select_all(struct wmOperatorType *ot);
+void CURVE_OT_hide(struct wmOperatorType *ot);
+void CURVE_OT_reveal(struct wmOperatorType *ot);
+void CURVE_OT_select_invert(struct wmOperatorType *ot);
+void CURVE_OT_subdivide(struct wmOperatorType *ot);
+void CURVE_OT_set_spline_type(struct wmOperatorType *ot);
+void CURVE_OT_make_segment(struct wmOperatorType *ot);
+void CURVE_OT_spin(struct wmOperatorType *ot);
+void CURVE_OT_add_vertex(struct wmOperatorType *ot);
+void CURVE_OT_extrude(struct wmOperatorType *ot);
+void CURVE_OT_make_cyclic(struct wmOperatorType *ot);
+void CURVE_OT_select_linked(struct wmOperatorType *ot);
+void CURVE_OT_select_row(struct wmOperatorType *ot);
+void CURVE_OT_select_next(struct wmOperatorType *ot);
+void CURVE_OT_select_previous(struct wmOperatorType *ot);
+void CURVE_OT_select_more(struct wmOperatorType *ot);
+void CURVE_OT_select_less(struct wmOperatorType *ot);
+void CURVE_OT_select_random(struct wmOperatorType *ot);
+void CURVE_OT_select_every_nth(struct wmOperatorType *ot);
+void CURVE_OT_add_duplicate(struct wmOperatorType *ot);
+void CURVE_OT_delete(struct wmOperatorType *ot);
+void CURVE_OT_set_smooth(struct wmOperatorType *ot);
+void CURVE_OT_clear_tilt(struct wmOperatorType *ot);
+
 #endif /* ED_UTIL_INTERN_H */
 
index 4d60c2716ba20cc288d4a63d742ecd9f7a67e14d..4455144c85975c23b8987d1054d909ce04a89733 100644 (file)
 void ED_operatortypes_curve(void)
 {
        WM_operatortype_append(FONT_OT_textedit);
+
+       WM_operatortype_append(CURVE_OT_separate);
+       WM_operatortype_append(CURVE_OT_switch_direction);
+       WM_operatortype_append(CURVE_OT_set_weight);
+       WM_operatortype_append(CURVE_OT_set_radius);
+       WM_operatortype_append(CURVE_OT_smooth);
+       WM_operatortype_append(CURVE_OT_smooth_curve_radius);
+       WM_operatortype_append(CURVE_OT_de_select_first);
+       WM_operatortype_append(CURVE_OT_de_select_last);
+       WM_operatortype_append(CURVE_OT_de_select_all);
+       WM_operatortype_append(CURVE_OT_hide);
+       WM_operatortype_append(CURVE_OT_reveal);
+       WM_operatortype_append(CURVE_OT_select_invert);
+       WM_operatortype_append(CURVE_OT_subdivide);
+       WM_operatortype_append(CURVE_OT_set_spline_type);
+       WM_operatortype_append(CURVE_OT_make_segment);
+       WM_operatortype_append(CURVE_OT_spin);
+       WM_operatortype_append(CURVE_OT_add_vertex);
+       WM_operatortype_append(CURVE_OT_extrude);
+       WM_operatortype_append(CURVE_OT_make_cyclic);
+       WM_operatortype_append(CURVE_OT_select_linked);
+       WM_operatortype_append(CURVE_OT_select_row);
+       WM_operatortype_append(CURVE_OT_select_next);
+       WM_operatortype_append(CURVE_OT_select_previous);
+       WM_operatortype_append(CURVE_OT_select_more);
+       WM_operatortype_append(CURVE_OT_select_less);
+       WM_operatortype_append(CURVE_OT_select_random);
+       WM_operatortype_append(CURVE_OT_select_every_nth);
+       WM_operatortype_append(CURVE_OT_add_duplicate);
+       WM_operatortype_append(CURVE_OT_delete);
+       WM_operatortype_append(CURVE_OT_set_smooth);
+       WM_operatortype_append(CURVE_OT_clear_tilt);
 }
 
 void ED_keymap_curve(wmWindowManager *wm)
@@ -77,6 +109,5 @@ void ED_keymap_curve(wmWindowManager *wm)
        keymap= WM_keymap_listbase(wm, "Curve", 0, 0);
        
        WM_keymap_add_item(keymap, "OBJECT_OT_curve_add", AKEY, KM_PRESS, KM_SHIFT, 0);
-
 }
 
index 4962a238f2e18e47b3ff1af0d7babbe5624e528b..281d9f407dcc5376d778e5e107a60c89b46c753f 100644 (file)
 #include "BKE_curve.h"
 #include "BKE_depsgraph.h"
 #include "BKE_fcurve.h"
+#include "BKE_global.h"
 #include "BKE_key.h"
 #include "BKE_library.h"
-#include "BKE_global.h"
 #include "BKE_main.h"
 #include "BKE_object.h"
+#include "BKE_report.h"
 #include "BKE_utildefines.h"
 
 #include "WM_api.h"
 #include "ED_anim_api.h"
 #include "ED_keyframes_edit.h"
 #include "ED_object.h"
+#include "ED_screen.h"
 #include "ED_types.h"
 #include "ED_util.h"
 #include "ED_view3d.h"
 
+#include "UI_interface.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
 /* still need to eradicate a few :( */
 #define callocstructN(x,y,name) (x*)MEM_callocN((y)* sizeof(x),name)
 
 
 /* XXX */
 static void BIF_undo_push() {}
-static void waitcursor() {}
-static void error() {}
 static int okee() {return 0;}
 static int pupmenu() {return 0;}
-static int button() {return 0;}
-static float fbutton() {return 0;}
 static void adduplicate() {}
 static void error_libdata() {}
 /* XXX */
@@ -373,9 +376,12 @@ void free_editNurb(Object *obedit)
        }
 }
 
-void separate_nurb(Scene *scene)
+/******************** XXX separate operator ***********************/
+
+static int separate_exec(bContext *C, wmOperator *op)
 {
-       Object *obedit= scene->obedit; // XXX use context
+       Scene *scene= CTX_data_scene(C);
+       Object *obedit= CTX_data_edit_object(C);
        ListBase *editnurb= curve_get_editcurve(obedit);
        View3D *v3d= NULL; // XXX
        Nurb *nu, *nu1;
@@ -384,17 +390,13 @@ void separate_nurb(Scene *scene)
        Curve *cu;
        ListBase editnurbo;
 
-       if( v3d==0 || (v3d->lay & obedit->lay)==0 ) return;
-
-       if(okee("Separate")==0) return;
-
-       waitcursor(1);
-       
        cu= obedit->data;
        if(cu->key) {
-               error("Can't separate a curve with vertex keys");
-               return;
+               BKE_report(op->reports, RPT_ERROR, "Can't separate a curve with vertex keys");
+               return OPERATOR_CANCELLED;
        }
+
+       WM_cursor_wait(1);
        
        /* we are going to trick everything as follows:
         * 1. duplicate base: this is the new one,  remember old pointer
@@ -445,22 +447,39 @@ void separate_nurb(Scene *scene)
        *editnurb= editnurbo;
        
        obedit= 0;      /* displists behave different in edit mode */
-       DAG_object_flush_update(scene, OBACT, OB_RECALC_DATA);  /* this is the separated one */
+       DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); /* this is the separated one */
        DAG_object_flush_update(scene, oldob, OB_RECALC_DATA);  /* this is the original one */
        
        obedit= oldob;
        BASACT= oldbase;
        BASACT->flag |= SELECT;
        
-       waitcursor(0);
-
        set_actNurb(obedit, NULL);
+
+       WM_cursor_wait(0);
+
+       // XXX notifier
+
+       return OPERATOR_FINISHED;
 }
 
-/* ******************* FLAGS ********************* */
+void CURVE_OT_separate(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Separate";
+       ot->idname= "CURVE_OT_separate";
+       
+       /* api callbacks */
+       ot->exec= separate_exec;
+       ot->poll= ED_operator_editcurve;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
 
+/* ******************* FLAGS ********************* */
 
-short isNurbselUV(Nurb *nu, int *u, int *v, int flag)
+static short isNurbselUV(Nurb *nu, int *u, int *v, int flag)
 {
        /* return u!=-1:     1 row in u-direction selected. U has value between 0-pntsv 
      * return v!=-1: 1 collumn in v-direction selected. V has value between 0-pntsu 
@@ -501,7 +520,7 @@ short isNurbselUV(Nurb *nu, int *u, int *v, int flag)
        return 0;
 }
 
-void setflagsNurb(ListBase *editnurb, short flag)
+static void setflagsNurb(ListBase *editnurb, short flag)
 {
        Nurb *nu;
        BezTriple *bezt;
@@ -528,7 +547,7 @@ void setflagsNurb(ListBase *editnurb, short flag)
        }
 }
 
-void rotateflagNurb(ListBase *editnurb, short flag, float *cent, float rotmat[][3])
+static void rotateflagNurb(ListBase *editnurb, short flag, float *cent, float rotmat[][3])
 {
        /* all verts with (flag & 'flag') rotate */
        Nurb *nu;
@@ -556,8 +575,7 @@ void rotateflagNurb(ListBase *editnurb, short flag, float *cent, float rotmat[][
        }
 }
 
-
-void translateflagNurb(ListBase *editnurb, short flag, float *vec)
+static void translateflagNurb(ListBase *editnurb, short flag, float *vec)
 {
        /* all verts with ('flag' & flag) translate */
        Nurb *nu;
@@ -589,7 +607,7 @@ void translateflagNurb(ListBase *editnurb, short flag, float *vec)
        }
 }
 
-void weightflagNurb(ListBase *editnurb, short flag, float w, int mode) /* mode==0: replace, mode==1: multiply */
+static void weightflagNurb(ListBase *editnurb, short flag, float w, int mode)  /* mode==0: replace, mode==1: multiply */
 {
        Nurb *nu;
        BPoint *bp;
@@ -610,9 +628,9 @@ void weightflagNurb(ListBase *editnurb, short flag, float w, int mode)      /* mode==
        }
 }
 
-void deleteflagNurb(Scene *scene, short flag)
+static int deleteflagNurb(bContext *C, wmOperator *op, int flag)
 {
-       Object *obedit= scene->obedit; // XXX use context
+       Object *obedit= CTX_data_edit_object(C);
        Curve *cu= obedit->data;
        ListBase *editnurb= curve_get_editcurve(obedit);
        Nurb *nu, *next;
@@ -620,7 +638,7 @@ void deleteflagNurb(Scene *scene, short flag)
        int a, b, newu, newv, sel;
 
        if(obedit && obedit->type==OB_SURF);
-       else return;
+       else return OPERATOR_CANCELLED;
 
        cu->lastselbp= NULL;
 
@@ -727,10 +745,12 @@ void deleteflagNurb(Scene *scene, short flag)
                }
                nu= next;
        }
+
+       return OPERATOR_FINISHED;
 }
 
 /* only for OB_SURF */
-short extrudeflagNurb(ListBase *editnurb, int flag)
+static short extrudeflagNurb(ListBase *editnurb, int flag)
 {
        Nurb *nu;
        BPoint *bp, *bpn, *newbp;
@@ -847,9 +867,8 @@ short extrudeflagNurb(ListBase *editnurb, int flag)
        return ok;
 }
 
-void adduplicateflagNurb(Scene *scene, short flag)
+static void adduplicateflagNurb(Object *obedit, short flag)
 {
-       Object *obedit= scene->obedit; // XXX context
        ListBase *editnurb= curve_get_editcurve(obedit);
        Nurb *nu, *newnu;
        BezTriple *bezt, *bezt1;
@@ -1018,138 +1037,152 @@ void adduplicateflagNurb(Scene *scene, short flag)
        /* actnu changed */
 }
 
+/**************** switch direction operator ***************/
 
-void switchdirectionNurb2(Scene *scene)
+static int switch_direction_exec(bContext *C, wmOperator *op)
 {
-       Object *obedit= scene->obedit; // XXX use context
+       Object *obedit= CTX_data_edit_object(C);
        ListBase *editnurb= curve_get_editcurve(obedit);
-       View3D *v3d= NULL; // XXX
        Nurb *nu;
        
-       if(v3d==0 || !(obedit->lay & v3d->lay))
-               return;
-       
-       for(nu= editnurb->first; nu; nu= nu->next) {
-               if( isNurbsel(nu) ) switchdirectionNurb(nu);
-       }
+       for(nu= editnurb->first; nu; nu= nu->next)
+               if(isNurbsel(nu))
+                       switchdirectionNurb(nu);
        
-       DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+       DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA);
+       // XXX notifier
 
-       BIF_undo_push("Switch direction");
+       return OPERATOR_FINISHED;
 }
 
-void switchdirection_knots(float *base, int tot)
+void CURVE_OT_switch_direction(wmOperatorType *ot)
 {
-       float *fp1, *fp2, *tempf;
-       int a;
-       
-       if(base==NULL || tot==0) return;
+       /* identifiers */
+       ot->name= "Switch Direction";
+       ot->idname= "CURVE_OT_switch_direction";
        
-       /* reverse knots */
-       a= tot;
-       fp1= base;
-       fp2= fp1+(a-1);
-       a/= 2;
-       while(fp1!=fp2 && a>0) {
-               SWAP(float, *fp1, *fp2);
-               a--;
-               fp1++; 
-               fp2--;
-       }
-       /* and make in increasing order again */
-       a= tot;
-       fp1= base;
-       fp2=tempf= MEM_mallocN(sizeof(float)*a, "switchdirect");
-       while(a--) {
-               fp2[0]= fabs(fp1[1]-fp1[0]);
-               fp1++;
-               fp2++;
-       }
+       /* api callbacks */
+       ot->exec= switch_direction_exec;
+       ot->poll= ED_operator_editcurve; // XXX nurb poll()
 
-       a= tot-1;
-       fp1= base;
-       fp2= tempf;
-       fp1[0]= 0.0;
-       fp1++;
-       while(a--) {
-               fp1[0]= fp1[-1]+fp2[0];
-               fp1++;
-               fp2++;
-       }
-       MEM_freeN(tempf);
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
-void setweightNurb(Scene *scene)
+/****************** set weight operator *******************/
+
+static int set_weight_exec(bContext *C, wmOperator *op)
 {
-       Object *obedit= scene->obedit; // XXX context
+       Object *obedit= CTX_data_edit_object(C);
        ListBase *editnurb= curve_get_editcurve(obedit);
-       static float weight= 1.0f;
        Nurb *nu;
        BezTriple *bezt;
        BPoint *bp;
+       float weight= RNA_float_get(op->ptr, "weight");
        int a;
                                
-       if(fbutton(&weight, 0.0f, 1.0f, 10, 10, "Set Weight")) {
-               for(nu= editnurb->first; nu; nu= nu->next) {
-                       if(nu->bezt) {
-                               for(bezt=nu->bezt, a=0; a<nu->pntsu; a++, bezt++) {
-                                       if(bezt->f2 & SELECT)
-                                               bezt->weight= weight;
-                               }
+       for(nu= editnurb->first; nu; nu= nu->next) {
+               if(nu->bezt) {
+                       for(bezt=nu->bezt, a=0; a<nu->pntsu; a++, bezt++) {
+                               if(bezt->f2 & SELECT)
+                                       bezt->weight= weight;
                        }
-                       else if(nu->bp) {
-                               for(bp=nu->bp, a=0; a<nu->pntsu*nu->pntsv; a++, bp++) {
-                                       if(bp->f1 & SELECT)
-                                               bp->weight= weight;
-                               }
+               }
+               else if(nu->bp) {
+                       for(bp=nu->bp, a=0; a<nu->pntsu*nu->pntsv; a++, bp++) {
+                               if(bp->f1 & SELECT)
+                                       bp->weight= weight;
                        }
-               }       
-       }
-       BIF_undo_push("Set Curve Weight");
-       DAG_object_flush_update(scene, OBACT, OB_RECALC_DATA);
+               }
+       }       
+
+       // XXX notifier
+       DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA);
+
+       return OPERATOR_FINISHED;
 }
 
-void setradiusNurb(Scene *scene)
+void CURVE_OT_set_weight(wmOperatorType *ot)
 {
-       Object *obedit= scene->obedit; // XXX
+       /* identifiers */
+       ot->name= "Set Curve Weight";
+       ot->idname= "CURVE_OT_set_weight";
+       
+       /* api callbacks */
+       ot->exec= set_weight_exec;
+       ot->poll= ED_operator_editcurve; // XXX nurb poll()
+
+       // XXX invoke popup?
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+       /* properties */
+       RNA_def_float(ot->srna, "weight", 1.0f, 0.0f, 1.0f, "Weight", "", 0.0f, 1.0f);
+}
+
+/******************* set radius operator ******************/
+
+static int set_radius_exec(bContext *C, wmOperator *op)
+{
+       Object *obedit= CTX_data_edit_object(C);
        ListBase *editnurb= curve_get_editcurve(obedit);
-       static float radius= 1.0f;
        Nurb *nu;
        BezTriple *bezt;
        BPoint *bp;
+       float radius= RNA_float_get(op->ptr, "radius");
        int a;
        
-       if(fbutton(&radius, 0.0001f, 10.0f, 10, 10, "Set Radius")) {
-               for(nu= editnurb->first; nu; nu= nu->next) {
-                       if(nu->bezt) {
-                               for(bezt=nu->bezt, a=0; a<nu->pntsu; a++, bezt++) {
-                                       if(bezt->f2 & SELECT)
-                                               bezt->radius= radius;
-                               }
+       for(nu= editnurb->first; nu; nu= nu->next) {
+               if(nu->bezt) {
+                       for(bezt=nu->bezt, a=0; a<nu->pntsu; a++, bezt++) {
+                               if(bezt->f2 & SELECT)
+                                       bezt->radius= radius;
                        }
-                       else if(nu->bp) {
-                               for(bp=nu->bp, a=0; a<nu->pntsu*nu->pntsv; a++, bp++) {
-                                       if(bp->f1 & SELECT)
-                                               bp->radius= radius;
-                               }
+               }
+               else if(nu->bp) {
+                       for(bp=nu->bp, a=0; a<nu->pntsu*nu->pntsv; a++, bp++) {
+                               if(bp->f1 & SELECT)
+                                       bp->radius= radius;
                        }
-               }       
-       }
-       BIF_undo_push("Set Curve Radius");
-       DAG_object_flush_update(scene, OBACT, OB_RECALC_DATA);
+               }
+       }       
+
+       DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA);
+
+       return OPERATOR_FINISHED;
+}
+
+void CURVE_OT_set_radius(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Set Curve Radius";
+       ot->idname= "CURVE_OT_set_radius";
+       
+       /* api callbacks */
+       ot->exec= set_radius_exec;
+       ot->poll= ED_operator_editcurve; // XXX nurb poll()
+
+       // XXX invoke popup?
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+       /* properties */
+       RNA_def_float(ot->srna, "radius", 1.0f, 0.0f, FLT_MAX, "Radius", "", 0.0001f, 10.0f);
 }
 
-void smoothNurb(Scene *scene)
+/********************* smooth operator ********************/
+
+static int smooth_exec(bContext *C, wmOperator *op)
 {
-       Object *obedit= scene->obedit; // XXX
+       Object *obedit= CTX_data_edit_object(C);
        ListBase *editnurb= curve_get_editcurve(obedit);
        Nurb *nu;
        BezTriple *bezt, *beztOrig;
        BPoint *bp, *bpOrig;
-       int a, i, change = 0;
-       
-       /* floats for smoothing */
        float val, newval, offset;
+       int a, i, change = 0;
        
        for(nu= editnurb->first; nu; nu= nu->next) {
                if(nu->bezt) {
@@ -1189,14 +1222,33 @@ void smoothNurb(Scene *scene)
                        MEM_freeN(bpOrig);
                }
        }
-       BIF_undo_push("Smooth Curve");
-       DAG_object_flush_update(scene, OBACT, OB_RECALC_DATA);
+
+       DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA);
+       // XXX notifier
+
+       return OPERATOR_FINISHED;
+}
+
+void CURVE_OT_smooth(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Smooth";
+       ot->idname= "CURVE_OT_smooth";
+       
+       /* api callbacks */
+       ot->exec= smooth_exec;
+       ot->poll= ED_operator_editcurve; // XXX nurb poll()
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
+/**************** smooth curve radius operator *************/
+
 /* TODO, make smoothing distance based */
-void smoothradiusNurb(Scene *scene)
+static int smooth_curve_radius_exec(bContext *C, wmOperator *op)
 {
-       Object *obedit= scene->obedit; // XXX
+       Object *obedit= CTX_data_edit_object(C);
        ListBase *editnurb= curve_get_editcurve(obedit);
        Nurb *nu;
        BezTriple *bezt;
@@ -1335,13 +1387,28 @@ void smoothradiusNurb(Scene *scene)
                        }
                }
        }
-       BIF_undo_push("Smooth Curve Radius");
-       DAG_object_flush_update(scene, OBACT, OB_RECALC_DATA);
-}
 
+       DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA);
+       // XXX notifier
+
+       return OPERATOR_FINISHED;
+}
 
+void CURVE_OT_smooth_curve_radius(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Smooth Curve Radius";
+       ot->idname= "CURVE_OT_smooth_curve_radius";
+       
+       /* api clastbacks */
+       ot->exec= smooth_curve_radius_exec;
+       ot->poll= ED_operator_editcurve;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
 
-/* **************** EDIT ************************ */
+/***************** selection utility *************************/
 
 /* next == 1 -> select next            */
 /* next == -1 -> select previous       */
@@ -1406,47 +1473,14 @@ static void select_adjacent_cp(ListBase *editnurb, short next, short cont, short
        }
 }
 
-static short nurb_has_selected_cps(ListBase *editnurb)
-{
-       Nurb *nu;
-       BezTriple *bezt;
-       BPoint *bp;
-       int a;
-
-       for(nu= editnurb->first; nu; nu= nu->next) {
-               if((nu->type & 7)==CU_BEZIER) {
-                       a= nu->pntsu;
-                       bezt= nu->bezt;
-                       while(a--) {
-                               if(bezt->hide==0) {
-                                       if((bezt->f1 & SELECT)
-                                       || (bezt->f2 & SELECT)
-                                       || (bezt->f3 & SELECT)) return 1;
-                               }
-                               bezt++;
-                       }
-               }
-               else {
-                       a= nu->pntsu*nu->pntsv;
-                       bp= nu->bp;
-                       while(a--) {
-                               if((bp->hide==0) && (bp->f1 & SELECT)) return 1;
-                               bp++;
-                       }
-               }
-       }
-       
-       return 0;
-}
-
+/**************** select start/end operators **************/
 
 /* (de)selects first or last of visible part of each Nurb depending on selFirst     */
 /* selFirst: defines the end of which to select                                            */
 /* doswap: defines if selection state of each first/last control point is swapped   */
 /* selstatus: selection status in case doswap is false                             */
-void selectend_nurb(Scene *scene, short selfirst, short doswap, short selstatus)
+void selectend_nurb(Object *obedit, short selfirst, short doswap, short selstatus)
 {
-       Object *obedit= scene->obedit; // XXX use context
        ListBase *editnurb= curve_get_editcurve(obedit);
        Nurb *nu;
        BPoint *bp;
@@ -1497,43 +1531,134 @@ void selectend_nurb(Scene *scene, short selfirst, short doswap, short selstatus)
                        }
                }
        }
+}
+
+static int de_select_first_exec(bContext *C, wmOperator *op)
+{
+       Object *obedit= CTX_data_edit_object(C);
+
+       selectend_nurb(obedit, FIRST, 1, DESELECT);
+       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
 
-       BIF_undo_push("Select/Deselect End");
+       return OPERATOR_FINISHED;
 }
 
-void deselectall_nurb(Scene *scene)
+void CURVE_OT_de_select_first(wmOperatorType *ot)
 {
-       Object *obedit= scene->obedit; // XXX use context
-       ListBase *editnurb= curve_get_editcurve(obedit);
-       View3D *v3d= NULL; // XXX
+       /* identifiers */
+       ot->name= "Select or Deselect First";
+       ot->idname= "CURVE_OT_de_select_first";
        
-       if(!v3d || !(obedit->lay & v3d->lay))
-               return;
+       /* api cfirstbacks */
+       ot->exec= de_select_first_exec;
+       ot->poll= ED_operator_editcurve;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int de_select_last_exec(bContext *C, wmOperator *op)
+{
+       Object *obedit= CTX_data_edit_object(C);
+
+       selectend_nurb(obedit, LAST, 1, DESELECT);
+       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+
+       return OPERATOR_FINISHED;
+}
+
+void CURVE_OT_de_select_last(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Select or Deselect Last";
+       ot->idname= "CURVE_OT_de_select_last";
+       
+       /* api clastbacks */
+       ot->exec= de_select_last_exec;
+       ot->poll= ED_operator_editcurve;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/******************* de select all operator ***************/
+
+static short nurb_has_selected_cps(ListBase *editnurb)
+{
+       Nurb *nu;
+       BezTriple *bezt;
+       BPoint *bp;
+       int a;
 
+       for(nu= editnurb->first; nu; nu= nu->next) {
+               if((nu->type & 7)==CU_BEZIER) {
+                       a= nu->pntsu;
+                       bezt= nu->bezt;
+                       while(a--) {
+                               if(bezt->hide==0) {
+                                       if((bezt->f1 & SELECT)
+                                       || (bezt->f2 & SELECT)
+                                       || (bezt->f3 & SELECT)) return 1;
+                               }
+                               bezt++;
+                       }
+               }
+               else {
+                       a= nu->pntsu*nu->pntsv;
+                       bp= nu->bp;
+                       while(a--) {
+                               if((bp->hide==0) && (bp->f1 & SELECT)) return 1;
+                               bp++;
+                       }
+               }
+       }
+       
+       return 0;
+}
+
+static int de_select_all_exec(bContext *C, wmOperator *op)
+{
+       Object *obedit= CTX_data_edit_object(C);
+       ListBase *editnurb= curve_get_editcurve(obedit);
+       
        if(nurb_has_selected_cps(editnurb)) { /* deselect all */
-               selectend_nurb(scene, FIRST, 0, DESELECT); /* set first control points as unselected */
+               selectend_nurb(obedit, FIRST, 0, DESELECT); /* set first control points as unselected */
                select_adjacent_cp(editnurb, 1, 1, DESELECT); /* cascade selection */   
        }
        else { /* select all */
-               selectend_nurb(scene, FIRST, 0, SELECT); /* set first control points as selected */
+               selectend_nurb(obedit, FIRST, 0, SELECT); /* set first control points as selected */
                select_adjacent_cp(editnurb, 1, 1, SELECT); /* cascade selection */
        }
        
-       BIF_undo_push("Deselect all");
+       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+
+       return OPERATOR_FINISHED;
+}
+
+void CURVE_OT_de_select_all(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Select or Deselect All";
+       ot->idname= "CURVE_OT_de_select_all";
+       
+       /* api callbacks */
+       ot->exec= de_select_all_exec;
+       ot->poll= ED_operator_editcurve;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
-void hideNurb(Scene *scene, int swap)
+/********************** hide operator *********************/
+
+static int hide_exec(bContext *C, wmOperator *op)
 {
-       Object *obedit= scene->obedit; // XXX
+       Object *obedit= CTX_data_edit_object(C);
        ListBase *editnurb= curve_get_editcurve(obedit);
        Nurb *nu;
        BPoint *bp;
        BezTriple *bezt;
-       int a, sel;
-
-       if(obedit==0) return;
-
-       BIF_undo_push("Hide");
+       int a, sel, invert= RNA_boolean_get(op->ptr, "invert");
 
        for(nu= editnurb->first; nu; nu= nu->next) {
                if((nu->type & 7)==CU_BEZIER) {
@@ -1555,11 +1680,11 @@ void hideNurb(Scene *scene, int swap)
                        a= nu->pntsu*nu->pntsv;
                        sel= 0;
                        while(a--) {
-                               if(swap==0 && (bp->f1 & SELECT)) {
+                               if(invert==0 && (bp->f1 & SELECT)) {
                                        select_bpoint(bp, DESELECT, 1, HIDDEN);
                                        bp->hide= 1;
                                }
-                               else if(swap && (bp->f1 & SELECT)==0) {
+                               else if(invert && (bp->f1 & SELECT)==0) {
                                        select_bpoint(bp, DESELECT, 1, HIDDEN);
                                        bp->hide= 1;
                                }
@@ -1570,20 +1695,40 @@ void hideNurb(Scene *scene, int swap)
                }
        }
 
-       DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+       DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA);
+       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+
+       return OPERATOR_FINISHED;       
+}
+
+void CURVE_OT_hide(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Hide Selection";
+       ot->idname= "CURVE_OT_hide";
+       
+       /* api callbacks */
+       ot->exec= hide_exec;
+       ot->poll= ED_operator_editcurve;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+       
+       /* props */
+       RNA_def_boolean(ot->srna, "invert", 0, "Invert", "Hide unselected rather than selected.");
 }
 
-void revealNurb(Scene *scene)
+/********************** reveal operator *********************/
+
+static int reveal_exec(bContext *C, wmOperator *op)
 {
-       Object *obedit= scene->obedit; // XXX
+       Object *obedit= CTX_data_edit_object(C);
        ListBase *editnurb= curve_get_editcurve(obedit);
        Nurb *nu;
        BPoint *bp;
        BezTriple *bezt;
        int a;
 
-       if(obedit==0) return;
-
        for(nu= editnurb->first; nu; nu= nu->next) {
                nu->hide= 0;
                if((nu->type & 7)==CU_BEZIER) {
@@ -1610,22 +1755,37 @@ void revealNurb(Scene *scene)
                }
        }
 
-       DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
-       BIF_undo_push("Reveal");
+       DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA);
+       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+
+       return OPERATOR_FINISHED;       
+}
 
+void CURVE_OT_reveal(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Reveal Hidden";
+       ot->idname= "CURVE_OT_reveal";
+       
+       /* api callbacks */
+       ot->exec= reveal_exec;
+       ot->poll= ED_operator_editcurve;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
-void selectswapNurb(Scene *scene)
+/********************** select invert operator *********************/
+
+static int select_invert_exec(bContext *C, wmOperator *op)
 {
-       Object *obedit= scene->obedit; // XXX
+       Object *obedit= CTX_data_edit_object(C);
        ListBase *editnurb= curve_get_editcurve(obedit);
        Nurb *nu;
        BPoint *bp;
        BezTriple *bezt;
        int a;
 
-       if(obedit==0) return;
-
        for(nu= editnurb->first; nu; nu= nu->next) {
                if((nu->type & 7)==CU_BEZIER) {
                        bezt= nu->bezt;
@@ -1651,10 +1811,27 @@ void selectswapNurb(Scene *scene)
                }
        }
 
-       BIF_undo_push("Select swap");
+       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+
+       return OPERATOR_FINISHED;       
+}
 
+void CURVE_OT_select_invert(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Select Invert";
+       ot->idname= "CURVE_OT_select_invert";
+       
+       /* api callbacks */
+       ot->exec= select_invert_exec;
+       ot->poll= ED_operator_editcurve;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
+/********************** subdivide operator *********************/
+
 /** Divide the line segments associated with the currently selected
  * curve nodes (Bezier or NURB). If there are no valid segment
  * selections within the current selection, nothing happens.
@@ -1663,9 +1840,10 @@ void selectswapNurb(Scene *scene)
  * @return Nothing
  * @param  None
 */
-void subdivideNurb(Scene *scene)
+
+static int subdivide_exec(bContext *C, wmOperator *op)
 {
-       Object *obedit= scene->obedit; // XXX
+       Object *obedit= CTX_data_edit_object(C);
        ListBase *editnurb= curve_get_editcurve(obedit);
        Nurb *nu;
        BezTriple *prevbezt, *bezt, *beztnew, *beztn;
@@ -2030,12 +2208,28 @@ void subdivideNurb(Scene *scene)
        }
 
 
-       DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+       DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA);
+       // XXX notifier WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
 
-       BIF_undo_push("Subdivide");
+       return OPERATOR_FINISHED;       
+}
 
+void CURVE_OT_subdivide(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Subdivide";
+       ot->idname= "CURVE_OT_subdivide";
+       
+       /* api callbacks */
+       ot->exec= subdivide_exec;
+       ot->poll= ED_operator_editcurve;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
+/******************** find nearest ************************/
+
 static void findnearestNurbvert__doClosest(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, int x, int y)
 {
        struct { BPoint *bp; BezTriple *bezt; Nurb *nurb; short dist, hpoint, select, mval[2]; } *data = userData;
@@ -2091,7 +2285,6 @@ static short findnearestNurbvert(ViewContext *vc, short sel, short mval[2], Nurb
        return data.hpoint;
 }
 
-
 static void findselectedNurbvert(ListBase *editnurb, Nurb **nu, BezTriple **bezt, BPoint **bp)
 {
        /* in nu and (bezt or bp) selected are written if there's 1 sel.  */
@@ -2154,7 +2347,9 @@ static void findselectedNurbvert(ListBase *editnurb, Nurb **nu, BezTriple **bezt
        }
 }
 
-int convertspline(short type, Nurb *nu)
+/***************** set spline type operator *******************/
+
+static int convertspline(short type, Nurb *nu)
 {
        BezTriple *bezt;
        BPoint *bp;
@@ -2248,7 +2443,7 @@ int convertspline(short type, Nurb *nu)
                        }
                }
        }
-       else if( (nu->type & 7)==CU_NURBS) {
+       else if((nu->type & 7)==CU_NURBS) {
                if(type==0) {                   /* to Poly */
                        nu->type &= ~7;
                        if(nu->knotsu) MEM_freeN(nu->knotsu); /* python created nurbs have a knotsu of zero */
@@ -2290,33 +2485,105 @@ int convertspline(short type, Nurb *nu)
                        }
                }
        }
+
        return 0;
 }
 
-void setsplinetype(Scene *scene, short type)
+static int set_spline_type_exec(bContext *C, wmOperator *op)
 {
-       Object *obedit= scene->obedit; // XXX
+       Object *obedit= CTX_data_edit_object(C);
        ListBase *editnurb= curve_get_editcurve(obedit);
        Nurb *nu;
+       int changed=0, type= RNA_enum_get(op->ptr, "type");
 
        if(type==CU_CARDINAL || type==CU_BSPLINE) {
-               error("Not implemented yet");
-               return;
+               BKE_report(op->reports, RPT_ERROR, "Not implemented yet");
+               return OPERATOR_CANCELLED;
        }
        
        for(nu= editnurb->first; nu; nu= nu->next) {
                if(isNurbsel(nu)) {
-                       if (convertspline(type, nu))
-                               error("no conversion possible");
+                       if(convertspline(type, nu))
+                               BKE_report(op->reports, RPT_ERROR, "No conversion possible");
+                       else
+                               changed= 1;
                }
        }
-       BIF_undo_push("Set spline type");
-       
+
+       return (changed)? OPERATOR_FINISHED: OPERATOR_CANCELLED;
+}
+
+void CURVE_OT_set_spline_type(wmOperatorType *ot)
+{
+       static EnumPropertyItem type_items[]= {
+               {CU_POLY, "POLY", "Poly", ""},
+               {CU_BEZIER, "BEZIER", "Bezier", ""},
+               {CU_CARDINAL, "CARDINAL", "Cardinal", ""},
+               {CU_BSPLINE, "B_SPLINE", "B-Spline", ""},
+               {CU_NURBS, "NURBS", "NURBS", ""},
+               {0, NULL, NULL, NULL}};
+
+       /* identifiers */
+       ot->name= "Set Spline Type";
+       ot->idname= "CURVE_OT_set_spline_type";
+       
+       /* api callbacks */
+       ot->exec= set_spline_type_exec;
+       ot->poll= ED_operator_editcurve;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+       /* properties */
+       RNA_def_enum(ot->srna, "type", type_items, CU_POLY, "Type", "Spline type");
 }
 
+/***************** XXX make segment operator **********************/
+
 /* ******************** SKINNING LOFTING!!! ******************** */
 
-void rotate_direction_nurb(Nurb *nu)
+static void switchdirection_knots(float *base, int tot)
+{
+       float *fp1, *fp2, *tempf;
+       int a;
+       
+       if(base==NULL || tot==0) return;
+       
+       /* reverse knots */
+       a= tot;
+       fp1= base;
+       fp2= fp1+(a-1);
+       a/= 2;
+       while(fp1!=fp2 && a>0) {
+               SWAP(float, *fp1, *fp2);
+               a--;
+               fp1++; 
+               fp2--;
+       }
+       /* and make in increasing order again */
+       a= tot;
+       fp1= base;
+       fp2=tempf= MEM_mallocN(sizeof(float)*a, "switchdirect");
+       while(a--) {
+               fp2[0]= fabs(fp1[1]-fp1[0]);
+               fp1++;
+               fp2++;
+       }
+
+       a= tot-1;
+       fp1= base;
+       fp2= tempf;
+       fp1[0]= 0.0;
+       fp1++;
+       while(a--) {
+               fp1[0]= fp1[-1]+fp2[0];
+               fp1++;
+               fp2++;
+       }
+       MEM_freeN(tempf);
+}
+
+static void rotate_direction_nurb(Nurb *nu)
 {
        BPoint *bp1, *bp2, *temp;
        int u, v;
@@ -2341,7 +2608,7 @@ void rotate_direction_nurb(Nurb *nu)
        MEM_freeN(temp);
 }
 
-int is_u_selected(Nurb *nu, int u)
+static int is_u_selected(Nurb *nu, int u)
 {
        BPoint *bp;
        int v;
@@ -2355,8 +2622,6 @@ int is_u_selected(Nurb *nu, int u)
        return 0;
 }
 
-/* ******************************** */
-
 typedef struct NurbSort {
        struct NurbSort *next, *prev;
        Nurb *nu;
@@ -2366,7 +2631,7 @@ typedef struct NurbSort {
 static ListBase nsortbase= {0, 0};
 /*  static NurbSort *nusmain; */ /* this var seems to go unused... at least in this file */
 
-void make_selection_list_nurb(ListBase *editnurb)
+static void make_selection_list_nurb(ListBase *editnurb)
 {
        ListBase nbase= {0, 0};
        NurbSort *nus, *nustest, *headdo, *taildo;
@@ -2433,7 +2698,7 @@ void make_selection_list_nurb(ListBase *editnurb)
        }
 }
 
-void merge_2_nurb(ListBase *editnurb, Nurb *nu1, Nurb *nu2)
+static void merge_2_nurb(wmOperator *op, ListBase *editnurb, Nurb *nu1, Nurb *nu2)
 {
        BPoint *bp, *bp1, *bp2, *temp;
        float  len1, len2;
@@ -2485,7 +2750,7 @@ void merge_2_nurb(ListBase *editnurb, Nurb *nu1, Nurb *nu2)
        }
        
        if( nu1->pntsv != nu2->pntsv ) {
-               error("Resolution doesn't match");
+               BKE_report(op->reports, RPT_ERROR, "Resolution doesn't match");
                return;
        }
        
@@ -2549,9 +2814,9 @@ void merge_2_nurb(ListBase *editnurb, Nurb *nu1, Nurb *nu2)
        freeNurb(nu2);
 }
 
-void merge_nurb(Scene *scene)
+static int merge_nurb(bContext *C, wmOperator *op)
 {
-       Object *obedit= scene->obedit; // XXX use context
+       Object *obedit= CTX_data_edit_object(C);
        ListBase *editnurb= curve_get_editcurve(obedit);
        NurbSort *nus1, *nus2;
        int ok= 1;
@@ -2560,8 +2825,8 @@ void merge_nurb(Scene *scene)
        
        if(nsortbase.first == nsortbase.last) {
                BLI_freelistN(&nsortbase);
-               error("Too few selections to merge");
-               return;
+               BKE_report(op->reports, RPT_ERROR, "Too few selections to merge.");
+               return OPERATOR_CANCELLED;
        }
        
        nus1= nsortbase.first;
@@ -2583,13 +2848,13 @@ void merge_nurb(Scene *scene)
        }
        
        if(ok==0) {
-               error("Resolution doesn't match");
+               BKE_report(op->reports, RPT_ERROR, "Resolution doesn't match");
                BLI_freelistN(&nsortbase);
-               return;
+               return OPERATOR_CANCELLED;
        }
        
        while(nus2) {
-               merge_2_nurb(editnurb, nus1->nu, nus2->nu);
+               merge_2_nurb(op, editnurb, nus1->nu, nus2->nu);
                nus2= nus2->next;
        }
        
@@ -2597,17 +2862,19 @@ void merge_nurb(Scene *scene)
        
        set_actNurb(obedit, NULL);
 
-       DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+       DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA);
+       // XXX notifier
 
-       BIF_undo_push("Merge");
+       // XXX BIF_undo_push("Merge");
        
+       return OPERATOR_FINISHED;
 }
 
-
-void addsegment_nurb(Scene *scene)
+static int make_segment_exec(bContext *C, wmOperator *op)
 {
        /* joins 2 curves */
-       Object *obedit= scene->obedit; // XXX
+       Scene *scene= CTX_data_scene(C);
+       Object *obedit= CTX_data_edit_object(C);
        ListBase *editnurb= curve_get_editcurve(obedit);
        Nurb *nu, *nu1=0, *nu2=0;
        BezTriple *bezt;
@@ -2634,10 +2901,9 @@ void addsegment_nurb(Scene *scene)
                }
                nu= nu->next;
        }
-       if(nu) {
-               merge_nurb(scene);
-               return;
-       }
+
+       if(nu)
+               return merge_nurb(C, op);
        
        /* find both nurbs and points, nu1 will be put behind nu2 */
        for(nu= editnurb->first; nu; nu= nu->next) {
@@ -2753,13 +3019,32 @@ void addsegment_nurb(Scene *scene)
                set_actNurb(obedit, NULL);      /* for selected */
 
                DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); 
+               // XXX notifier
 
-               BIF_undo_push("Add segment");
-       
+               return OPERATOR_FINISHED;
+       }
+       else {
+               BKE_report(op->reports, RPT_ERROR, "Can't make segment");
+               return OPERATOR_CANCELLED;
        }
-       else error("Can't make segment");
 }
 
+void CURVE_OT_make_segment(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Make Segment";
+       ot->idname= "CURVE_OT_make_segment";
+       
+       /* api callbacks */
+       ot->exec= make_segment_exec;
+       ot->poll= ED_operator_editcurve; // XXX nurb poll()
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/***************** XXX pick select operator **********************/
+
 void mouse_nurb(bContext *C, short mval[2], int extend)
 {
        Object *obedit= CTX_data_edit_object(C); 
@@ -2823,11 +3108,13 @@ void mouse_nurb(bContext *C, short mval[2], int extend)
        
 }
 
+/***************** XXX spin operator **********************/
+
 /* from what I can gather, the mode==0 magic number spins and bridges the nurbs based on the 
  * orientation of the global 3d view (yuck yuck!) mode==1 does the same, but doesn't bridge up
  * up the new geometry, mode==2 now does the same as 0, but aligned to world axes, not the view.
 */
-static void spin_nurb(Scene *scene, Object *obedit, float *dvec, short mode)
+static int spin_nurb(Scene *scene, Object *obedit, float *dvec, short mode)
 {
        ListBase *editnurb= curve_get_editcurve(obedit);
        RegionView3D *rv3d= NULL; // XXX
@@ -2836,10 +3123,10 @@ static void spin_nurb(Scene *scene, Object *obedit, float *dvec, short mode)
        float *curs, si,phi,n[3],q[4],cmat[3][3],tmat[3][3],imat[3][3];
        float cent[3],bmat[3][3], rotmat[3][3], scalemat1[3][3], scalemat2[3][3];
        float persmat[3][3], persinv[3][3];
-       short a,ok;
+       short a,ok, changed= 0;
        
-       if(v3d==0 || obedit==0 || obedit->type!=OB_SURF) return;
-       if( (v3d->lay & obedit->lay)==0 ) return;
+       if(obedit->type!=OB_SURF)
+               return changed; // XXX poll
 
        if (mode != 2) Mat3CpyMat4(persmat, rv3d->viewmat);
        else Mat3One(persmat);
@@ -2896,11 +3183,13 @@ static void spin_nurb(Scene *scene, Object *obedit, float *dvec, short mode)
 
        for(a=0;a<7;a++) {
                if(mode==0 || mode==2) ok= extrudeflagNurb(editnurb, 1);
-               else adduplicateflagNurb(scene, 1);
-               if(ok==0) {
-                       error("Can't spin");
-                       break;
-               }
+               else adduplicateflagNurb(obedit, 1);
+
+               if(ok==0)
+                       return changed;
+
+               changed= 1;
+
                rotateflagNurb(editnurb, 1,cent,rotmat);
 
                if(mode==0 || mode==2) {
@@ -2928,21 +3217,44 @@ static void spin_nurb(Scene *scene, Object *obedit, float *dvec, short mode)
                        }
                }
        }
-       
+
+       return changed;
+}
+
+static int spin_exec(bContext *C, wmOperator *op)
+{
+       Scene *scene= CTX_data_scene(C);
+       Object *obedit= CTX_data_edit_object(C);
+
+       if(!spin_nurb(scene, obedit, 0, 0)) {
+               BKE_report(op->reports, RPT_ERROR, "Can't spin");
+               return OPERATOR_CANCELLED;
+       }
+
+       DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+       // XXX notifier
+
+       return OPERATOR_FINISHED;
 }
 
-/* external one, for undo */
-void spinNurb(Scene *scene, float *dvec, short mode)
+void CURVE_OT_spin(wmOperatorType *ot)
 {
-       Object *obedit= scene->obedit; // XXX use context
+       /* identifiers */
+       ot->name= "Spin";
+       ot->idname= "CURVE_OT_spin";
+       
+       /* api callbacks */
+       ot->exec= spin_exec;
+       ot->poll= ED_operator_editcurve; // XXX nurb poll()
 
-       spin_nurb(scene, obedit, dvec, mode);
-       BIF_undo_push("Spin");
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
-void addvert_Nurb(Scene *scene, int mode)
+/***************** XXX add vertex operator **********************/
+
+static int addvert_Nurb(Scene *scene, Object *obedit, short mode)
 {
-       Object *obedit= scene->obedit; // XXX use context
        ListBase *editnurb= curve_get_editcurve(obedit);
        View3D *v3d= NULL; // XXX
        Nurb *nu;
@@ -2950,14 +3262,14 @@ void addvert_Nurb(Scene *scene, int mode)
        BPoint *bp, *newbp = NULL;
        float *curs, mat[3][3],imat[3][3], temp[3];
 
-       if(obedit==0 || v3d == 0) return;
-       if( (v3d->lay & obedit->lay)==0 ) return;
+       if(obedit==0 || v3d == 0) return OPERATOR_CANCELLED;
+       if( (v3d->lay & obedit->lay)==0 ) return OPERATOR_CANCELLED;
 
        Mat3CpyMat4(mat, obedit->obmat);
        Mat3Inv(imat,mat);
 
        findselectedNurbvert(editnurb, &nu, &bezt, &bp);
-       if(bezt==0 && bp==0) return;
+       if(bezt==0 && bp==0) return OPERATOR_CANCELLED;
 
        if((nu->type & 7)==CU_BEZIER) {
                /* which bezpoint? */
@@ -3074,41 +3386,87 @@ void addvert_Nurb(Scene *scene, int mode)
                BIF_undo_push("Add vertex");
        
        }
+
+       return OPERATOR_FINISHED;
+}
+
+static int add_vertex_exec(bContext *C, wmOperator *op)
+{
+       Scene *scene= CTX_data_scene(C);
+       Object *obedit= CTX_data_edit_object(C);
+
+       // XXX
+
+       return addvert_Nurb(scene, obedit, 0);
 }
 
-void extrude_nurb(Scene *scene)
+void CURVE_OT_add_vertex(wmOperatorType *ot)
 {
-       Object *obedit= scene->obedit; // XXX
+       /* identifiers */
+       ot->name= "Add Vertex";
+       ot->idname= "CURVE_OT_add_vertex";
+       
+       /* api callbacks */
+       ot->exec= add_vertex_exec;
+       ot->poll= ED_operator_editcurve; // XXX nurb poll()
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/***************** XXX extrude operator **********************/
+
+static int extrude_exec(bContext *C, wmOperator *op)
+{
+       Scene *scene= CTX_data_scene(C);
+       Object *obedit= CTX_data_edit_object(C);
        ListBase *editnurb= curve_get_editcurve(obedit);
        Nurb *nu;
        int ok= 0;
 
-       if(obedit && obedit->type==OB_SURF) {
+       if(obedit->type!=OB_SURF)
+               return OPERATOR_CANCELLED;
 
-               /* first test: curve? */
-               for(nu= editnurb->first; nu; nu= nu->next) {
-                       if(nu->pntsv==1 && isNurbsel_count(nu)==1 ) break;
-               }
-               if(nu) {
-                       addvert_Nurb(scene, 'e');
-               } else {
-                       ok= extrudeflagNurb(editnurb, 1); /* '1'= flag */
-               
-                       if(ok) {
-                               DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
-// XXX                         BIF_TransformSetUndo("Extrude");
-//                             initTransform(TFM_TRANSLATION, CTX_NO_PET);
-//                             Transform();
-                       }
+       /* first test: curve? */
+       for(nu= editnurb->first; nu; nu= nu->next) {
+               if(nu->pntsv==1 && isNurbsel_count(nu)==1 ) break;
+       }
+       if(nu) {
+               addvert_Nurb(scene, obedit, 'e');
+       } else {
+               ok= extrudeflagNurb(editnurb, 1); /* '1'= flag */
+       
+               if(ok) {
+                       DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+                       // XXX notifier
+// XXX         BIF_TransformSetUndo("Extrude");
+//                     initTransform(TFM_TRANSLATION, CTX_NO_PET);
+//                     Transform();
                }
        }
+
+       return OPERATOR_FINISHED;
 }
 
+void CURVE_OT_extrude(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Extrude";
+       ot->idname= "CURVE_OT_extrude";
+       
+       /* api callbacks */
+       ot->exec= extrude_exec;
+       ot->poll= ED_operator_editcurve; // XXX nurb poll()
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
 
+/***************** XXX make cyclic operator **********************/
 
-void makecyclicNurb(Scene *scene)
+static int make_cyclic_exec(bContext *C, wmOperator *op)
 {
-       Object *obedit= scene->obedit; // XXX
+       Object *obedit= CTX_data_edit_object(C);
        ListBase *editnurb= curve_get_editcurve(obedit);
        Nurb *nu;
        BezTriple *bezt;
@@ -3170,8 +3528,8 @@ void makecyclicNurb(Scene *scene)
                        }
                        else if(nu->type==CU_NURBS) {
                                if(cyclmode==0) {
-                                       cyclmode= pupmenu("Toggle %t|cyclic U%x1|cyclic V%x2");
-                                       if(cyclmode < 1) return;
+                                       cyclmode= pupmenu("Toggle %t|cyclic U%x1|cyclic V%x2"); // XXX
+                                       if(cyclmode < 1) return OPERATOR_CANCELLED;
                                }
                                a= nu->pntsu*nu->pntsv;
                                bp= nu->bp;
@@ -3220,12 +3578,31 @@ void makecyclicNurb(Scene *scene)
                        }
                }
        }
-       DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
-       BIF_undo_push("Cyclic");
+
+       DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA);
+
+       return OPERATOR_FINISHED;
+}
+
+void CURVE_OT_make_cyclic(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Make Cyclic";
+       ot->idname= "CURVE_OT_make_cyclic";
+       
+       /* api callbacks */
+       ot->exec= make_cyclic_exec;
+       ot->poll= ED_operator_editcurve; // XXX nurb poll()
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
-void selectconnected_nurb(Scene *scene)
+/***************** XXX select linked operator **********************/
+
+static int select_linked_exec(bContext *C, wmOperator *op)
 {
+       Object *obedit= CTX_data_edit_object(C);
        ViewContext vc;
        Nurb *nu;
        BezTriple *bezt;
@@ -3233,8 +3610,8 @@ void selectconnected_nurb(Scene *scene)
        int a;
        short mval[2], shift= 0; // XXX
        
-       
        findnearestNurbvert(&vc, 1, mval, &nu, &bezt, &bp);
+
        if(bezt) {
                a= nu->pntsu;
                bezt= nu->bezt;
@@ -3254,13 +3631,30 @@ void selectconnected_nurb(Scene *scene)
                }
        }
 
-       BIF_undo_push("Select connected");
+       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+       
+       return OPERATOR_FINISHED;
+}
+
+void CURVE_OT_select_linked(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Select Linked";
+       ot->idname= "CURVE_OT_select_linked";
        
+       /* api callbacks */
+       ot->exec= select_linked_exec;
+       ot->poll= ED_operator_editcurve;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
-void selectrow_nurb(Scene *scene)
+/***************** select row operator **********************/
+
+static int select_row_exec(bContext *C, wmOperator *op)
 {
-       Object *obedit= scene->obedit; // XXX
+       Object *obedit= CTX_data_edit_object(C);
        ListBase *editnurb= curve_get_editcurve(obedit);
        Curve *cu= obedit->data;
        static BPoint *last=0;
@@ -3269,9 +3663,14 @@ void selectrow_nurb(Scene *scene)
        BPoint *bp;
        int u = 0, v = 0, a, b, ok=0;
 
-       if(editnurb->first==0) return;
-       if(obedit==NULL || obedit->type!=OB_SURF) return;
-       if(cu->lastselbp==NULL) return;
+       if(editnurb->first==0)
+               return OPERATOR_CANCELLED;
+
+       if(obedit->type!=OB_SURF)
+               return OPERATOR_CANCELLED; // XXX poll()
+
+       if(cu->lastselbp==NULL)
+               return OPERATOR_CANCELLED;
 
        /* find the correct nurb and toggle with u of v */
        for(nu= editnurb->first; nu; nu= nu->next) {
@@ -3287,6 +3686,7 @@ void selectrow_nurb(Scene *scene)
                        }
                        if(ok) break;
                }
+
                if(ok) {
                        if(last==cu->lastselbp) {
                                direction= 1-direction;
@@ -3305,40 +3705,89 @@ void selectrow_nurb(Scene *scene)
                                        }
                                }
                        }
-                       return;
+
+                       break;
                }
        }
-       BIF_undo_push("Select Row");
        
+       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+
+       return OPERATOR_FINISHED;
 }
 
-void select_next_nurb(Scene *scene)
+void CURVE_OT_select_row(wmOperatorType *ot)
 {
-       Object *obedit= scene->obedit; // XXX use context
-       ListBase *editnurb= curve_get_editcurve(obedit);
+       /* identifiers */
+       ot->name= "Select Control Point Row";
+       ot->idname= "CURVE_OT_select_row";
        
-       if(obedit==0) return;
+       /* api callbacks */
+       ot->exec= select_row_exec;
+       ot->poll= ED_operator_editcurve;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/***************** select next operator **********************/
+
+static int select_next_exec(bContext *C, wmOperator *op)
+{
+       Object *obedit= CTX_data_edit_object(C);
+       ListBase *editnurb= curve_get_editcurve(obedit);
        
        select_adjacent_cp(editnurb, 1, 0, SELECT);
+       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+
+       return OPERATOR_FINISHED;
+}
+
+void CURVE_OT_select_next(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Select Next";
+       ot->idname= "CURVE_OT_select_next";
        
-       BIF_undo_push("Select Next");
+       /* api callbacks */
+       ot->exec= select_next_exec;
+       ot->poll= ED_operator_editcurve;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
-void select_prev_nurb(Scene *scene)
+/***************** select previous operator **********************/
+
+static int select_previous_exec(bContext *C, wmOperator *op)
 {
-       Object *obedit= scene->obedit; // XXX use context
+       Object *obedit= CTX_data_edit_object(C);
        ListBase *editnurb= curve_get_editcurve(obedit);
        
-       if(obedit==NULL) return;
-       
        select_adjacent_cp(editnurb, -1, 0, SELECT);
+       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+
+       return OPERATOR_FINISHED;
+}
+
+void CURVE_OT_select_previous(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Select Previous";
+       ot->idname= "CURVE_OT_select_previous";
        
-       BIF_undo_push("Select Previous");
+       /* api callbacks */
+       ot->exec= select_previous_exec;
+       ot->poll= ED_operator_editcurve;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
-void select_more_nurb(Scene *scene)
+/***************** select more operator **********************/
+
+static int select_more_exec(bContext *C, wmOperator *op)
 {
-       Object *obedit= scene->obedit; // XXX
+       Object *obedit= CTX_data_edit_object(C);
        ListBase *editnurb= curve_get_editcurve(obedit);
        Nurb *nu;
        BPoint *bp, *tempbp;
@@ -3346,8 +3795,6 @@ void select_more_nurb(Scene *scene)
        short sel= 0;
        short *selbpoints;
        
-       if(obedit==0) return;
-       
        /* note that NURBS surface is a special case because we mimic */
        /* the behaviour of "select more" of mesh tools.              */
        /* The algorithm is designed to work in planar cases so it    */
@@ -3404,13 +3851,31 @@ void select_more_nurb(Scene *scene)
                select_adjacent_cp(editnurb, -1, 0, SELECT);
        }
                
-       BIF_undo_push("Select More");
+       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+
+       return OPERATOR_FINISHED;
+}
+
+void CURVE_OT_select_more(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Select More";
+       ot->idname= "CURVE_OT_select_more";
+       
+       /* api callbacks */
+       ot->exec= select_more_exec;
+       ot->poll= ED_operator_editcurve;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
+/******************** select less operator *****************/
+
 /* basic method: deselect if control point doesn't have all neighbours selected */
-void select_less_nurb(Scene *scene)
+static int select_less_exec(bContext *C, wmOperator *op)
 {
-       Object *obedit= scene->obedit; // XXX
+       Object *obedit= CTX_data_edit_object(C);
        ListBase *editnurb= curve_get_editcurve(obedit);
        Nurb *nu;
        BPoint *bp;
@@ -3418,8 +3883,6 @@ void select_less_nurb(Scene *scene)
        int a;
        short sel= 0, lastsel= 0;
        short *selbpoints;
-
-       if(obedit==0) return;
        
        if(obedit->type==OB_SURF) {             
                for(nu= editnurb->first; nu; nu= nu->next) {
@@ -3549,9 +4012,27 @@ void select_less_nurb(Scene *scene)
                }
        }
        
-       BIF_undo_push("Select Less");
+       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+
+       return OPERATOR_FINISHED;
+}
+
+void CURVE_OT_select_less(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Select Less";
+       ot->idname= "CURVE_OT_select_less";
+       
+       /* api callbacks */
+       ot->exec= select_less_exec;
+       ot->poll= ED_operator_editcurve;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
+/********************** select random *********************/
+
 /* this function could be moved elsewhere as it can be reused in other parts of the source needing randomized list */
 /* returns list containing -1 in indices that have been left out of the list. otherwise index contains reference   */
 /* to next index. basically *list contains a linked list                                                          */
@@ -3584,26 +4065,23 @@ static void generate_pickable_list(int *list, int size, int pickamount)
        }
 }
 
-void select_random_nurb(Scene *scene)
+static int select_random_exec(bContext *C, wmOperator *op)
 {
-       Object *obedit= scene->obedit; // XXX
+       Object *obedit= CTX_data_edit_object(C);
        ListBase *editnurb= curve_get_editcurve(obedit);
        Nurb *nu;
        BezTriple *bezt;
        BPoint *bp;
-       static short randfac= 50;
+       float percent= RNA_float_get(op->ptr, "percent");
        int amounttoselect, amountofcps, a, i, k= 0;
        int *itemstobeselected;
-       
-       if(!obedit) return;
-
-       if(!button(&randfac,0, 100,"Percentage:")) return;
 
-       if(randfac == 0) return;
+       if(percent == 0.0f)
+               return OPERATOR_CANCELLED;
        
        amountofcps= count_curveverts_without_handles(editnurb);
        itemstobeselected= MEM_callocN(sizeof(int) * amountofcps, "selectitems");
-       amounttoselect= floor(randfac * amountofcps / 100 + 0.5);
+       amounttoselect= floor(percent * amountofcps + 0.5);
        generate_pickable_list(itemstobeselected, amountofcps, amounttoselect);
        
        /* select elements */
@@ -3630,69 +4108,117 @@ void select_random_nurb(Scene *scene)
                
        MEM_freeN(itemstobeselected);
 
-       BIF_undo_push("Select Random"); 
+       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+
+       return OPERATOR_FINISHED;
 }
 
-void select_every_nth_nurb(Scene *scene)
+void CURVE_OT_select_random(wmOperatorType *ot)
 {
-       Object *obedit= scene->obedit; // XXX use context
-       ListBase *editnurb= curve_get_editcurve(obedit);
-       static short nfac= 2;
-               
-       if(!obedit) return;
+       /* identifiers */
+       ot->name= "Select Random";
+       ot->idname= "CURVE_OT_select_random";
+       
+       /* api callbacks */
+       ot->exec= select_random_exec;
+       ot->poll= ED_operator_editcurve;
+       
+       // XXX invoke popup?
 
-       if(!button(&nfac, 2, 25,"N:")) return;
-                                               
-       select_adjacent_cp(editnurb, nfac, 1, SELECT);
-       select_adjacent_cp(editnurb, -nfac, 1, SELECT);
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+       /* properties */
+       RNA_def_float(ot->srna, "percent", 0.5f, 0.0f, 1.0f, "Percent", "Percentage of vertices to select randomly.", 0.0001f, 1.0f);
+}
+
+/********************** select every nth *********************/
+
+static int select_every_nth_exec(bContext *C, wmOperator *op)
+{
+       Object *obedit= CTX_data_edit_object(C);
+       ListBase *editnurb= curve_get_editcurve(obedit);
+       int n= RNA_int_get(op->ptr, "n");
+       
+       select_adjacent_cp(editnurb, n, 1, SELECT);
+       select_adjacent_cp(editnurb, -n, 1, SELECT);
        
-       BIF_undo_push("Select Every Nth");      
+       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+
+       return OPERATOR_FINISHED;
 }
 
-void adduplicate_nurb(Scene *scene)
+void CURVE_OT_select_every_nth(wmOperatorType *ot)
 {
-       Object *obedit= scene->obedit; // XXX use context
-       View3D *v3d= NULL; // XXX
+       /* identifiers */
+       ot->name= "Select Every Nth";
+       ot->idname= "CURVE_OT_select_every_nth";
+       
+       /* api callbacks */
+       ot->exec= select_every_nth_exec;
+       ot->poll= ED_operator_editcurve;
+
+       // XXX invoke popup?
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 
-       if(v3d==0 || (v3d->lay & obedit->lay)==0 ) return;
+       /* properties */
+       RNA_def_int(ot->srna, "n", 2, 2, INT_MAX, "N", "Select every Nth element", 2, 25);
+}
+
+/********************** add duplicate operator *********************/
+
+static int add_duplicate_exec(bContext *C, wmOperator *op)
+{
+       Object *obedit= CTX_data_edit_object(C);
 
-       adduplicateflagNurb(scene, 1);
+       adduplicateflagNurb(obedit, 1);
 
 // XXX BIF_TransformSetUndo("Add Duplicate");
 //     initTransform(TFM_TRANSLATION, CTX_NO_PET);
 //     Transform();
+       
+       return OPERATOR_FINISHED;
 }
 
-void delNurb(Scene *scene)
+void CURVE_OT_add_duplicate(wmOperatorType *ot)
 {
-       Object *obedit= scene->obedit; // XXX
+       /* identifiers */
+       ot->name= "Add Duplicate";
+       ot->idname= "CURVE_OT_add_duplicate";
+       
+       /* api callbacks */
+       ot->exec= add_duplicate_exec;
+       ot->poll= ED_operator_editcurve;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/********************** delete operator *********************/
+
+static int delete_exec(bContext *C, wmOperator *op)
+{
+       Scene *scene= CTX_data_scene(C);
+       Object *obedit= CTX_data_edit_object(C);
        ListBase *editnurb= curve_get_editcurve(obedit);
-       View3D *v3d= NULL; // XXX
        Nurb *nu, *next, *nu1;
        BezTriple *bezt, *bezt1, *bezt2;
        BPoint *bp, *bp1, *bp2;
-       int a;
-       short event, cut = 0;
-
-       if(obedit==0 ) return;
-       if(v3d==0 || (v3d->lay & obedit->lay)==0 ) return;
-
-       if(obedit->type==OB_SURF) event= pupmenu("Erase %t|Selected%x0|All%x2");
-       else event= pupmenu("Erase %t|Selected%x0|Segment%x1|All%x2");
-
-       if(event== -1) return;
+       int a, cut= 0, type= RNA_enum_get(op->ptr, "type");
 
        if(obedit->type==OB_SURF) {
-               if(event==0) deleteflagNurb(scene, 1);
+               if(type==0) deleteflagNurb(C, op, 1);
                else freeNurblist(editnurb);
 
+               // XXX notifier
                DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
-               BIF_undo_push("Delete");
        
-               return;
+               return OPERATOR_FINISHED;
        }
 
-       if(event==0) {
+       if(type==0) {
                /* first loop, can we remove entire pieces? */
                nu= editnurb->first;
                while(nu) {
@@ -3743,7 +4269,7 @@ void delNurb(Scene *scene)
                nu= editnurb->first;
                while(nu) {
                        next= nu->next;
-                       event= 0;
+                       type= 0;
                        if( (nu->type & 7)==CU_BEZIER ) {
                                bezt= nu->bezt;
                                for(a=0;a<nu->pntsu;a++) {
@@ -3751,11 +4277,11 @@ void delNurb(Scene *scene)
                                                memmove(bezt, bezt+1, (nu->pntsu-a-1)*sizeof(BezTriple));
                                                nu->pntsu--;
                                                a--;
-                                               event= 1;
+                                               type= 1;
                                        }
                                        else bezt++;
                                }
-                               if(event) {
+                               if(type) {
                                        bezt1 =
                                                (BezTriple*)MEM_mallocN((nu->pntsu) * sizeof(BezTriple), "delNurb");
                                        memcpy(bezt1, nu->bezt, (nu->pntsu)*sizeof(BezTriple) );
@@ -3772,13 +4298,13 @@ void delNurb(Scene *scene)
                                                memmove(bp, bp+1, (nu->pntsu-a-1)*sizeof(BPoint));
                                                nu->pntsu--;
                                                a--;
-                                               event= 1;
+                                               type= 1;
                                        }
                                        else {
                                                bp++;
                                        }
                                }
-                               if(event) {
+                               if(type) {
                                        bp1 = (BPoint*)MEM_mallocN(nu->pntsu * sizeof(BPoint), "delNurb2");
                                        memcpy(bp1, nu->bp, (nu->pntsu)*sizeof(BPoint) );
                                        MEM_freeN(nu->bp);
@@ -3796,7 +4322,7 @@ void delNurb(Scene *scene)
                        nu= next;
                }
        }
-       else if(event==1) {     /* erase segment */
+       else if(type==1) {      /* erase segment */
                /* find the 2 selected points */
                bezt1= bezt2= 0;
                bp1= bp2= 0;
@@ -3820,7 +4346,7 @@ void delNurb(Scene *scene)
                                                                        BIF_undo_push("Delete");
                                                                }
                                                        }
-                                                       return;
+                                                       return OPERATOR_FINISHED; //XXX
                                                }
                                                cut= a;
                                                nu1= nu;
@@ -3845,7 +4371,7 @@ void delNurb(Scene *scene)
                                                                        BIF_undo_push("Delete");
                                                                }
                                                        }
-                                                       return;
+                                                       return OPERATOR_FINISHED; // XXX
                                                }
                                                cut= a;
                                                nu1= nu;
@@ -3935,39 +4461,106 @@ void delNurb(Scene *scene)
                        }
                }
        }
-       else if(event==2) {
+       else if(type==2)
                freeNurblist(editnurb);
-       }
 
        DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
-
-       BIF_undo_push("Delete");
+       // XXX notifier
        
+       return OPERATOR_FINISHED;
 }
 
-void nurb_set_smooth(Scene *scene, short event)
+static int delete_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {
-       Object *obedit= scene->obedit; // XXX
+       Object *obedit= CTX_data_edit_object(C);
+       uiMenuItem *head;
+
+       if(obedit->type==OB_SURF) {
+               head= uiPupMenuBegin("Delete", 0);
+               uiMenuItemEnumO(head, "", 0, op->idname, "type", 0);
+               uiMenuItemEnumO(head, "", 0, op->idname, "type", 2);
+               uiPupMenuEnd(C, head);
+       }
+       else {
+               head= uiPupMenuBegin("Delete", 0);
+               uiMenuItemsEnumO(head, op->idname, "type");
+               uiPupMenuEnd(C, head);
+       }
+
+       return OPERATOR_CANCELLED;
+}
+
+void CURVE_OT_delete(wmOperatorType *ot)
+{
+       static EnumPropertyItem type_items[] = {
+               {0, "SELECTED", "Selected", ""},
+               {1, "SEGMENT", "Segment", ""},
+               {2, "ALL", "All", ""},
+               {0, NULL, NULL, NULL}};
+
+       /* identifiers */
+       ot->name= "Delete";
+       ot->idname= "CURVE_OT_delete";
+       
+       /* api callbacks */
+       ot->exec= delete_exec;
+       ot->invoke= delete_invoke;
+       ot->poll= ED_operator_editcurve;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+       /* properties */
+       RNA_def_enum(ot->srna, "type", type_items, 0, "Type", "Which elements to delete.");
+}
+
+/********************** set smooth operator *********************/
+
+static int set_smooth_exec(bContext *C, wmOperator *op)
+{
+       Object *obedit= CTX_data_edit_object(C);
        ListBase *editnurb= curve_get_editcurve(obedit);
        Nurb *nu;
+       int disable= RNA_boolean_get(op->ptr, "disable");
        
-       if(obedit==0) return;
-       
-       if(obedit->type != OB_CURVE) return;
+       if(obedit->type != OB_CURVE)
+               return OPERATOR_CANCELLED;
        
        for(nu= editnurb->first; nu; nu= nu->next) {
                if(isNurbsel(nu)) {
-                       if(event==1) nu->flag |= CU_SMOOTH;
-                       else if(event==0) nu->flag &= ~CU_SMOOTH;
+                       if(!disable) nu->flag |= CU_SMOOTH;
+                       else nu->flag &= ~CU_SMOOTH;
                }
        }
        
-       DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+       // XXX notifier
+       DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA);
        
-       if(event==1) BIF_undo_push("Set Smooth");
-       else if(event==0) BIF_undo_push("Set Solid");
+       // XXX if(event==1) BIF_undo_push("Set Smooth");
+       // XXX else if(event==0) BIF_undo_push("Set Solid");
+
+       return OPERATOR_FINISHED;
 }
 
+void CURVE_OT_set_smooth(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Set Smooth";
+       ot->idname= "CURVE_OT_set_smooth";
+       
+       /* api callbacks */
+       ot->exec= set_smooth_exec;
+       ot->poll= ED_operator_editcurve;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+       /* properties */
+       RNA_def_boolean(ot->srna, "disable", 0, "Disable", "Disable smooth shading for selection instead of enabling it.");
+}
+
+/********************* XXX join operator ***********************/
+
 int join_curve(Scene *scene, int type)
 {
        View3D *v3d= NULL; // XXX
@@ -4052,6 +4645,8 @@ int join_curve(Scene *scene, int type)
        return 1;
 }
 
+/***************** XXX add primitive operator ********************/
+
 Nurb *addNurbprim(bContext *C, int type, int newname)
 {
        static int xzproj= 0;   /* this function calls itself... */
@@ -4454,54 +5049,17 @@ Nurb *addNurbprim(bContext *C, int type, int newname)
        return nu;
 }
 
-void default_curve_ipo(Scene *scene, Curve *cu)
-{
-#if 0 // XXX old animation system
-       IpoCurve *icu;
-       BezTriple *bezt;
-       
-       if(cu->ipo) return;
-       
-       cu->ipo= add_ipo(scene, "CurveIpo", ID_CU);
-       
-       icu= MEM_callocN(sizeof(IpoCurve), "ipocurve");
-                       
-       icu->blocktype= ID_CU;
-       icu->adrcode= CU_SPEED;
-       icu->flag= IPO_VISIBLE|IPO_SELECT|IPO_AUTO_HORIZ;
-       set_icu_vars(icu);
-       
-       BLI_addtail( &(cu->ipo->curve), icu);
-       
-       icu->bezt= bezt= MEM_callocN(2*sizeof(BezTriple), "defaultipo");
-       icu->totvert= 2;
-       
-       bezt->hide= IPO_BEZ;
-       bezt->f1=bezt->f2= bezt->f3= SELECT;
-       bezt->h1= bezt->h2= HD_AUTO;
-       bezt++;
-       bezt->vec[1][0]= 100.0;
-       bezt->vec[1][1]= 1.0;
-       bezt->hide= IPO_BEZ;
-       bezt->f1=bezt->f2= bezt->f3= SELECT;
-       bezt->h1= bezt->h2= HD_AUTO;
-       
-       calchandles_ipocurve(icu);
-#endif // XXX old animation system
-}
-
+/***************** clear tilt operator ********************/
 
-void clear_tilt(Scene *scene)
+static int clear_tilt_exec(bContext *C, wmOperator *op)
 {
-       Object *obedit= scene->obedit; // XXX
+       Object *obedit= CTX_data_edit_object(C);
        ListBase *editnurb= curve_get_editcurve(obedit);
        Nurb *nu;
        BezTriple *bezt;
        BPoint *bp;
        int a;
 
-       if(okee("Clear tilt")==0) return;
-
        for(nu= editnurb->first; nu; nu= nu->next) {
                if( nu->bezt ) {
                        bezt= nu->bezt;
@@ -4521,37 +5079,27 @@ void clear_tilt(Scene *scene)
                }
        }
 
-       DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
-       BIF_undo_push("Clear tilt");
-       
+       // XXX notifier WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_TRANSFORM, obedit);
+       DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA);
+
+       return OPERATOR_FINISHED;
 }
 
-int bezt_compare (const void *e1, const void *e2)
+void CURVE_OT_clear_tilt(wmOperatorType *ot)
 {
-       BezTriple *b1 = *((BezTriple**)e1);
-       BezTriple *b2 = *((BezTriple**)e2);
-
-       /* Check numerical values */
-       float val = b1->vec[1][0] - b2->vec[1][0];
-
-       if (val<0)
-               return -1;
-
-       if (val>0)
-               return 1;
-
-       /* Check selected flags : Ensures that selected keys will be listed first */
-
-       if ((b1->f2 & SELECT) && !(b2->f2 & SELECT))
-               return -1;
-       if (!(b1->f2 & SELECT) && (b2->f2 & SELECT))
-               return 1;
-
-       return 0;
+       /* identifiers */
+       ot->name= "Clear Tilt";
+       ot->idname= "CURVE_OT_clear_tilt";
+       
+       /* api callbacks */
+       ot->exec= clear_tilt_exec;
+       ot->poll= ED_operator_editcurve;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
-
-/* **************** undo for curves ************** */
+/****************** undo for curves ****************/
 
 static void undoCurve_to_editCurve(void *lbu, void *lbe)
 {
@@ -4604,6 +5152,41 @@ void undo_push_curve(bContext *C, char *name)
        undo_editmode_push(C, name, get_data, free_undoCurve, undoCurve_to_editCurve, editCurve_to_undoCurve, NULL);
 }
 
+/***************** XXX old cruft ********************/
 
+void default_curve_ipo(Scene *scene, Curve *cu)
+{
+#if 0 // XXX old animation system
+       IpoCurve *icu;
+       BezTriple *bezt;
+       
+       if(cu->ipo) return;
+       
+       cu->ipo= add_ipo(scene, "CurveIpo", ID_CU);
+       
+       icu= MEM_callocN(sizeof(IpoCurve), "ipocurve");
+                       
+       icu->blocktype= ID_CU;
+       icu->adrcode= CU_SPEED;
+       icu->flag= IPO_VISIBLE|IPO_SELECT|IPO_AUTO_HORIZ;
+       set_icu_vars(icu);
+       
+       BLI_addtail( &(cu->ipo->curve), icu);
+       
+       icu->bezt= bezt= MEM_callocN(2*sizeof(BezTriple), "defaultipo");
+       icu->totvert= 2;
+       
+       bezt->hide= IPO_BEZ;
+       bezt->f1=bezt->f2= bezt->f3= SELECT;
+       bezt->h1= bezt->h2= HD_AUTO;
+       bezt++;
+       bezt->vec[1][0]= 100.0;
+       bezt->vec[1][1]= 1.0;
+       bezt->hide= IPO_BEZ;
+       bezt->f1=bezt->f2= bezt->f3= SELECT;
+       bezt->h1= bezt->h2= HD_AUTO;
+       
+       calchandles_ipocurve(icu);
+#endif // XXX old animation system
+}
 
-/***/
index bd878946bb95a293ffd3d7f21349059939b793b5..d98d5731236b979f85061690b417e82a7c685d41 100644 (file)
@@ -2661,7 +2661,7 @@ void MESH_OT_hide(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
        
        /* props */
-       RNA_def_boolean(ot->srna, "invert", 0, "Invert", "");
+       RNA_def_boolean(ot->srna, "invert", 0, "Invert", "Hide unselected rather than selected.");
 }
 
 void EM_reveal_mesh(EditMesh *em)
@@ -3167,7 +3167,7 @@ void EM_select_swap(EditMesh *em) /* exported for UV */
 
 }
 
-static int selectswap_mesh_exec(bContext *C, wmOperator *op)
+static int select_invert_mesh_exec(bContext *C, wmOperator *op)
 {
        Object *obedit= CTX_data_edit_object(C);
        EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
@@ -3181,11 +3181,11 @@ static int selectswap_mesh_exec(bContext *C, wmOperator *op)
 void MESH_OT_select_invert(wmOperatorType *ot)
 {
        /* identifiers */
-       ot->name= "Select Swap";
+       ot->name= "Select Invert";
        ot->idname= "MESH_OT_select_invert";
        
        /* api callbacks */
-       ot->exec= selectswap_mesh_exec;
+       ot->exec= select_invert_mesh_exec;
        ot->poll= ED_operator_editmesh;
        
        /* flags */
@@ -3388,7 +3388,7 @@ static void selectrandom_mesh(EditMesh *em, float perc) /* randomly selects a us
        EditVert *eve;
        EditEdge *eed;
        EditFace *efa;
-       float randfac= perc/100.0f;
+       float randfac= perc;
        /* Get the percentage of vertices to randomly select as 'randfac' */
 // XXX if(button(&randfac,0, 100,"Percentage:")==0) return;
 
@@ -3451,7 +3451,7 @@ void MESH_OT_select_random(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/;
        
        /* props */
-       RNA_def_float(ot->srna, "percent", 50.0f, 0.0f, 100.0f, "Percent", "percentage of mesh data to randomly select", 0.01f, 100.0f);
+       RNA_def_float(ot->srna, "percent", 0.5f, 0.0f, 1.0f, "Percent", "Percentage of vertices to select randomly.", 0.0001f, 1.0f);
 }
 
 void editmesh_select_by_material(EditMesh *em, int index) 
index 7830d4d0ae8423bfc3422c89a4ea49da88c6a1b4..03b2c6fe983a8725bad346c95738aa4778bd726e 100644 (file)
@@ -1170,7 +1170,7 @@ static int delete_mesh_exec(bContext *C, wmOperator *op)
 void MESH_OT_delete(wmOperatorType *ot)
 {
        /* identifiers */
-       ot->name= "Delete Mesh";
+       ot->name= "Delete";
        ot->idname= "MESH_OT_delete";
        
        /* api callbacks */
@@ -6672,7 +6672,7 @@ void MESH_OT_subdivide_smooth(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
        
        /* props */
-       RNA_def_float(ot->srna, "smoothness", 5.0f, 0.0f, 1000.0f, "Smoothness", "", 0.0f, FLT_MAX);
+       RNA_def_float(ot->srna, "smoothness", 1.0f, 0.0f, 1000.0f, "Smoothness", "", 0.0f, FLT_MAX);
 }
 
 static int subdivs_invoke(bContext *C, wmOperator *op, wmEvent *event)
@@ -6735,7 +6735,7 @@ void MESH_OT_subdivs(wmOperatorType *ot)
        /* this is temp, the ops are different, but they are called from subdivs, so all the possible props should be here as well*/
        RNA_def_int(ot->srna, "number_cuts", 4, 1, 10, "Number of Cuts", "", 1, INT_MAX);
        RNA_def_float(ot->srna, "random_factor", 5.0, 0.0f, FLT_MAX, "Random Factor", "", 0.0f, 1000.0f);
-       RNA_def_float(ot->srna, "smoothness", 5.0f, 0.0f, 1000.0f, "Smoothness", "", 0.0f, FLT_MAX);
+       RNA_def_float(ot->srna, "smoothness", 1.0f, 0.0f, 1000.0f, "Smoothness", "", 0.0f, FLT_MAX);
                
 }
 
index 6cd06faab68d879333ba494625ad1a3d0bf828be..2225be4eda8907c815232bce88130e68fb1d01ec 100644 (file)
@@ -238,6 +238,9 @@ int ED_operator_editcurve(bContext *C)
        if(obedit && obedit->type==OB_CURVE)
                return NULL != ((Mesh *)obedit->data)->edit_mesh;
        return 0;
+
+       // XXX this test was in many tools, still needed?
+       // if(v3d==0 || (v3d->lay & obedit->lay)==0 ) return 0;
 }
 
 
index ebe8341ffc5231839e74159059f605b7fcbdf292..0a87940d9179ddf665ba11686327a34e500d7a12 100644 (file)
@@ -1338,8 +1338,6 @@ TransDataCurveHandleFlags *initTransDataCurveHandes(TransData *td, struct BezTri
 
 static void createTransCurveVerts(bContext *C, TransInfo *t)
 {
-       // TRANSFORM_FIX_ME
-#if 0
        Object *obedit= CTX_data_edit_object(C);
        Curve *cu= obedit->data;
        TransData *td = NULL;
@@ -1542,7 +1540,6 @@ static void createTransCurveVerts(bContext *C, TransInfo *t)
                                calc_distanceCurveVerts(head, tail-1);
                }
        }
-#endif
 }
 
 /* ********************* lattice *************** */
index 0a0b6e6f07a6360cd65f841c9a97f79a8fc3029c..b1387d7d50443662c6aa96ed2b647af7e17e2a06 100644 (file)
@@ -351,41 +351,12 @@ void recalcData(TransInfo *t)
                        }
                }
        }
-       else if (t->obedit) {
-               if ELEM(t->obedit->type, OB_CURVE, OB_SURF) {
-                       Curve *cu= t->obedit->data;
-                       Nurb *nu= cu->editnurb->first;
-                       
-                       DAG_object_flush_update(G.scene, t->obedit, OB_RECALC_DATA);  /* sets recalc flags */
-                       
-                       if (t->state == TRANS_CANCEL) {
-                               while(nu) {
-                                       calchandlesNurb(nu); /* Cant do testhandlesNurb here, it messes up the h1 and h2 flags */
-                                       nu= nu->next;
-                               }
-                       } else {
-                               /* Normal updating */
-                               while(nu) {
-                                       test2DNurb(nu);
-                                       calchandlesNurb(nu);
-                                       nu= nu->next;
-                               }
-                               retopo_do_all();
-                       }
-               }
-               else if(t->obedit->type==OB_LATTICE) {
-                       DAG_object_flush_update(G.scene, t->obedit, OB_RECALC_DATA);  /* sets recalc flags */
-                       
-                       if(editLatt->flag & LT_OUTSIDE) outside_lattice(editLatt);
-               }
-               else {
-                       DAG_object_flush_update(G.scene, t->obedit, OB_RECALC_DATA);  /* sets recalc flags */
-               }
+#endif
+       if (t->obedit) {
        }
        else if(G.f & G_PARTICLEEDIT) {
                flushTransParticles(t);
        }
-#endif
        if (t->spacetype==SPACE_NODE) {
                flushTransNodes(t);
        }
@@ -446,7 +417,35 @@ void recalcData(TransInfo *t)
                }
        }
        else if (t->obedit) {
-               if (t->obedit->type == OB_MESH) {
+               if ELEM(t->obedit->type, OB_CURVE, OB_SURF) {
+                       Curve *cu= t->obedit->data;
+                       Nurb *nu= cu->editnurb->first;
+                       
+                       DAG_object_flush_update(scene, t->obedit, OB_RECALC_DATA);  /* sets recalc flags */
+                       
+                       if (t->state == TRANS_CANCEL) {
+                               while(nu) {
+                                       calchandlesNurb(nu); /* Cant do testhandlesNurb here, it messes up the h1 and h2 flags */
+                                       nu= nu->next;
+                               }
+                       } else {
+                               /* Normal updating */
+                               while(nu) {
+                                       test2DNurb(nu);
+                                       calchandlesNurb(nu);
+                                       nu= nu->next;
+                               }
+                               /* TRANSFORM_FIX_ME */
+                               // retopo_do_all();
+                       }
+               }
+               else if(t->obedit->type==OB_LATTICE) {
+                       Lattice *la= t->obedit->data;
+                       DAG_object_flush_update(scene, t->obedit, OB_RECALC_DATA);  /* sets recalc flags */
+                       
+                       if(la->editlatt->flag & LT_OUTSIDE) outside_lattice(la->editlatt);
+               }
+               else if (t->obedit->type == OB_MESH) {
                        if(t->spacetype==SPACE_IMAGE) {
                                SpaceImage *sima= t->sa->spacedata.first;
 
@@ -454,7 +453,7 @@ void recalcData(TransInfo *t)
                                if(sima->flag & SI_LIVE_UNWRAP)
                                        ED_uvedit_live_unwrap_re_solve();
        
-                               DAG_object_flush_update(t->scene, t->obedit, OB_RECALC_DATA);
+                               DAG_object_flush_update(scene, t->obedit, OB_RECALC_DATA);
                        } else {
                                EditMesh *em = ((Mesh*)t->obedit->data)->edit_mesh;
                                /* mirror modifier clipping? */
@@ -466,10 +465,10 @@ void recalcData(TransInfo *t)
 //                                     }
                                        clipMirrorModifier(t, t->obedit);
                                }
-                               if((t->options & CTX_NO_MIRROR) == 0 && (t->scene->toolsettings->editbutflag & B_MESH_X_MIRROR))
+                               if((t->options & CTX_NO_MIRROR) == 0 && (scene->toolsettings->editbutflag & B_MESH_X_MIRROR))
                                        editmesh_apply_to_mirror(t);
                                
-                               DAG_object_flush_update(t->scene, t->obedit, OB_RECALC_DATA);  /* sets recalc flags */
+                               DAG_object_flush_update(scene, t->obedit, OB_RECALC_DATA);  /* sets recalc flags */
                                
                                recalc_editnormals(em);
                        }
@@ -552,6 +551,8 @@ void recalcData(TransInfo *t)
                                transform_armature_mirror_update(t->obedit);
                        
                }
+               else
+                       DAG_object_flush_update(scene, t->obedit, OB_RECALC_DATA);  /* sets recalc flags */
        }
        else if( (t->flag & T_POSE) && t->poseobj) {
                Object *ob= t->poseobj;