rename operators TFM_OT_* --> TRANSFORM_OT_*
[blender.git] / source / blender / editors / mesh / editmesh_mods.c
index a1f8b3251c8ba8ed5ca0a142d1e65e8dbf9be3d7..30dc61140979cdd2571b680bc39de60ea62d3c03 100644 (file)
@@ -39,7 +39,7 @@ editmesh_mods.c, UI level access, no geometry changes
 
 #include "MEM_guardedalloc.h"
 
-#include "MTC_matrixops.h"
+
 
 #include "DNA_mesh_types.h"
 #include "DNA_material_types.h"
@@ -53,7 +53,7 @@ editmesh_mods.c, UI level access, no geometry changes
 #include "DNA_view3d_types.h"
 
 #include "BLI_blenlib.h"
-#include "BLI_arithb.h"
+#include "BLI_math.h"
 #include "BLI_editVert.h"
 #include "BLI_rand.h"
 
@@ -65,6 +65,7 @@ editmesh_mods.c, UI level access, no geometry changes
 #include "BKE_global.h"
 #include "BKE_mesh.h"
 #include "BKE_material.h"
+#include "BKE_paint.h"
 #include "BKE_texture.h"
 #include "BKE_utildefines.h"
 #include "BKE_report.h"
@@ -77,8 +78,11 @@ editmesh_mods.c, UI level access, no geometry changes
 #include "WM_api.h"
 #include "WM_types.h"
 
+#include "UI_resources.h"
+
 #include "RNA_access.h"
 #include "RNA_define.h"
+#include "RNA_enum_types.h"
 
 #include "ED_mesh.h"
 #include "ED_screen.h"
@@ -92,44 +96,70 @@ editmesh_mods.c, UI level access, no geometry changes
 #include "BLO_sys_types.h" // for intptr_t support
 
 /* XXX */
-static void waitcursor() {}
+static void waitcursor(int val) {}
 static int pupmenu() {return 0;}
 
 /* ****************************** MIRROR **************** */
 
-void EM_select_mirrored(Object *obedit, EditMesh *em)
+void EM_cache_x_mirror_vert(struct Object *ob, struct EditMesh *em)
 {
-       if(em->selectmode & SCE_SELECT_VERTEX) {
-               EditVert *eve, *v1;
-               
-               for(eve= em->verts.first; eve; eve= eve->next) {
-                       if(eve->f & SELECT) {
-                               v1= editmesh_get_x_mirror_vert(obedit, em, eve->co);
-                               if(v1) {
-                                       eve->f &= ~SELECT;
-                                       v1->f |= SELECT;
-                               }
+       EditVert *eve, *eve_mirror;
+
+       for(eve= em->verts.first; eve; eve= eve->next) {
+               eve->tmp.v= NULL;
+       }
+
+       for(eve= em->verts.first; eve; eve= eve->next) {
+               if(eve->tmp.v==NULL) {
+                       eve_mirror = editmesh_get_x_mirror_vert(ob, em, eve->co);
+                       if(eve_mirror) {
+                               eve->tmp.v= eve_mirror;
+                               eve_mirror->tmp.v = eve;
                        }
                }
        }
 }
 
-void EM_automerge(int update) 
+void EM_select_mirrored(Object *obedit, EditMesh *em, int extend)
 {
-// XXX int len;
-       
-//     if ((scene->automerge) &&
-//             (obedit && obedit->type==OB_MESH) &&
-//             (((Mesh*)obedit->data)->mr==NULL)
-//       ) {
-//             len = removedoublesflag(1, 1, scene->toolsettings->doublimit);
-//             if (len) {
-//                     em->totvert -= len; /* saves doing a countall */
-//                     if (update) {
-//                             DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
-//                     }
-//             }
-//     }
+
+       EditVert *eve;
+
+       EM_cache_x_mirror_vert(obedit, em);
+
+       for(eve= em->verts.first; eve; eve= eve->next) {
+               if(eve->f & SELECT && eve->tmp.v) {
+                       eve->tmp.v->f |= SELECT;
+
+                       if(extend==FALSE)
+                               eve->f &= ~SELECT;
+
+                       /* remove the interference */
+                       eve->tmp.v->tmp.v= eve->tmp.v= NULL;
+               }
+       }
+}
+
+void EM_automerge(Scene *scene, Object *obedit, int update)
+{
+       Mesh *me= obedit ? obedit->data : NULL; /* can be NULL */
+       int len;
+
+       if ((scene->toolsettings->automerge) &&
+               (obedit && obedit->type==OB_MESH && (obedit->mode & OB_MODE_EDIT)) &&
+               (me->mr==NULL)
+         ) {
+               Mesh *me= (Mesh*)obedit->data;
+               EditMesh *em= me->edit_mesh;
+
+               len = removedoublesflag(em, 1, 1, scene->toolsettings->doublimit);
+               if (len) {
+                       em->totvert -= len; /* saves doing a countall */
+                       if (update) {
+                               DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+                       }
+               }
+       }
 }
 
 /* ****************************** SELECTION ROUTINES **************** */
@@ -242,7 +272,7 @@ int EM_mask_init_backbuf_border(ViewContext *vc, short mcords[][2], short tot, s
        
        /* method in use for face selecting too */
        if(vc->obedit==NULL) {
-               if(FACESEL_PAINT_TEST);
+               if(paint_facesel_test(vc->obact));
                else return 0;
        }
        else if(vc->v3d->drawtype<OB_SOLID || (vc->v3d->flag & V3D_ZBUF_SELECT)==0) return 0;
@@ -297,7 +327,7 @@ int EM_init_backbuf_circle(ViewContext *vc, short xs, short ys, short rads)
        
        /* method in use for face selecting too */
        if(vc->obedit==NULL) {
-               if(FACESEL_PAINT_TEST);
+               if(paint_facesel_test(vc->obact));
                else return 0;
        }
        else if(vc->v3d->drawtype<OB_SOLID || (vc->v3d->flag & V3D_ZBUF_SELECT)==0) return 0;
@@ -415,6 +445,9 @@ EditVert *findnearestvert(ViewContext *vc, int *dist, short sel, short strict)
                data.closestIndex = 0;
 
                data.pass = 0;
+
+               ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
+
                mesh_foreachScreenVert(vc, findnearestvert__doClosest, &data, 1);
 
                if (data.dist>3) {
@@ -450,14 +483,17 @@ static void findnearestedge__doClosest(void *userData, EditEdge *eed, int x0, in
        struct { ViewContext vc; float mval[2]; int dist; EditEdge *closest; } *data = userData;
        float v1[2], v2[2];
        int distance;
-               
+
+       ED_view3d_local_clipping(data->vc.rv3d, data->vc.obedit->obmat); /* for local clipping lookups */
+
        v1[0] = x0;
        v1[1] = y0;
        v2[0] = x1;
        v2[1] = y1;
-               
-       distance= PdistVL2Dfl(data->mval, v1, v2);
-               
+
+       distance= dist_to_line_segment_v2(data->mval, v1, v2);
+
+
        if(eed->f & SELECT) distance+=5;
        if(distance < data->dist) {
                if(data->vc.rv3d->rflag & RV3D_CLIPPING) {
@@ -467,9 +503,8 @@ static void findnearestedge__doClosest(void *userData, EditEdge *eed, int x0, in
                        vec[0]= eed->v1->co[0] + labda*(eed->v2->co[0] - eed->v1->co[0]);
                        vec[1]= eed->v1->co[1] + labda*(eed->v2->co[1] - eed->v1->co[1]);
                        vec[2]= eed->v1->co[2] + labda*(eed->v2->co[2] - eed->v1->co[2]);
-                       Mat4MulVecfl(data->vc.obedit->obmat, vec);
 
-                       if(view3d_test_clipping(data->vc.rv3d, vec)==0) {
+                       if(view3d_test_clipping(data->vc.rv3d, vec, 1)==0) {
                                data->dist = distance;
                                data->closest = eed;
                        }
@@ -504,6 +539,7 @@ EditEdge *findnearestedge(ViewContext *vc, int *dist)
                data.dist = *dist;
                data.closest = NULL;
 
+               ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
                mesh_foreachScreenEdge(vc, findnearestedge__doClosest, &data, 2);
 
                *dist = data.dist;
@@ -559,6 +595,7 @@ static EditFace *findnearestface(ViewContext *vc, int *dist)
                        data.dist = 0x7FFF;             /* largest short */
                        data.toFace = efa;
 
+                       ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
                        mesh_foreachScreenFace(vc, findnearestface__getDistance, &data);
 
                        if(vc->em->selectmode == SCE_SELECT_FACE || data.dist<*dist) {  /* only faces, no dist check */
@@ -587,6 +624,8 @@ static EditFace *findnearestface(ViewContext *vc, int *dist)
                data.closestIndex = 0;
 
                data.pass = 0;
+
+               ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
                mesh_foreachScreenFace(vc, findnearestface__doClosest, &data);
 
                if (data.dist>3) {
@@ -642,25 +681,53 @@ static int unified_findnearest(ViewContext *vc, EditVert **eve, EditEdge **eed,
 
 /* ****************  SIMILAR "group" SELECTS. FACE, EDGE AND VERTEX ************** */
 
-/* selects new faces/edges/verts based on the
- existing selection
-
-FACES GROUP
- mode 1: same material
- mode 2: same image
- mode 3: same area
- mode 4: same perimeter
- mode 5: same normal
- mode 6: same co-planer
-*/
-
-static EnumPropertyItem prop_simface_types[] = {
-       {1, "MATERIAL", 0, "Material", ""},
-       {2, "IMAGE", 0, "Image", ""},
-       {3, "AREA", 0, "Area", ""},
-       {4, "PERIMETER", 0, "Perimeter", ""},
-       {5, "NORMAL", 0, "Normal", ""},
-       {6, "COPLANAR", 0, "Co-planar", ""},
+/* selects new faces/edges/verts based on the existing selection */
+
+/* VERT GROUP */
+
+#define SIMVERT_NORMAL 0
+#define SIMVERT_FACE   1
+#define SIMVERT_VGROUP 2
+#define SIMVERT_TOT            3
+
+/* EDGE GROUP */
+
+#define SIMEDGE_LENGTH         101
+#define SIMEDGE_DIR                    102
+#define SIMEDGE_FACE           103
+#define SIMEDGE_FACE_ANGLE     104
+#define SIMEDGE_CREASE         105
+#define SIMEDGE_SEAM           106
+#define SIMEDGE_SHARP          107
+#define SIMEDGE_TOT                    108
+
+/* FACE GROUP */
+
+#define SIMFACE_MATERIAL       201
+#define SIMFACE_IMAGE          202
+#define SIMFACE_AREA           203
+#define SIMFACE_PERIMETER      204
+#define SIMFACE_NORMAL         205
+#define SIMFACE_COPLANAR       206
+#define SIMFACE_TOT                    207
+
+static EnumPropertyItem prop_similar_types[] = {
+       {SIMVERT_NORMAL, "NORMAL", 0, "Normal", ""},
+       {SIMVERT_FACE, "FACE", 0, "Amount of Vertices in Face", ""},
+       {SIMVERT_VGROUP, "VGROUP", 0, "Vertex Groups", ""},
+       {SIMEDGE_LENGTH, "LENGTH", 0, "Length", ""},
+       {SIMEDGE_DIR, "DIR", 0, "Direction", ""},
+       {SIMEDGE_FACE, "FACE", 0, "Amount of Vertices in Face", ""},
+       {SIMEDGE_FACE_ANGLE, "FACE_ANGLE", 0, "Face Angles", ""},
+       {SIMEDGE_CREASE, "CREASE", 0, "Crease", ""},
+       {SIMEDGE_SEAM, "SEAM", 0, "Seam", ""},
+       {SIMEDGE_SHARP, "SHARP", 0, "Sharpness", ""},
+       {SIMFACE_MATERIAL, "MATERIAL", 0, "Material", ""},
+       {SIMFACE_IMAGE, "IMAGE", 0, "Image", ""},
+       {SIMFACE_AREA, "AREA", 0, "Area", ""},
+       {SIMFACE_PERIMETER, "PERIMETER", 0, "Perimeter", ""},
+       {SIMFACE_NORMAL, "NORMAL", 0, "Normal", ""},
+       {SIMFACE_COPLANAR, "COPLANAR", 0, "Co-planar", ""},
        {0, NULL, 0, NULL, NULL}
 };
 
@@ -695,12 +762,11 @@ static int similar_face_select__internal(Scene *scene, EditMesh *em, int mode)
        if (!ok || !deselcount) /* no data selected OR no more data to select */
                return 0;
        
-       /*if mode is 3 then record face areas, 4 record perimeter */
-       if (mode==3) {
+       if (mode==SIMFACE_AREA) {
                for(efa= em->faces.first; efa; efa= efa->next) {
                        efa->tmp.fp= EM_face_area(efa);
                }
-       } else if (mode==4) {
+       } else if (mode==SIMFACE_PERIMETER) {
                for(efa= em->faces.first; efa; efa= efa->next) {
                        efa->tmp.fp= EM_face_perimeter(efa);
                }
@@ -708,7 +774,7 @@ static int similar_face_select__internal(Scene *scene, EditMesh *em, int mode)
        
        for(base_efa= em->faces.first; base_efa; base_efa= base_efa->next) {
                if (base_efa->f1) { /* This was one of the faces originaly selected */
-                       if (mode==1) { /* same material */
+                       if (mode==SIMFACE_MATERIAL) { /* same material */
                                for(efa= em->faces.first; efa; efa= efa->next) {
                                        if (
                                                !(efa->f & SELECT) &&
@@ -722,7 +788,7 @@ static int similar_face_select__internal(Scene *scene, EditMesh *em, int mode)
                                                        return selcount;
                                        }
                                }
-                       } else if (mode==2) { /* same image */
+                       } else if (mode==SIMFACE_IMAGE) { /* same image */
                                MTFace *tf, *base_tf;
 
                                base_tf = (MTFace*)CustomData_em_get(&em->fdata, base_efa->data,
@@ -745,7 +811,7 @@ static int similar_face_select__internal(Scene *scene, EditMesh *em, int mode)
                                                }
                                        }
                                }
-                       } else if (mode==3 || mode==4) { /* same area OR same perimeter, both use the same temp var */
+                       } else if (mode==SIMFACE_AREA || mode==SIMFACE_PERIMETER) { /* same area OR same perimeter, both use the same temp var */
                                for(efa= em->faces.first; efa; efa= efa->next) {
                                        if (
                                                (!(efa->f & SELECT) && !efa->h) &&
@@ -758,11 +824,11 @@ static int similar_face_select__internal(Scene *scene, EditMesh *em, int mode)
                                                        return selcount;
                                        }
                                }
-                       } else if (mode==5) { /* same normal */
+                       } else if (mode==SIMFACE_NORMAL) {
                                float angle;
                                for(efa= em->faces.first; efa; efa= efa->next) {
                                        if (!(efa->f & SELECT) && !efa->h) {
-                                               angle= VecAngle2(base_efa->n, efa->n);
+                                               angle= RAD2DEG(angle_v2v2(base_efa->n, efa->n));
                                                if (angle/180.0<=thresh) {
                                                        EM_select_face(efa, 1);
                                                        selcount++;
@@ -772,14 +838,14 @@ static int similar_face_select__internal(Scene *scene, EditMesh *em, int mode)
                                                }
                                        }
                                }
-                       } else if (mode==6) { /* same planer */
+                       } else if (mode==SIMFACE_COPLANAR) { /* same planer */
                                float angle, base_dot, dot;
-                               base_dot= Inpf(base_efa->cent, base_efa->n);
+                               base_dot= dot_v3v3(base_efa->cent, base_efa->n);
                                for(efa= em->faces.first; efa; efa= efa->next) {
                                        if (!(efa->f & SELECT) && !efa->h) {
-                                               angle= VecAngle2(base_efa->n, efa->n);
+                                               angle= RAD2DEG(angle_v2v2(base_efa->n, efa->n));
                                                if (angle/180.0<=thresh) {
-                                                       dot=Inpf(efa->cent, base_efa->n);
+                                                       dot=dot_v3v3(efa->cent, base_efa->n);
                                                        if (fabs(base_dot-dot) <= thresh) {
                                                                EM_select_face(efa, 1);
                                                                selcount++;
@@ -808,7 +874,7 @@ static int similar_face_select_exec(bContext *C, wmOperator *op)
        if (selcount) {
                /* here was an edge-mode only select flush case, has to be generalized */
                EM_selectmode_flush(em);
-               WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+               WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
                BKE_mesh_end_editmesh(me, em);
                return OPERATOR_FINISHED;
        }
@@ -817,49 +883,9 @@ static int similar_face_select_exec(bContext *C, wmOperator *op)
        return OPERATOR_CANCELLED;
 }      
 
-void MESH_OT_faces_select_similar(wmOperatorType *ot)
-{
-       /* identifiers */
-       ot->name= "Similar Face Select";
-       ot->idname= "MESH_OT_faces_select_similar";
-       
-       /* api callbacks */
-       ot->invoke= WM_menu_invoke;
-       ot->exec= similar_face_select_exec;
-       ot->poll= ED_operator_editmesh;
-       
-       /* flags */
-       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
-       
-       /* properties */
-       RNA_def_enum(ot->srna, "type", prop_simface_types, 0, "Type", "");
-}
-
 /* ***************************************************** */
 
-/*
-EDGE GROUP
- mode 1: same length
- mode 2: same direction
- mode 3: same number of face users
- mode 4: similar face angles.
- mode 5: similar crease
- mode 6: similar seam
- mode 7: similar sharp
-*/
-
-static EnumPropertyItem prop_simedge_types[] = {
-       {1, "LENGTH", 0, "Length", ""},
-       {2, "DIR", 0, "Direction", ""},
-       {3, "FACE", 0, "Amount of Vertices in Face", ""},
-       {4, "FACE_ANGLE", 0, "Face Angles", ""},
-       {5, "CREASE", 0, "Crease", ""},
-       {6, "SEAM", 0, "Seam", ""},
-       {7, "SHARP", 0, "Sharpness", ""},
-       {0, NULL, 0, NULL, NULL}
-};
-
-static int similar_edge_select__internal(Scene *scene, EditMesh *em, int mode)
+static int similar_edge_select__internal(ToolSettings *ts, EditMesh *em, int mode)
 {
        EditEdge *eed, *base_eed=NULL;
        unsigned int selcount=0; /* count how many new edges we select*/
@@ -869,7 +895,7 @@ static int similar_edge_select__internal(Scene *scene, EditMesh *em, int mode)
        unsigned int deselcount=0;
        
        short ok=0;
-       float thresh= scene->toolsettings->select_thresh;
+       float thresh= ts->select_thresh;
        
        for(eed= em->edges.first; eed; eed= eed->next) {
                if (!eed->h) {
@@ -883,19 +909,19 @@ static int similar_edge_select__internal(Scene *scene, EditMesh *em, int mode)
                        /* set all eed->tmp.l to 0 we use it later.
                        for counting face users*/
                        eed->tmp.l=0;
-                       eed->f2=0; /* only for mode 4, edge animations */
+                       eed->f2=0; /* only for mode SIMEDGE_FACE_ANGLE, edge animations */
                }
        }
        
        if (!ok || !deselcount) /* no data selected OR no more data to select*/
                return 0;
        
-       if (mode==1) { /*store length*/
+       if (mode==SIMEDGE_LENGTH) { /*store length*/
                for(eed= em->edges.first; eed; eed= eed->next) {
                        if (!eed->h) /* dont calc data for hidden edges*/
-                               eed->tmp.fp= VecLenf(eed->v1->co, eed->v2->co);
+                               eed->tmp.fp= len_v3v3(eed->v1->co, eed->v2->co);
                }
-       } else if (mode==3) { /*store face users*/
+       } else if (mode==SIMEDGE_FACE) { /*store face users*/
                EditFace *efa;
                /* cound how many faces each edge uses use tmp->l */
                for(efa= em->faces.first; efa; efa= efa->next) {
@@ -904,7 +930,7 @@ static int similar_edge_select__internal(Scene *scene, EditMesh *em, int mode)
                        efa->e3->tmp.l++;
                        if (efa->e4) efa->e4->tmp.l++;
                }
-       } else if (mode==4) { /*store edge angles */
+       } else if (mode==SIMEDGE_FACE_ANGLE) { /*store edge angles */
                EditFace *efa;
                int j;
                /* cound how many faces each edge uses use tmp.l */
@@ -936,7 +962,7 @@ static int similar_edge_select__internal(Scene *scene, EditMesh *em, int mode)
                                        else if (eed->f2==0) /* first access, assign the face */
                                                eed->tmp.f= efa;
                                        else if (eed->f2==1) /* second, we assign the angle*/
-                                               eed->tmp.fp= VecAngle2(eed->tmp.f->n, efa->n)/180;
+                                               eed->tmp.fp= RAD2DEG(angle_v2v2(eed->tmp.f->n, efa->n))/180;
                                        eed->f2++; /* f2==0 no face assigned. f2==1 one face found. f2==2 angle calculated.*/
                                }
                                j++;
@@ -946,7 +972,7 @@ static int similar_edge_select__internal(Scene *scene, EditMesh *em, int mode)
        
        for(base_eed= em->edges.first; base_eed; base_eed= base_eed->next) {
                if (base_eed->f1) {
-                       if (mode==1) { /* same length */
+                       if (mode==SIMEDGE_LENGTH) { /* same length */
                                for(eed= em->edges.first; eed; eed= eed->next) {
                                        if (
                                                !(eed->f & SELECT) &&
@@ -960,13 +986,13 @@ static int similar_edge_select__internal(Scene *scene, EditMesh *em, int mode)
                                                        return selcount;
                                        }
                                }
-                       } else if (mode==2) { /* same direction */
+                       } else if (mode==SIMEDGE_DIR) { /* same direction */
                                float base_dir[3], dir[3], angle;
-                               VecSubf(base_dir, base_eed->v1->co, base_eed->v2->co);
+                               sub_v3_v3v3(base_dir, base_eed->v1->co, base_eed->v2->co);
                                for(eed= em->edges.first; eed; eed= eed->next) {
                                        if (!(eed->f & SELECT) && !eed->h) {
-                                               VecSubf(dir, eed->v1->co, eed->v2->co);
-                                               angle= VecAngle2(base_dir, dir);
+                                               sub_v3_v3v3(dir, eed->v1->co, eed->v2->co);
+                                               angle= RAD2DEG(angle_v2v2(base_dir, dir));
                                                
                                                if (angle>90) /* use the smallest angle between the edges */
                                                        angle= fabs(angle-180.0f);
@@ -980,7 +1006,7 @@ static int similar_edge_select__internal(Scene *scene, EditMesh *em, int mode)
                                                }
                                        }
                                }
-                       } else if (mode==3) { /* face users */                          
+                       } else if (mode==SIMEDGE_FACE) { /* face users */                               
                                for(eed= em->edges.first; eed; eed= eed->next) {
                                        if (
                                                !(eed->f & SELECT) &&
@@ -994,7 +1020,7 @@ static int similar_edge_select__internal(Scene *scene, EditMesh *em, int mode)
                                                        return selcount;
                                        }
                                }
-                       } else if (mode==4 && base_eed->f2==2) { /* edge angles, f2==2 means the edge has an angle. */                          
+                       } else if (mode==SIMEDGE_FACE_ANGLE && base_eed->f2==2) { /* edge angles, f2==2 means the edge has an angle. */                         
                                for(eed= em->edges.first; eed; eed= eed->next) {
                                        if (
                                                !(eed->f & SELECT) &&
@@ -1009,7 +1035,7 @@ static int similar_edge_select__internal(Scene *scene, EditMesh *em, int mode)
                                                        return selcount;
                                        }
                                }
-                       } else if (mode==5) { /* edge crease */
+                       } else if (mode==SIMEDGE_CREASE) { /* edge crease */
                                for(eed= em->edges.first; eed; eed= eed->next) {
                                        if (
                                                !(eed->f & SELECT) &&
@@ -1023,7 +1049,7 @@ static int similar_edge_select__internal(Scene *scene, EditMesh *em, int mode)
                                                        return selcount;
                                        }
                                }
-                       } else if (mode==6) { /* edge seam */
+                       } else if (mode==SIMEDGE_SEAM) { /* edge seam */
                                for(eed= em->edges.first; eed; eed= eed->next) {
                                        if (
                                                !(eed->f & SELECT) &&
@@ -1037,7 +1063,7 @@ static int similar_edge_select__internal(Scene *scene, EditMesh *em, int mode)
                                                        return selcount;
                                        }
                                }
-                       } else if (mode==7) { /* edge sharp */
+                       } else if (mode==SIMEDGE_SHARP) { /* edge sharp */
                                for(eed= em->edges.first; eed; eed= eed->next) {
                                        if (
                                                !(eed->f & SELECT) &&
@@ -1059,17 +1085,17 @@ static int similar_edge_select__internal(Scene *scene, EditMesh *em, int mode)
 /* wrap the above function but do selection flushing edge to face */
 static int similar_edge_select_exec(bContext *C, wmOperator *op)
 {
-       Scene *scene= CTX_data_scene(C);
+       ToolSettings *ts= CTX_data_tool_settings(C);
        Object *obedit= CTX_data_edit_object(C);
        Mesh *me= obedit->data;
        EditMesh *em= BKE_mesh_get_editmesh(me); 
 
-       int selcount = similar_edge_select__internal(scene, em, RNA_int_get(op->ptr, "type"));
+       int selcount = similar_edge_select__internal(ts, em, RNA_int_get(op->ptr, "type"));
        
        if (selcount) {
                /* here was an edge-mode only select flush case, has to be generalized */
                EM_selectmode_flush(em);
-               WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+               WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
                BKE_mesh_end_editmesh(me, em);
                return OPERATOR_FINISHED;
        }
@@ -1078,43 +1104,11 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op)
        return OPERATOR_CANCELLED;
 }
 
-void MESH_OT_edges_select_similar(wmOperatorType *ot)
-{
-       /* identifiers */
-       ot->name= "Similar Edge Select";
-       ot->idname= "MESH_OT_edges_select_similar";
-       
-       /* api callbacks */
-       ot->invoke= WM_menu_invoke;
-       ot->exec= similar_edge_select_exec;
-       ot->poll= ED_operator_editmesh;
-       
-       /* flags */
-       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
-       
-       /* properties */
-       RNA_def_enum(ot->srna, "type", prop_simedge_types, 0, "Type", "");
-}
-
 /* ********************************* */
 
-/*
-VERT GROUP
- mode 1: same normal
- mode 2: same number of face users
- mode 3: same vertex groups
-*/
-static EnumPropertyItem prop_simvertex_types[] = {
-       {0, "NORMAL", 0, "Normal", ""},
-       {1, "FACE", 0, "Amount of Vertices in Face", ""},
-       {2, "VGROUP", 0, "Vertex Groups", ""},
-       {0, NULL, 0, NULL, NULL}
-};
-
-
 static int similar_vert_select_exec(bContext *C, wmOperator *op)
 {
-       Scene *scene= CTX_data_scene(C);
+       ToolSettings *ts= CTX_data_tool_settings(C);
        Object *obedit= CTX_data_edit_object(C);
        Mesh *me= obedit->data;
        EditMesh *em= BKE_mesh_get_editmesh(me); 
@@ -1124,9 +1118,10 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
        /*count how many visible selected edges there are,
        so we can return when there are none left */
        unsigned int deselcount=0;
+       int mode= RNA_enum_get(op->ptr, "type");
        
        short ok=0;
-       float thresh= scene->toolsettings->select_thresh;
+       float thresh= ts->select_thresh;
        
        for(eve= em->verts.first; eve; eve= eve->next) {
                if (!eve->h) {
@@ -1148,7 +1143,7 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
                return 0;
        }
        
-       if(RNA_enum_is_equal(op->ptr, "type", "FACE")) {
+       if(mode == SIMVERT_FACE) {
                /* store face users */
                EditFace *efa;
                
@@ -1165,11 +1160,11 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
        for(base_eve= em->verts.first; base_eve; base_eve= base_eve->next) {
                if (base_eve->f1) {
                                
-                       if(RNA_enum_is_equal(op->ptr, "type", "NORMAL")) {
+                       if(mode == SIMVERT_NORMAL) {
                                float angle;
                                for(eve= em->verts.first; eve; eve= eve->next) {
                                        if (!(eve->f & SELECT) && !eve->h) {
-                                               angle= VecAngle2(base_eve->no, eve->no);
+                                               angle= RAD2DEG(angle_v2v2(base_eve->no, eve->no));
                                                if (angle/180.0<=thresh) {
                                                        eve->f |= SELECT;
                                                        selcount++;
@@ -1182,7 +1177,7 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
                                        }
                                }
                        }
-                       else if(RNA_enum_is_equal(op->ptr, "type", "FACE")) {
+                       else if(mode == SIMVERT_FACE) {
                                for(eve= em->verts.first; eve; eve= eve->next) {
                                        if (
                                                !(eve->f & SELECT) &&
@@ -1199,7 +1194,7 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
                                        }
                                }
                        } 
-                       else if(RNA_enum_is_equal(op->ptr, "type", "VGROUP")) {
+                       else if(mode == SIMVERT_VGROUP) {
                                MDeformVert *dvert, *base_dvert;
                                short i, j; /* weight index */
 
@@ -1239,7 +1234,7 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
        } /* end basevert loop */
 
        if(selcount) {
-               WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+               WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
                BKE_mesh_end_editmesh(me, em);
                return OPERATOR_FINISHED;
        }
@@ -1248,22 +1243,67 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
        return OPERATOR_CANCELLED;
 }
 
-void MESH_OT_vertices_select_similar(wmOperatorType *ot)
+static int select_similar_exec(bContext *C, wmOperator *op)
+{
+       int type= RNA_enum_get(op->ptr, "type");
+
+       if(type < 100)
+               return similar_vert_select_exec(C, op);
+       else if(type < 200)
+               return similar_edge_select_exec(C, op);
+       else
+               return similar_face_select_exec(C, op);
+}
+
+static EnumPropertyItem *select_similar_type_itemf(bContext *C, PointerRNA *ptr, int *free)
 {
+       Object *obedit= CTX_data_edit_object(C);
+       EnumPropertyItem *item= NULL;
+       int a, totitem= 0;
+               
+       if(obedit && obedit->type == OB_MESH) {
+               EditMesh *em= BKE_mesh_get_editmesh(obedit->data); 
+
+               if(em->selectmode & SCE_SELECT_VERTEX) {
+                       for(a=SIMVERT_NORMAL; a<=SIMVERT_TOT; a++)
+                               RNA_enum_items_add_value(&item, &totitem, prop_similar_types, a);
+               }
+               else if(em->selectmode & SCE_SELECT_EDGE) {
+                       for(a=SIMEDGE_LENGTH; a<=SIMEDGE_TOT; a++)
+                               RNA_enum_items_add_value(&item, &totitem, prop_similar_types, a);
+               }
+               else if(em->selectmode & SCE_SELECT_FACE) {
+                       for(a=SIMFACE_MATERIAL; a<=SIMFACE_TOT; a++)
+                               RNA_enum_items_add_value(&item, &totitem, prop_similar_types, a);
+               }
+       }
+
+       RNA_enum_item_end(&item, &totitem);
+       *free= 1;
+
+       return item;
+}
+
+void MESH_OT_select_similar(wmOperatorType *ot)
+{
+       PropertyRNA *prop;
+
        /* identifiers */
-       ot->name= "Similar Vertex Select";
-       ot->idname= "MESH_OT_vertices_select_similar";
+       ot->name= "Select Similar";
+       ot->description= "Select similar vertices, edges or faces by property types.";
+       ot->idname= "MESH_OT_select_similar";
        
        /* api callbacks */
        ot->invoke= WM_menu_invoke;
-       ot->exec= similar_vert_select_exec;
+       ot->exec= select_similar_exec;
        ot->poll= ED_operator_editmesh;
        
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
        
        /* properties */
-       RNA_def_enum(ot->srna, "type", prop_simvertex_types, 0, "Type", "");
+       prop= RNA_def_enum(ot->srna, "type", prop_similar_types, SIMVERT_NORMAL, "Type", "");
+       RNA_def_enum_funcs(prop, select_similar_type_itemf);
 }
 
 /* ******************************************* */
@@ -1351,34 +1391,34 @@ void EM_mesh_copy_edge(EditMesh *em, short type)
                break;
 
        case 3: /* copy length */
-               eed_len_act = VecLenf(eed_act->v1->co, eed_act->v2->co);
+               eed_len_act = len_v3v3(eed_act->v1->co, eed_act->v2->co);
                for(eed=em->edges.first; eed; eed=eed->next) {
                        if (eed->f & SELECT && eed != eed_act) {
 
-                               eed_len = VecLenf(eed->v1->co, eed->v2->co);
+                               eed_len = len_v3v3(eed->v1->co, eed->v2->co);
 
                                if (eed_len == eed_len_act) continue;
                                /* if this edge is zero length we cont do anything with it*/
                                if (eed_len == 0.0f) continue;
                                if (eed_len_act == 0.0f) {
-                                       VecAddf(vec_mid, eed->v1->co, eed->v2->co);
-                                       VecMulf(vec_mid, 0.5);
+                                       add_v3_v3v3(vec_mid, eed->v1->co, eed->v2->co);
+                                       mul_v3_fl(vec_mid, 0.5);
                                        VECCOPY(eed->v1->co, vec_mid);
                                        VECCOPY(eed->v2->co, vec_mid);
                                } else {
                                        /* copy the edge length */
-                                       VecAddf(vec_mid, eed->v1->co, eed->v2->co);
-                                       VecMulf(vec_mid, 0.5);
+                                       add_v3_v3v3(vec_mid, eed->v1->co, eed->v2->co);
+                                       mul_v3_fl(vec_mid, 0.5);
 
                                        /* SCALE 1 */
-                                       VecSubf(vec, eed->v1->co, vec_mid);
-                                       VecMulf(vec, eed_len_act/eed_len);
-                                       VecAddf(eed->v1->co, vec, vec_mid);
+                                       sub_v3_v3v3(vec, eed->v1->co, vec_mid);
+                                       mul_v3_fl(vec, eed_len_act/eed_len);
+                                       add_v3_v3v3(eed->v1->co, vec, vec_mid);
 
                                        /* SCALE 2 */
-                                       VecSubf(vec, eed->v2->co, vec_mid);
-                                       VecMulf(vec, eed_len_act/eed_len);
-                                       VecAddf(eed->v2->co, vec, vec_mid);
+                                       sub_v3_v3v3(vec, eed->v2->co, vec_mid);
+                                       mul_v3_fl(vec, eed_len_act/eed_len);
+                                       add_v3_v3v3(eed->v2->co, vec, vec_mid);
                                }
                                change = 1;
                        }
@@ -1391,7 +1431,7 @@ void EM_mesh_copy_edge(EditMesh *em, short type)
        }
        
        if (change) {
-//             DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+//             DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
                
        }
 }
@@ -1422,7 +1462,7 @@ void EM_mesh_copy_face(EditMesh *em, wmOperator *op, short type)
                break;
        case 2: /* copy image */
                if (!tf_act) {
-                       BKE_report(op->reports, RPT_ERROR, "mesh has no uv/image layers");
+                       BKE_report(op->reports, RPT_ERROR, "Mesh has no uv/image layers.");
                        return;
                }
                for(efa=em->faces.first; efa; efa=efa->next) {
@@ -1443,7 +1483,7 @@ void EM_mesh_copy_face(EditMesh *em, wmOperator *op, short type)
 
        case 3: /* copy UV's */
                if (!tf_act) {
-                       BKE_report(op->reports, RPT_ERROR, "mesh has no uv/image layers");
+                       BKE_report(op->reports, RPT_ERROR, "Mesh has no uv/image layers.");
                        return;
                }
                for(efa=em->faces.first; efa; efa=efa->next) {
@@ -1456,7 +1496,7 @@ void EM_mesh_copy_face(EditMesh *em, wmOperator *op, short type)
                break;
        case 4: /* mode's */
                if (!tf_act) {
-                       BKE_report(op->reports, RPT_ERROR, "mesh has no uv/image layers");
+                       BKE_report(op->reports, RPT_ERROR, "Mesh has no uv/image layers.");
                        return;
                }
                for(efa=em->faces.first; efa; efa=efa->next) {
@@ -1469,7 +1509,7 @@ void EM_mesh_copy_face(EditMesh *em, wmOperator *op, short type)
                break;
        case 5: /* copy transp's */
                if (!tf_act) {
-                       BKE_report(op->reports, RPT_ERROR, "mesh has no uv/image layers");
+                       BKE_report(op->reports, RPT_ERROR, "Mesh has no uv/image layers.");
                        return;
                }
                for(efa=em->faces.first; efa; efa=efa->next) {
@@ -1483,7 +1523,7 @@ void EM_mesh_copy_face(EditMesh *em, wmOperator *op, short type)
 
        case 6: /* copy vcols's */
                if (!mcol_act) {
-                       BKE_report(op->reports, RPT_ERROR, "mesh has no color layers");
+                       BKE_report(op->reports, RPT_ERROR, "Mesh has no color layers.");
                        return;
                } else {
                        /* guess the 4th color if needs be */
@@ -1519,7 +1559,7 @@ void EM_mesh_copy_face(EditMesh *em, wmOperator *op, short type)
        }
        
        if (change) {
-//             DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+//             DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
                
        }
 }
@@ -1649,7 +1689,7 @@ void EM_mesh_copy_face_layer(EditMesh *em, wmOperator *op, short type)
        }
 
        if (change) {
-//             DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+//             DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
                
        }
 }
@@ -1969,7 +2009,7 @@ static int loop_multiselect(bContext *C, wmOperator *op)
        MEM_freeN(edarray);
 //     if (EM_texFaceCheck())
        
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+       WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
 
        BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;       
@@ -1979,6 +2019,7 @@ void MESH_OT_loop_multi_select(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Multi Select Loops";
+       ot->description= "Select a loop of connected edges by connection type.";
        ot->idname= "MESH_OT_loop_multi_select";
        
        /* api callbacks */
@@ -2010,6 +2051,9 @@ static void mouse_mesh_loop(bContext *C, short mval[2], short extend, short ring
        vc.mval[0]= mval[0];
        vc.mval[1]= mval[1];
        em= vc.em;
+
+       /* no afterqueue (yet), so we check it now, otherwise the em_xxxofs indices are bad */
+       view3d_validate_backbuf(&vc);
        
        eed= findnearestedge(&vc, &dist);
        if(eed) {
@@ -2037,7 +2081,7 @@ static void mouse_mesh_loop(bContext *C, short mval[2], short extend, short ring
                EM_selectmode_flush(em);
 //                     if (EM_texFaceCheck())
                
-               WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, vc.obedit);
+               WM_event_add_notifier(C, NC_GEOM|ND_SELECT, vc.obedit->data);
        }
 }
 
@@ -2057,6 +2101,7 @@ void MESH_OT_loop_select(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Loop Select";
+       ot->description= "Select a loop of connected edges.";
        ot->idname= "MESH_OT_loop_select";
        
        /* api callbacks */
@@ -2086,6 +2131,9 @@ static void mouse_mesh_shortest_path(bContext *C, short mval[2])
        vc.mval[1]= mval[1];
        em= vc.em;
        
+       /* no afterqueue (yet), so we check it now, otherwise the em_xxxofs indices are bad */
+       view3d_validate_backbuf(&vc);
+       
        eed= findnearestedge(&vc, &dist);
        if(eed) {
                Mesh *me= vc.obedit->data;
@@ -2135,9 +2183,8 @@ static void mouse_mesh_shortest_path(bContext *C, short mval[2])
                                break;
                }
                
-               DAG_object_flush_update(vc.scene, vc.obedit, OB_RECALC_DATA);
-       
-               WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, vc.obedit);
+               DAG_id_flush_update(vc.obedit->data, OB_RECALC_DATA);
+               WM_event_add_notifier(C, NC_GEOM|ND_SELECT, vc.obedit->data);
        }
 }
 
@@ -2156,6 +2203,7 @@ void MESH_OT_select_shortest_path(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Shortest Path Select";
+       ot->description= "Select shortest path between two selections.";
        ot->idname= "MESH_OT_select_shortest_path";
        
        /* api callbacks */
@@ -2175,7 +2223,7 @@ void MESH_OT_select_shortest_path(wmOperatorType *ot)
 
 /* here actual select happens */
 /* gets called via generic mouse select operator */
-void mouse_mesh(bContext *C, short mval[2], short extend)
+int mouse_mesh(bContext *C, short mval[2], short extend)
 {
        ViewContext vc;
        EditVert *eve;
@@ -2234,10 +2282,13 @@ void mouse_mesh(bContext *C, short mval[2], short extend)
                        vc.em->mat_nr= efa->mat_nr;
 //                     BIF_preview_changed(ID_MA);
                }
-       }
 
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, vc.obedit);
+               WM_event_add_notifier(C, NC_GEOM|ND_SELECT, vc.obedit->data);
+
+               return 1;
+       }
        
+       return 0;
 }
 
 /* *********** select linked ************* */
@@ -2355,6 +2406,15 @@ static int select_linked_limited_invoke(ViewContext *vc, short all, short sel)
 #undef is_face_tag
 #undef face_tag
 
+static void linked_limit_default(bContext *C, wmOperator *op) {
+       if(!RNA_property_is_set(op->ptr, "limit")) {
+               Object *obedit= CTX_data_edit_object(C);
+               EditMesh *em= BKE_mesh_get_editmesh(obedit->data);
+               if(em->selectmode == SCE_SELECT_FACE)
+                       RNA_boolean_set(op->ptr, "limit", TRUE);
+       }
+}
+
 static int select_linked_pick_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {
        Object *obedit= CTX_data_edit_object(C);
@@ -2364,8 +2424,12 @@ static int select_linked_pick_invoke(bContext *C, wmOperator *op, wmEvent *event
        EditFace *efa;
        short done=1, toggle=0;
        int sel= !RNA_boolean_get(op->ptr, "deselect");
-       int limit= RNA_boolean_get(op->ptr, "limit");
+       int limit;
        
+       linked_limit_default(C, op);
+
+       limit = RNA_boolean_get(op->ptr, "limit");
+
        /* unified_finednearest needs ogl */
        view3d_operator_needs_opengl(C);
        
@@ -2380,12 +2444,12 @@ static int select_linked_pick_invoke(bContext *C, wmOperator *op, wmEvent *event
        /* return warning! */
        if(limit) {
                int retval= select_linked_limited_invoke(&vc, 0, sel);
-               WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+               WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
                return retval;
        }
        
        if( unified_findnearest(&vc, &eve, &eed, &efa)==0 ) {
-               WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+               WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
        
                return OPERATOR_CANCELLED;
        }
@@ -2439,7 +2503,7 @@ static int select_linked_pick_invoke(bContext *C, wmOperator *op, wmEvent *event
        
 //     if (EM_texFaceCheck())
        
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+       WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
        return OPERATOR_FINISHED;       
 }
 
@@ -2447,6 +2511,7 @@ void MESH_OT_select_linked_pick(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Select Linked";
+       ot->description= "(un)select all vertices linked to the active mesh.";
        ot->idname= "MESH_OT_select_linked_pick";
        
        /* api callbacks */
@@ -2519,20 +2584,28 @@ static int select_linked_exec(bContext *C, wmOperator *op)
        else
                selectconnected_mesh_all(em);
        
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+       WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
 
        BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;       
 }
 
+static int select_linked_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+       linked_limit_default(C, op);
+       return select_linked_exec(C, op);
+}
+
 void MESH_OT_select_linked(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Select Linked All";
+       ot->description= "Select all vertices linked to the active mesh.";
        ot->idname= "MESH_OT_select_linked";
        
        /* api callbacks */
        ot->exec= select_linked_exec;
+       ot->invoke= select_linked_invoke;
        ot->poll= ED_operator_editmesh;
        
        /* flags */
@@ -2644,7 +2717,7 @@ void EM_hide_mesh(EditMesh *em, int swap)
        em->totedgesel= em->totfacesel= em->totvertsel= 0;
 //     if(EM_texFaceCheck())
 
-       //      DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); 
+       //      DAG_id_flush_update(obedit->data, OB_RECALC_DATA);      
 }
 
 static int hide_mesh_exec(bContext *C, wmOperator *op)
@@ -2654,7 +2727,7 @@ static int hide_mesh_exec(bContext *C, wmOperator *op)
        
        EM_hide_mesh(em, RNA_boolean_get(op->ptr, "unselected"));
                
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+       WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
 
        BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;       
@@ -2664,6 +2737,7 @@ void MESH_OT_hide(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Hide Selection";
+       ot->description= "Hide (un)selected vertices, edges or faces.";
        ot->idname= "MESH_OT_hide";
        
        /* api callbacks */
@@ -2710,7 +2784,7 @@ void EM_reveal_mesh(EditMesh *em)
        EM_selectmode_flush(em);
 
 //     if (EM_texFaceCheck())
-//     DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); 
+//     DAG_id_flush_update(obedit->data, OB_RECALC_DATA);      
 }
 
 static int reveal_mesh_exec(bContext *C, wmOperator *op)
@@ -2720,7 +2794,7 @@ static int reveal_mesh_exec(bContext *C, wmOperator *op)
        
        EM_reveal_mesh(em);
 
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+       WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
 
        BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;       
@@ -2730,6 +2804,7 @@ void MESH_OT_reveal(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Reveal Hidden";
+       ot->description= "Reveal all hidden vertices, edges and faces.";
        ot->idname= "MESH_OT_reveal";
        
        /* api callbacks */
@@ -2740,20 +2815,24 @@ void MESH_OT_reveal(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
-void select_faces_by_numverts(EditMesh *em, wmOperator *op, int numverts)
+int select_by_number_vertices_exec(bContext *C, wmOperator *op)
 {
+       Object *obedit= CTX_data_edit_object(C);
+       EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data));
        EditFace *efa;
+       int numverts= RNA_enum_get(op->ptr, "type");
 
        /* Selects trias/qiads or isolated verts, and edges that do not have 2 neighboring
         * faces
         */
 
        /* for loose vertices/edges, we first select all, loop below will deselect */
-       if(numverts==5)
+       if(numverts==5) {
                EM_set_flag_all(em, SELECT);
+       }
        else if(em->selectmode!=SCE_SELECT_FACE) {
                BKE_report(op->reports, RPT_ERROR, "Only works in face selection mode");
-               return;
+               return OPERATOR_CANCELLED;
        }
        
        for(efa= em->faces.first; efa; efa= efa->next) {
@@ -2765,8 +2844,66 @@ void select_faces_by_numverts(EditMesh *em, wmOperator *op, int numverts)
                }
        }
 
-//     if (EM_texFaceCheck())
+       WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
+       
+       return OPERATOR_FINISHED;
+}
+
+void MESH_OT_select_by_number_vertices(wmOperatorType *ot)
+{
+       static const EnumPropertyItem type_items[]= {
+               {3, "TRIANGLES", 0, "Triangles", NULL},
+               {4, "QUADS", 0, "Triangles", NULL},
+               {5, "OTHER", 0, "Other", NULL},
+               {0, NULL, 0, NULL, NULL}};
+
+       /* identifiers */
+       ot->name= "Select by Number of Vertices";
+       ot->description= "Select vertices or faces by vertex count.";
+       ot->idname= "MESH_OT_select_by_number_vertices";
+       
+       /* api callbacks */
+       ot->exec= select_by_number_vertices_exec;
+       ot->poll= ED_operator_editmesh;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
        
+       /* props */
+       RNA_def_enum(ot->srna, "type", type_items, 3, "Type", "Type of elements to select.");
+}
+
+
+int select_mirror_exec(bContext *C, wmOperator *op)
+{
+       Object *obedit= CTX_data_edit_object(C);
+       EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data));
+
+       int extend= RNA_boolean_get(op->ptr, "extend");
+
+       EM_select_mirrored(obedit, em, extend);
+
+       WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
+
+       return OPERATOR_FINISHED;
+}
+
+void MESH_OT_select_mirror(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Select Mirror";
+       ot->description= "Select mesh items at mirrored locations.";
+       ot->idname= "MESH_OT_select_mirror";
+
+       /* api callbacks */
+       ot->exec= select_mirror_exec;
+       ot->poll= ED_operator_editmesh;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+       /* props */
+       RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend the existing selection");
 }
 
 static int select_sharp_edges_exec(bContext *C, wmOperator *op)
@@ -2866,7 +3003,7 @@ static int select_sharp_edges_exec(bContext *C, wmOperator *op)
 
 //     if (EM_texFaceCheck())
        
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); //TODO is this needed ?
+       WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); //TODO is this needed ?
 
        BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;       
@@ -2876,6 +3013,7 @@ void MESH_OT_edges_select_sharp(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Select Sharp Edges";
+       ot->description= "Marked selected edges as sharp.";
        ot->idname= "MESH_OT_edges_select_sharp";
        
        /* api callbacks */
@@ -3033,7 +3171,7 @@ static int select_linked_flat_faces_exec(bContext *C, wmOperator *op)
        
        select_linked_flat_faces(em, op, RNA_float_get(op->ptr, "sharpness"));
        
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+       WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
 
        BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;       
@@ -3043,6 +3181,7 @@ void MESH_OT_faces_select_linked_flat(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Select Linked Flat Faces";
+       ot->description= "Select linked faces by angle.";
        ot->idname= "MESH_OT_faces_select_linked_flat";
        
        /* api callbacks */
@@ -3133,7 +3272,7 @@ static int select_non_manifold_exec(bContext *C, wmOperator *op)
        
        select_non_manifold(em, op);
        
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+       WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
 
        BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;       
@@ -3143,6 +3282,7 @@ void MESH_OT_select_non_manifold(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Select Non Manifold";
+       ot->description= "Select all non-manifold vertices or edges.";
        ot->idname= "MESH_OT_select_non_manifold";
        
        /* api callbacks */
@@ -3189,27 +3329,28 @@ void EM_select_swap(EditMesh *em) /* exported for UV */
 
 }
 
-static int select_invert_mesh_exec(bContext *C, wmOperator *op)
+static int select_inverse_mesh_exec(bContext *C, wmOperator *op)
 {
        Object *obedit= CTX_data_edit_object(C);
        EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data));
        
        EM_select_swap(em);
        
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+       WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
 
        BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;       
 }
 
-void MESH_OT_select_invert(wmOperatorType *ot)
+void MESH_OT_select_inverse(wmOperatorType *ot)
 {
        /* identifiers */
-       ot->name= "Select Invert";
-       ot->idname= "MESH_OT_select_invert";
+       ot->name= "Select Inverse";
+       ot->description= "Select inverse of (un)selected vertices, edges or faces.";
+       ot->idname= "MESH_OT_select_inverse";
        
        /* api callbacks */
-       ot->exec= select_invert_mesh_exec;
+       ot->exec= select_inverse_mesh_exec;
        ot->poll= ED_operator_editmesh;
        
        /* flags */
@@ -3226,31 +3367,58 @@ void EM_toggle_select_all(EditMesh *em) /* exported for UV */
                EM_set_flag_all(em, SELECT);
 }
 
-static int toggle_select_all_exec(bContext *C, wmOperator *op)
+void EM_select_all(EditMesh *em)
+{
+       EM_set_flag_all(em, SELECT);
+}
+
+void EM_deselect_all(EditMesh *em)
+{
+       EM_clear_flag_all(em, SELECT);
+}
+
+static int select_all_exec(bContext *C, wmOperator *op)
 {
        Object *obedit= CTX_data_edit_object(C);
        EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data));
+       int action = RNA_enum_get(op->ptr, "action");
        
-       EM_toggle_select_all(em);
+       switch (action) {
+       case SEL_TOGGLE:
+               EM_toggle_select_all(em);
+               break;
+       case SEL_SELECT:
+               EM_select_all(em);
+               break;
+       case SEL_DESELECT:
+               EM_deselect_all(em);
+               break;
+       case SEL_INVERT:
+               EM_select_swap(em);
+               break;
+       }
        
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);     
+       WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);      
        BKE_mesh_end_editmesh(obedit->data, em);
 
        return OPERATOR_FINISHED;
 }
 
-void MESH_OT_select_all_toggle(wmOperatorType *ot)
+void MESH_OT_select_all(wmOperatorType *ot)
 {
        /* identifiers */
-       ot->name= "Select or Deselect All";
-       ot->idname= "MESH_OT_select_all_toggle";
+       ot->name= "Select/Deselect All";
+       ot->description= "Change selection of all vertices, edges or faces.";
+       ot->idname= "MESH_OT_select_all";
        
        /* api callbacks */
-       ot->exec= toggle_select_all_exec;
+       ot->exec= select_all_exec;
        ot->poll= ED_operator_editmesh;
        
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+       WM_operator_properties_select_all(ot);
 }
 
 /* ******************** **************** */
@@ -3303,7 +3471,7 @@ static int select_more(bContext *C, wmOperator *op)
 
 //     if (EM_texFaceCheck(em))
 
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+       WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
 
        BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;
@@ -3313,6 +3481,7 @@ void MESH_OT_select_more(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Select More";
+       ot->description= "Select more vertices, edges or faces connected to initial selection.";
        ot->idname= "MESH_OT_select_more";
 
        /* api callbacks */
@@ -3392,7 +3561,7 @@ static int select_less(bContext *C, wmOperator *op)
        EM_select_less(em);
 
 //     if (EM_texFaceCheck(em))
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+       WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
 
        BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;
@@ -3402,6 +3571,7 @@ void MESH_OT_select_less(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Select Less";
+       ot->description= "Select less vertices, edges or faces connected to initial selection.";
        ot->idname= "MESH_OT_select_less";
 
        /* api callbacks */
@@ -3412,14 +3582,11 @@ void MESH_OT_select_less(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
-static void selectrandom_mesh(EditMesh *em, float perc) /* randomly selects a user-set % of vertices/edges/faces */
+static void selectrandom_mesh(EditMesh *em, float randfac) /* randomly selects a user-set % of vertices/edges/faces */
 {
        EditVert *eve;
        EditEdge *eed;
        EditFace *efa;
-       float randfac= perc;
-       /* Get the percentage of vertices to randomly select as 'randfac' */
-// XXX if(button(&randfac,0, 100,"Percentage:")==0) return;
 
        BLI_srand( BLI_rand() ); /* random seed */
        
@@ -3459,9 +3626,12 @@ static int mesh_select_random_exec(bContext *C, wmOperator *op)
        Object *obedit= CTX_data_edit_object(C);
        EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data));
        
-       selectrandom_mesh(em, RNA_float_get(op->ptr,"percent"));
+       if(!RNA_boolean_get(op->ptr, "extend"))
+               EM_deselect_all(em);
+       
+       selectrandom_mesh(em, RNA_float_get(op->ptr, "percent")/100.0f);
                
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+       WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
        
        BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;       
@@ -3471,6 +3641,7 @@ void MESH_OT_select_random(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Select Random";
+       ot->description= "Randomly select vertices.";
        ot->idname= "MESH_OT_select_random";
 
        /* api callbacks */
@@ -3481,10 +3652,11 @@ void MESH_OT_select_random(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
        
        /* props */
-       RNA_def_float_percentage(ot->srna, "percent", 0.5f, 0.0f, 1.0f, "Percent", "Percentage of vertices to select randomly.", 0.0001f, 1.0f);
+       RNA_def_float_percentage(ot->srna, "percent", 50.f, 0.0f, 100.0f, "Percent", "Percentage of elements to select randomly.", 0.f, 100.0f);
+       RNA_def_boolean(ot->srna, "extend", FALSE, "Extend Selection", "Extend selection instead of deselecting everything first.");
 }
 
-void editmesh_select_by_material(EditMesh *em, int index) 
+void EM_select_by_material(EditMesh *em, int index) 
 {
        EditFace *efa;
        
@@ -3497,7 +3669,7 @@ void editmesh_select_by_material(EditMesh *em, int index)
        EM_selectmode_flush(em);
 }
 
-void editmesh_deselect_by_material(EditMesh *em, int index) 
+void EM_deselect_by_material(EditMesh *em, int index) 
 {
        EditFace *efa;
        
@@ -3510,48 +3682,32 @@ void editmesh_deselect_by_material(EditMesh *em, int index)
        EM_selectmode_flush(em);
 }
 
-static void mesh_selection_type(Scene *scene, EditMesh *em, int val)
+static void mesh_selection_type(ToolSettings *ts, EditMesh *em, int val)
 {
        if(val>0) {
-               if(val==1) { 
-                       em->selectmode= SCE_SELECT_VERTEX;
-                       EM_selectmode_set(em);
-               }
-               else if(val==2) {
-                       //if(ctrl) EM_convertsel(em, em->selectmode, SCE_SELECT_EDGE);
-                       em->selectmode= SCE_SELECT_EDGE;
-                       EM_selectmode_set(em);
-               }
-               
-               else{
-                       //if((ctrl)) EM_convertsel(em, em->selectmode, SCE_SELECT_FACE);
-                       em->selectmode= SCE_SELECT_FACE;
-                       EM_selectmode_set(em);
-               }
+               //if(ctrl) EM_convertsel(em, em->selectmode, SCE_SELECT_EDGE);
+               //if((ctrl)) EM_convertsel(em, em->selectmode, SCE_SELECT_FACE);
+
+               em->selectmode= val;
+               EM_selectmode_set(em);
                
                /* note, em stores selectmode to be able to pass it on everywhere without scene,
                   this is only until all select modes and toolsettings are settled more */
-               scene->selectmode= em->selectmode;
+               ts->selectmode= em->selectmode;
 //             if (EM_texFaceCheck())
        }
 }
 
-static EnumPropertyItem prop_mesh_edit_types[] = {
-       {1, "VERT", 0, "Vertices", ""},
-       {2, "EDGE", 0, "Edges", ""},
-       {3, "FACE", 0, "Faces", ""},
-       {0, NULL, 0, NULL, NULL}
-};
-
 static int mesh_selection_type_exec(bContext *C, wmOperator *op)
 {              
-       
+       ToolSettings *ts= CTX_data_tool_settings(C);
        Object *obedit= CTX_data_edit_object(C);
        EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data));
 
-       mesh_selection_type(CTX_data_scene(C), em, RNA_enum_get(op->ptr,"type"));
+       mesh_selection_type(ts, em, RNA_enum_get(op->ptr,"type"));
 
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+       WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
+       WM_event_add_notifier(C, NC_SCENE|ND_MODE, NULL); /* header redraw */
        
        BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;
@@ -3561,6 +3717,7 @@ void MESH_OT_selection_type(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Selection Mode";
+       ot->description= "Set the selection mode type.";
        ot->idname= "MESH_OT_selection_type";
        
        /* api callbacks */
@@ -3570,10 +3727,10 @@ void MESH_OT_selection_type(wmOperatorType *ot)
        ot->poll= ED_operator_editmesh;
        
        /* flags */
-       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+       ot->flag= OPTYPE_UNDO;
        
        /* props */
-       RNA_def_enum(ot->srna, "type", prop_mesh_edit_types, 0, "Type", "Set the mesh selection type");
+       RNA_def_enum(ot->srna, "type", mesh_select_mode_items, 0, "Type", "Set the mesh selection type");
        
 }
 /* ************************* SEAMS AND EDGES **************** */
@@ -3610,16 +3767,19 @@ static int editmesh_mark_seam(bContext *C, wmOperator *op)
                }
        }
 
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
-
        BKE_mesh_end_editmesh(obedit->data, em);
+
+       DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+       WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
+
        return OPERATOR_FINISHED;
 }
 
 void MESH_OT_mark_seam(wmOperatorType *ot)
 {
        /* identifiers */
-       ot->name= "Mark seam";
+       ot->name= "Mark Seam";
+       ot->description= "(un)mark selected edges as a seam.";
        ot->idname= "MESH_OT_mark_seam";
        
        /* api callbacks */
@@ -3637,15 +3797,15 @@ static int editmesh_mark_sharp(bContext *C, wmOperator *op)
        Object *obedit= CTX_data_edit_object(C);
        EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data));
        Mesh *me= ((Mesh *)obedit->data);
-       int set = RNA_boolean_get(op->ptr, "set");
+       int clear = RNA_boolean_get(op->ptr, "clear");
        EditEdge *eed;
 
        /* auto-enable sharp edge drawing */
-       if(set) {
+       if(clear == 0) {
                me->drawflag |= ME_DRAWSHARP;
        }
 
-       if(set) {
+       if(!clear) {
                eed= em->edges.first;
                while(eed) {
                        if(!eed->h && (eed->f & SELECT)) eed->sharp = 1;
@@ -3659,16 +3819,19 @@ static int editmesh_mark_sharp(bContext *C, wmOperator *op)
                }
        }
 
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
-
        BKE_mesh_end_editmesh(obedit->data, em);
+
+       DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+       WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
+
        return OPERATOR_FINISHED;
 }
 
 void MESH_OT_mark_sharp(wmOperatorType *ot)
 {
        /* identifiers */
-       ot->name= "Mark sharp";
+       ot->name= "Mark Sharp";
+       ot->description= "(un)mark selected edges as sharp.";
        ot->idname= "MESH_OT_mark_sharp";
        
        /* api callbacks */
@@ -3678,167 +3841,9 @@ void MESH_OT_mark_sharp(wmOperatorType *ot)
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
        
-       RNA_def_boolean(ot->srna, "set", 0, "Set", "");
-}
-
-void BME_Menu()        {
-       short ret;
-       ret= pupmenu("BME modeller%t|Select Edges of Vert%x1");
-       
-       switch(ret)
-       {
-               case 1:
-               //BME_edges_of_vert();
-               break;
-       }
-}
-
-
-
-void Vertex_Menu(EditMesh *em) 
-{
-       short ret;
-       ret= pupmenu("Vertex Specials%t|Remove Doubles%x1|Merge%x2|Smooth %x3|Select Vertex Path%x4|Blend From Shape%x5|Propagate To All Shapes%x6");
-
-       switch(ret)
-       {
-               case 1:
-// XXX                 notice("Removed %d Vertices", removedoublesflag(1, 0, scene->toolsettings->doublimit));
-                       break;
-               case 2: 
-// XXX                 mergemenu(em);
-                       break;
-               case 3:
-// XXX                 vertexsmooth(em);
-                       break;
-               case 4:
-// XXX                 pathselect(em);
-                       break;
-               case 5: 
-// XXX                 shape_copy_select_from(em);
-                       break;
-               case 6: 
-// XXX                 shape_propagate(em);
-                       break;
-       }
-       /* some items crashed because this is in the original W menu but not here. should really manage this better */
-//     DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
-}
-
-
-void Edge_Menu(EditMesh *em) 
-{
-       short ret;
-
-       ret= pupmenu("Edge Specials%t|Mark Seam %x1|Clear Seam %x2|Rotate Edge CW%x3|Rotate Edge CCW%x4|Loopcut%x6|Edge Slide%x5|Edge Loop Select%x7|Edge Ring Select%x8|Loop to Region%x9|Region to Loop%x10|Mark Sharp%x11|Clear Sharp%x12");
-
-       switch(ret)
-       {
-       case 1:
-               //editmesh_mark_seam(em, 0);
-               break;
-       case 2:
-               //editmesh_mark_seam(em, 1);
-               break;
-       case 3:
-//             edge_rotate_selected(em, 2);
-               break;
-       case 4:
-//             edge_rotate_selected(em, 1);
-               break;
-       case 5:
-//             EdgeSlide(em, 0,0.0);
-               break;
-       case 6:
-//             CutEdgeloop(em, 1);
-               break;
-       case 7:
-//             loop_multiselect(em, 0);
-               break;
-       case 8:
-//             loop_multiselect(em, 1);
-               break;
-       case 9:
-//             loop_to_region(em);
-               break;
-       case 10:
-//             region_to_loop(em);
-               break;
-       case 11:
-//             editmesh_mark_sharp(em, 1);
-//             DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
-               break;
-       case 12: 
-//             editmesh_mark_sharp(em, 0);
-//             DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
-               break;
-       }
-       /* some items crashed because this is in the original W menu but not here. should really manage this better */
-//     DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
-}
-
-void Face_Menu(EditMesh *em) 
-{
-       short ret;
-       ret= pupmenu(
-               "Face Specials%t|Flip Normals%x1|Bevel%x2|Shade Smooth%x3|Shade Flat%x4|"
-               "Triangulate (Ctrl T)%x5|Quads from Triangles (Alt J)%x6|Flip Triangle Edges (Ctrl Shift F)%x7|%l|"
-               "Face Mode Set%x8|Face Mode Clear%x9|%l|"
-               "UV Rotate (Shift - CCW)%x10|UV Mirror (Shift - Switch Axis)%x11|"
-               "Color Rotate (Shift - CCW)%x12|Color Mirror (Shift - Switch Axis)%x13");
-
-       switch(ret)
-       {
-               case 1:
-//                     flip_editnormals(em);
-//                     DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
-                       break;
-               case 2:
-//                     bevel_menu(em);
-                       break;
-               case 3:
-//                     mesh_set_smooth_faces(em, 1);
-                       break;
-               case 4:
-//                     mesh_set_smooth_faces(em, 0);
-                       break;
-                       
-               case 5: /* Quads to Tris */
-//                     convert_to_triface(em, 0);
-//                     DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
-                       break;
-               case 6: /* Tris to Quads */
-//                     join_triangles(em);
-                       break;
-               case 7: /* Flip triangle edges */
-//                     edge_flip(em);
-                       break;
-               case 8:
-//                     mesh_set_face_flags(em, 1);
-                       break;
-               case 9:
-//                     mesh_set_face_flags(em, 0);
-                       break;
-                       
-               /* uv texface options */
-               case 10:
-//                     mesh_rotate_uvs(em);
-                       break;
-               case 11:
-//                     mesh_mirror_uvs(em);
-                       break;
-               case 12:
-//                     mesh_rotate_colors(em);
-                       break;
-               case 13:
-//                     mesh_mirror_colors(em);
-                       break;
-       }
-       /* some items crashed because this is in the original W menu but not here. should really manage this better */
-//     DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+       RNA_def_boolean(ot->srna, "clear", 0, "Clear", "");
 }
 
-
 /* **************** NORMALS ************** */
 
 /* XXX value of select is messed up, it means two things */
@@ -3899,7 +3904,7 @@ void righthandfaces(EditMesh *em, int select)     /* makes faces righthand turning *
 
                while(efa) {
                        if(efa->f1) {
-                               CalcCent3f(cent, efa->v1->co, efa->v2->co, efa->v3->co);
+                               cent_tri_v3(cent, efa->v1->co, efa->v2->co, efa->v3->co);
                                cent[0]= cent[0]*cent[0] + cent[1]*cent[1] + cent[2]*cent[2];
                                
                                if(cent[0]>maxx) {
@@ -3908,7 +3913,7 @@ void righthandfaces(EditMesh *em, int select)     /* makes faces righthand turning *
                                        tria_nr= 0;
                                }
                                if(efa->v4) {
-                                       CalcCent3f(cent, efa->v1->co, efa->v3->co, efa->v4->co);
+                                       cent_tri_v3(cent, efa->v1->co, efa->v3->co, efa->v4->co);
                                        cent[0]= cent[0]*cent[0] + cent[1]*cent[1] + cent[2]*cent[2];
                                        
                                        if(cent[0]>maxx) {
@@ -3927,11 +3932,11 @@ void righthandfaces(EditMesh *em, int select)   /* makes faces righthand turning *
                /* set first face correct: calc normal */
                
                if(tria_nr==1) {
-                       CalcNormFloat(startvl->v1->co, startvl->v3->co, startvl->v4->co, nor);
-                       CalcCent3f(cent, startvl->v1->co, startvl->v3->co, startvl->v4->co);
+                       normal_tri_v3( nor,startvl->v1->co, startvl->v3->co, startvl->v4->co);
+                       cent_tri_v3(cent, startvl->v1->co, startvl->v3->co, startvl->v4->co);
                } else {
-                       CalcNormFloat(startvl->v1->co, startvl->v2->co, startvl->v3->co, nor);
-                       CalcCent3f(cent, startvl->v1->co, startvl->v2->co, startvl->v3->co);
+                       normal_tri_v3( nor,startvl->v1->co, startvl->v2->co, startvl->v3->co);
+                       cent_tri_v3(cent, startvl->v1->co, startvl->v2->co, startvl->v3->co);
                }
                /* first normal is oriented this way or the other */
                if(select) {
@@ -4047,7 +4052,7 @@ void righthandfaces(EditMesh *em, int select)     /* makes faces righthand turning *
 
        recalc_editnormals(em);
        
-//     DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+//     DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
 
        waitcursor(0);
 }
@@ -4063,9 +4068,11 @@ static int righthandfaces_exec(bContext *C, wmOperator *op)
        // XXX  need other args
        righthandfaces(em, RNA_boolean_get(op->ptr, "inside"));
        
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); //TODO is this needed ?
-
        BKE_mesh_end_editmesh(obedit->data, em);
+
+       DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+       WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); //TODO is this needed ?
+
        return OPERATOR_FINISHED;       
 }
 
@@ -4073,6 +4080,7 @@ void MESH_OT_normals_make_consistent(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Make Normals Consistent";
+       ot->description= "Flip all selected vertex and face normals in a consistent direction.";
        ot->idname= "MESH_OT_normals_make_consistent";
        
        /* api callbacks */
@@ -4138,9 +4146,9 @@ void faceselect_align_view_to_selected(View3D *v3d, RegionView3D *rv3d, Mesh *me
                        v3= me->mvert[mf->v3].co;
                        if (mf->v4) {
                                float *v4= me->mvert[mf->v4].co;
-                               CalcNormFloat4(v1, v2, v3, v4, fno);
+                               normal_quad_v3( fno,v1, v2, v3, v4);
                        } else {
-                               CalcNormFloat(v1, v2, v3, fno);
+                               normal_tri_v3( fno,v1, v2, v3);
                        }
 
                        norm[0]+= fno[0];
@@ -4163,18 +4171,18 @@ static void face_getnormal_obspace(Object *obedit, EditFace *efa, float *fno)
        float vec[4][3];
        
        VECCOPY(vec[0], efa->v1->co);
-       Mat4Mul3Vecfl(obedit->obmat, vec[0]);
+       mul_mat3_m4_v3(obedit->obmat, vec[0]);
        VECCOPY(vec[1], efa->v2->co);
-       Mat4Mul3Vecfl(obedit->obmat, vec[1]);
+       mul_mat3_m4_v3(obedit->obmat, vec[1]);
        VECCOPY(vec[2], efa->v3->co);
-       Mat4Mul3Vecfl(obedit->obmat, vec[2]);
+       mul_mat3_m4_v3(obedit->obmat, vec[2]);
        if(efa->v4) {
                VECCOPY(vec[3], efa->v4->co);
-               Mat4Mul3Vecfl(obedit->obmat, vec[3]);
+               mul_mat3_m4_v3(obedit->obmat, vec[3]);
                
-               CalcNormFloat4(vec[0], vec[1], vec[2], vec[3], fno);
+               normal_quad_v3( fno,vec[0], vec[1], vec[2], vec[3]);
        }
-       else CalcNormFloat(vec[0], vec[1], vec[2], fno);
+       else normal_tri_v3( fno,vec[0], vec[1], vec[2]);
 }
 
 
@@ -4210,7 +4218,7 @@ void editmesh_align_view_to_selected(Object *obedit, EditMesh *em, wmOperator *o
                        if (eve->f & SELECT) {
                                if (leve) {
                                        float tno[3];
-                                       CalcNormFloat(cent, leve->co, eve->co, tno);
+                                       normal_tri_v3( tno,cent, leve->co, eve->co);
                                        
                                                /* XXX, fixme, should be flipped intp a 
                                                 * consistent direction. -zr
@@ -4223,7 +4231,7 @@ void editmesh_align_view_to_selected(Object *obedit, EditMesh *em, wmOperator *o
                        }
                }
 
-               Mat4Mul3Vecfl(obedit->obmat, norm);
+               mul_mat3_m4_v3(obedit->obmat, norm);
                view3d_align_axis_to_vector(v3d, rv3d, axis, norm);
        } 
        else if (nselverts==2) { /* Align view to edge (or 2 verts) */ 
@@ -4240,7 +4248,7 @@ void editmesh_align_view_to_selected(Object *obedit, EditMesh *em, wmOperator *o
                                leve= eve;
                        }
                }
-               Mat4Mul3Vecfl(obedit->obmat, norm);
+               mul_mat3_m4_v3(obedit->obmat, norm);
                view3d_align_axis_to_vector(v3d, rv3d, axis, norm);
        } 
        else if (nselverts==1) { /* Align view to vert normal */ 
@@ -4254,7 +4262,7 @@ void editmesh_align_view_to_selected(Object *obedit, EditMesh *em, wmOperator *o
                                break; /* we know this is the only selected vert, so no need to keep looking */
                        }
                }
-               Mat4Mul3Vecfl(obedit->obmat, norm);
+               mul_mat3_m4_v3(obedit->obmat, norm);
                view3d_align_axis_to_vector(v3d, rv3d, axis, norm);
        }
 } 
@@ -4263,22 +4271,14 @@ void editmesh_align_view_to_selected(Object *obedit, EditMesh *em, wmOperator *o
 
 static int smooth_vertex(bContext *C, wmOperator *op)
 {
-       Scene *scene= CTX_data_scene(C);
        Object *obedit= CTX_data_edit_object(C);
-       Mesh *me= obedit->data;
-       EditMesh *em= (EditMesh *)me; 
-
+       EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data));
        EditVert *eve, *eve_mir = NULL;
        EditEdge *eed;
        float *adror, *adr, fac;
        float fvec[3];
        int teller=0;
-       ModifierData *md= obedit->modifiers.first;
-
-       if(em==NULL) {
-               BKE_mesh_end_editmesh(obedit->data, em);
-               return OPERATOR_CANCELLED;
-       }
+       ModifierData *md;
 
        /* count */
        eve= em->verts.first;
@@ -4306,8 +4306,8 @@ static int smooth_vertex(bContext *C, wmOperator *op)
        /* if there is a mirror modifier with clipping, flag the verts that
         * are within tolerance of the plane(s) of reflection 
         */
-       for (; md; md=md->next) {
-               if (md->type==eModifierType_Mirror) {
+       for(md=obedit->modifiers.first; md; md=md->next) {
+               if(md->type==eModifierType_Mirror) {
                        MirrorModifierData *mmd = (MirrorModifierData*) md;     
                
                        if(mmd->flag & MOD_MIR_CLIPPING) {
@@ -4343,11 +4343,11 @@ static int smooth_vertex(bContext *C, wmOperator *op)
                        
                        if((eed->v1->f & SELECT) && eed->v1->f1<255) {
                                eed->v1->f1++;
-                               VecAddf(eed->v1->tmp.p, eed->v1->tmp.p, fvec);
+                               add_v3_v3v3(eed->v1->tmp.p, eed->v1->tmp.p, fvec);
                        }
                        if((eed->v2->f & SELECT) && eed->v2->f1<255) {
                                eed->v2->f1++;
-                               VecAddf(eed->v2->tmp.p, eed->v2->tmp.p, fvec);
+                               add_v3_v3v3(eed->v2->tmp.p, eed->v2->tmp.p, fvec);
                        }
                }
                eed= eed->next;
@@ -4358,7 +4358,7 @@ static int smooth_vertex(bContext *C, wmOperator *op)
                if(eve->f & SELECT) {
                        if(eve->f1) {
                                
-                               if (scene->toolsettings->editbutflag & B_MESH_X_MIRROR) {
+                               if (((Mesh *)obedit->data)->editflag & ME_EDIT_MIRROR_X) {
                                        eve_mir= editmesh_get_x_mirror_vert(obedit, em, eve->co);
                                }
                                
@@ -4398,11 +4398,25 @@ static int smooth_vertex(bContext *C, wmOperator *op)
 
        recalc_editnormals(em);
 
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+       BKE_mesh_end_editmesh(obedit->data, em);
 
-//     DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+       DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+       WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
+
+       return OPERATOR_FINISHED;
+}
+
+static int smooth_vertex_exec(bContext *C, wmOperator *op)
+{
+       int repeat = RNA_int_get(op->ptr, "repeat");
+       int i;
+
+       if (!repeat) repeat = 1;
+
+       for (i=0; i<repeat; i++) {
+               smooth_vertex(C, op);
+       }
 
-       BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;
 }
 
@@ -4410,14 +4424,17 @@ void MESH_OT_vertices_smooth(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Smooth Vertex";
+       ot->description= "Flatten angles of selected vertices.";
        ot->idname= "MESH_OT_vertices_smooth";
        
        /* api callbacks */
-       ot->exec= smooth_vertex;
+       ot->exec= smooth_vertex_exec;
        ot->poll= ED_operator_editmesh;
        
        /* flags */
-       ot->flag= OPTYPE_UNDO;
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+       RNA_def_int(ot->srna, "repeat", 1, 1, 100, "Smooth Iterations", "", 1, INT_MAX);
 }
 
 void vertexnoise(Object *obedit, EditMesh *em)
@@ -4449,7 +4466,7 @@ void vertexnoise(Object *obedit, EditMesh *em)
                                vec[1]= 0.2*(b2-BLI_hnoise(tex->noisesize, eve->co[0], eve->co[1]+ofs, eve->co[2]));
                                vec[2]= 0.2*(b2-BLI_hnoise(tex->noisesize, eve->co[0], eve->co[1], eve->co[2]+ofs));
                                
-                               VecAddf(eve->co, eve->co, vec);
+                               add_v3_v3v3(eve->co, eve->co, vec);
                        }
                        else {
                                float tin, dum;
@@ -4461,99 +4478,10 @@ void vertexnoise(Object *obedit, EditMesh *em)
        }
 
        recalc_editnormals(em);
-//     DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+//     DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
 
 }
 
-static void vertices_to_sphere(Scene *scene, View3D *v3d, Object *obedit, EditMesh *em, float perc)
-{
-       EditVert *eve;
-       float *curs, len, vec[3], cent[3], fac, facm, imat[3][3], bmat[3][3];
-       int tot;
-       
-// XXX if(button(&perc, 1, 100, "Percentage:")==0) return;
-       
-       fac= perc/100.0f;
-       facm= 1.0f-fac;
-       
-       Mat3CpyMat4(bmat, obedit->obmat);
-       Mat3Inv(imat, bmat);
-
-       /* center */
-       curs= give_cursor(scene, v3d);
-       cent[0]= curs[0]-obedit->obmat[3][0];
-       cent[1]= curs[1]-obedit->obmat[3][1];
-       cent[2]= curs[2]-obedit->obmat[3][2];
-       Mat3MulVecfl(imat, cent);
-
-       len= 0.0;
-       tot= 0;
-       eve= em->verts.first;
-       while(eve) {
-               if(eve->f & SELECT) {
-                       tot++;
-                       len+= VecLenf(cent, eve->co);
-               }
-               eve= eve->next;
-       }
-       len/=tot;
-       
-       if(len==0.0) len= 10.0;
-       
-       eve= em->verts.first;
-       while(eve) {
-               if(eve->f & SELECT) {
-                       vec[0]= eve->co[0]-cent[0];
-                       vec[1]= eve->co[1]-cent[1];
-                       vec[2]= eve->co[2]-cent[2];
-                       
-                       Normalize(vec);
-                       
-                       eve->co[0]= fac*(cent[0]+vec[0]*len) + facm*eve->co[0];
-                       eve->co[1]= fac*(cent[1]+vec[1]*len) + facm*eve->co[1];
-                       eve->co[2]= fac*(cent[2]+vec[2]*len) + facm*eve->co[2];
-                       
-               }
-               eve= eve->next;
-       }
-       
-       recalc_editnormals(em);
-//     DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
-
-}
-
-static int vertices_to_sphere_exec(bContext *C, wmOperator *op)
-{
-       Object *obedit= CTX_data_edit_object(C);
-       View3D *v3d = CTX_wm_view3d(C);
-       Scene *scene = CTX_data_scene(C);
-       EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data));
-       
-       vertices_to_sphere(scene, v3d, obedit, em, RNA_float_get(op->ptr,"percent"));
-               
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
-       
-       BKE_mesh_end_editmesh(obedit->data, em);
-       return OPERATOR_FINISHED;       
-}
-
-void MESH_OT_vertices_transform_to_sphere(wmOperatorType *ot)
-{
-       /* identifiers */
-       ot->name= "Vertices to Sphere";
-       ot->idname= "MESH_OT_vertices_transform_to_sphere";
-       
-       /* api callbacks */
-       ot->exec= vertices_to_sphere_exec;
-       ot->poll= ED_operator_editmesh;
-
-       /* flags */
-       ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/;
-       
-       /* props */
-       RNA_def_float(ot->srna, "percent", 100.0f, 0.0f, 100.0f, "Percent", "DOC_BROKEN", 0.01f, 100.0f);
-}
-
 void flipface(EditMesh *em, EditFace *efa)
 {
        if(efa->v4) {
@@ -4569,12 +4497,12 @@ void flipface(EditMesh *em, EditFace *efa)
                EM_data_interp_from_faces(em, efa, NULL, efa, 0, 2, 1, 3);
        }
 
-       if(efa->v4) CalcNormFloat4(efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co, efa->n);
-       else CalcNormFloat(efa->v1->co, efa->v2->co, efa->v3->co, efa->n);
+       if(efa->v4) normal_quad_v3( efa->n,efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co);
+       else normal_tri_v3( efa->n,efa->v1->co, efa->v2->co, efa->v3->co);
 }
 
 
-static int flip_editnormals(bContext *C, wmOperator *op)
+static int flip_normals(bContext *C, wmOperator *op)
 {
        Object *obedit= CTX_data_edit_object(C);
        EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data));
@@ -4592,19 +4520,25 @@ static int flip_editnormals(bContext *C, wmOperator *op)
        recalc_editnormals(em);
 
        BKE_mesh_end_editmesh(obedit->data, em);
+
+       DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+       WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
+
        return OPERATOR_FINISHED;
 }
 
-void MESH_OT_flip_editnormals(wmOperatorType *ot)
+void MESH_OT_flip_normals(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Flip Normals";
-       ot->idname= "MESH_OT_flip_editnormals";
+       ot->description= "Toggle the direction of selected face's vertex and face normals.";
+       ot->idname= "MESH_OT_flip_normals";
        
        /* api callbacks */
-       ot->exec= flip_editnormals;
+       ot->exec= flip_normals;
        ot->poll= ED_operator_editmesh;
        
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
+