whitespace only, no functional change mixed tabs/spaces --> tabs.
[blender.git] / source / blender / editors / mesh / editmesh_tools.c
index 92b4800ccfded2fc123ce83d8d6af5854c91b5ff..dc1023952a6f31f45076707d82e65704f1cf2c24 100644 (file)
@@ -1,4 +1,4 @@
- /* $Id:
+ /* $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -14,7 +14,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  *
  * The Original Code is Copyright (C) 2004 by Blender Foundation.
  * All rights reserved.
  * ***** END GPL LICENSE BLOCK *****
  */
 
+/** \file blender/editors/mesh/editmesh_tools.c
+ *  \ingroup edmesh
+ */
+
+
 /*
 
 editmesh_tool.c: UI called tools for editmesh, geometry changes here, otherwise in mods.c
@@ -37,48 +42,37 @@ editmesh_tool.c: UI called tools for editmesh, geometry changes here, otherwise
 #include <math.h>
 #include <float.h>
 
-#include "MEM_guardedalloc.h"
-#include "PIL_time.h"
-
 #include "BLO_sys_types.h" // for intptr_t support
 
-#include "DNA_mesh_types.h"
-#include "DNA_material_types.h"
 #include "DNA_meshdata_types.h"
 #include "DNA_modifier_types.h"
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
-#include "DNA_screen_types.h"
-#include "DNA_view3d_types.h"
 #include "DNA_key_types.h"
-#include "DNA_windowmanager_types.h"
 
-#include "RNA_types.h"
+#include "MEM_guardedalloc.h"
+
 #include "RNA_define.h"
 #include "RNA_access.h"
 
 #include "BLI_blenlib.h"
 #include "BLI_math.h"
+#include "BLI_utildefines.h"
 #include "BLI_editVert.h"
 #include "BLI_rand.h"
 #include "BLI_ghash.h"
 #include "BLI_linklist.h"
 #include "BLI_heap.h"
+#include "BLI_scanfill.h"
 
 #include "BKE_context.h"
-#include "BKE_customdata.h"
 #include "BKE_depsgraph.h"
 #include "BKE_global.h"
 #include "BKE_key.h"
-#include "BKE_library.h"
 #include "BKE_mesh.h"
-#include "BKE_object.h"
-#include "BKE_utildefines.h"
 #include "BKE_bmesh.h"
 #include "BKE_report.h"
 
-#include "BIF_gl.h"
-#include "BIF_glutil.h"
 
 #include "WM_api.h"
 #include "WM_types.h"
@@ -86,20 +80,27 @@ editmesh_tool.c: UI called tools for editmesh, geometry changes here, otherwise
 #include "ED_mesh.h"
 #include "ED_screen.h"
 #include "ED_transform.h"
-#include "ED_util.h"
 #include "ED_view3d.h"
+#include "ED_object.h"
 
-#include "UI_interface.h"
 
 #include "mesh_intern.h"
 
 /* XXX */
-static void waitcursor(int val) {}
-static int pupmenu() {return 0;}
+static void waitcursor(int UNUSED(val)) {}
 #define add_numbut(a, b, c, d, e, f, g) {}
 
 /* XXX */
 
+/* RNA corner cut enum property - used in multiple files for tools
+ * that need this property for esubdivideflag() */
+EnumPropertyItem corner_type_items[] = {
+       {SUBDIV_CORNER_PATH,  "PATH", 0, "Path", ""},
+       {SUBDIV_CORNER_INNERVERT,  "INNER_VERTEX", 0, "Inner Vertex", ""},
+       {SUBDIV_CORNER_FAN,  "FAN",  0, "Fan", ""},
+       {0, NULL, 0, NULL, NULL}};
+
+
 /* local prototypes ---------------*/
 static void free_tagged_edges_faces(EditMesh *em, EditEdge *eed, EditFace *efa);
 int EdgeLoopDelete(EditMesh *em, wmOperator *op);
@@ -482,28 +483,30 @@ static int removedoublesflag_exec(bContext *C, wmOperator *op)
 {
        Object *obedit= CTX_data_edit_object(C);
        EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data));
-       /*char msg[100];*/
 
-       /*int cnt =*/ removedoublesflag(em,1,0,RNA_float_get(op->ptr, "limit"));
-       /*XXX this messes up last operator panel
-       if(cnt)
-       {
-               sprintf(msg, "Removed %d vertices", cnt);
-               BKE_report(op->reports, RPT_INFO, msg);
-       }*/
+       int count = removedoublesflag(em,1,0,RNA_float_get(op->ptr, "limit"));
+       
+       if(count) {
+               recalc_editnormals(em);
 
-       DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
-       WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
+               DAG_id_tag_update(obedit->data, 0);
+               WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
+       }
+
+       BKE_reportf(op->reports, RPT_INFO, "Removed %d vert%s.", count, (count==1)?"ex":"ices");
 
        BKE_mesh_end_editmesh(obedit->data, em);
+
        return OPERATOR_FINISHED;
 }
 
 void MESH_OT_remove_doubles(wmOperatorType *ot)
 {
+       PropertyRNA *prop;
+
        /* identifiers */
        ot->name= "Remove Doubles";
-       ot->description= "Remove duplicate vertices.";
+       ot->description= "Remove duplicate vertices";
        ot->idname= "MESH_OT_remove_doubles";
 
        /* api callbacks */
@@ -513,12 +516,13 @@ void MESH_OT_remove_doubles(wmOperatorType *ot)
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 
-       RNA_def_float(ot->srna, "limit", 0.0001f, 0.000001f, 50.0f, "Merge Threshold", "Minimum distance between merged verts", 0.00001f, 2.0f);
+       prop= RNA_def_float(ot->srna, "limit", 0.0001f, 0.000001f, 50.0f, "Merge Threshold", "Minimum distance between merged verts", 0.00001f, 2.0f);
+       RNA_def_property_ui_range(prop,  0.000001f, 50.0f, 0.001, 5);
 }
 
 // XXX is this needed?
 /* called from buttons */
-static void xsortvert_flag__doSetX(void *userData, EditVert *eve, int x, int y, int index)
+static void xsortvert_flag__doSetX(void *userData, EditVert *UNUSED(eve), int x, int UNUSED(y), int index)
 {
        xvertsort *sortblock = userData;
 
@@ -526,7 +530,7 @@ static void xsortvert_flag__doSetX(void *userData, EditVert *eve, int x, int y,
 }
 
 /* all verts with (flag & 'flag') are sorted */
-void xsortvert_flag(bContext *C, int flag)
+static void xsortvert_flag(bContext *C, int flag)
 {
        ViewContext vc;
        EditVert *eve;
@@ -558,14 +562,37 @@ void xsortvert_flag(bContext *C, int flag)
                }
        }
 
-       addlisttolist(&vc.em->verts, &tbase);
+       BLI_movelisttolist(&vc.em->verts, &tbase);
 
        MEM_freeN(sortblock);
 
 }
 
+static int mesh_vertices_sort_exec(bContext *C, wmOperator *UNUSED(op))
+{
+       xsortvert_flag(C, SELECT);
+       return OPERATOR_FINISHED;
+}
+
+void MESH_OT_vertices_sort(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Vertex Sort";
+       ot->description= "Sort vertex order";
+       ot->idname= "MESH_OT_vertices_sort";
+
+       /* api callbacks */
+       ot->exec= mesh_vertices_sort_exec;
+
+       ot->poll= EM_view3d_poll; /* uses view relative X axis to sort verts */
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+
 /* called from buttons */
-void hashvert_flag(EditMesh *em, int flag)
+static void hashvert_flag(EditMesh *em, int flag)
 {
        /* switch vertex order using hash table */
        EditVert *eve;
@@ -616,57 +643,54 @@ void hashvert_flag(EditMesh *em, int flag)
                sb++;
        }
 
-       addlisttolist(&em->verts, &tbase);
+       BLI_movelisttolist(&em->verts, &tbase);
 
        MEM_freeN(sortblock);
 
 }
 
+static int mesh_vertices_randomize_exec(bContext *C, wmOperator *UNUSED(op))
+{
+       Object *obedit= CTX_data_edit_object(C);
+       EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data);
+       hashvert_flag(em, SELECT);
+       return OPERATOR_FINISHED;
+}
+
+void MESH_OT_vertices_randomize(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Vertex Randomize";
+       ot->description= "Randomize vertex order";
+       ot->idname= "MESH_OT_vertices_randomize";
+
+       /* api callbacks */
+       ot->exec= mesh_vertices_randomize_exec;
+
+       ot->poll= ED_operator_editmesh;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+
 /* generic extern called extruder */
-void extrude_mesh(Scene *scene, Object *obedit, EditMesh *em, wmOperator *op)
+static void extrude_mesh(Object *obedit, EditMesh *em, wmOperator *op, short type)
 {
        float nor[3]= {0.0, 0.0, 0.0};
-       short nr, transmode= 0;
-
-       /* extrude depends on totvertsel etc */
-       EM_stats_update(em);
-       
-       if(em->selectmode & SCE_SELECT_VERTEX) {
-               if(em->totvertsel==0) nr= 0;
-               else if(em->totvertsel==1) nr= 4;
-               else if(em->totedgesel==0) nr= 4;
-               else if(em->totfacesel==0)
-                       nr= 3; // pupmenu("Extrude %t|Only Edges%x3|Only Vertices%x4");
-               else if(em->totfacesel==1)
-                       nr= 1; // pupmenu("Extrude %t|Region %x1|Only Edges%x3|Only Vertices%x4");
-               else
-                       nr= 1; // pupmenu("Extrude %t|Region %x1||Individual Faces %x2|Only Edges%x3|Only Vertices%x4");
-       }
-       else if(em->selectmode & SCE_SELECT_EDGE) {
-               if (em->totedgesel==0) nr = 0;
-               else if (em->totedgesel==1) nr = 3;
-               else if(em->totfacesel==0) nr = 3;
-               else if(em->totfacesel==1)
-                       nr= 1; // pupmenu("Extrude %t|Region %x1|Only Edges%x3");
-               else
-                       nr= 1; // pupmenu("Extrude %t|Region %x1||Individual Faces %x2|Only Edges%x3");
-       }
-       else {
-               if (em->totfacesel == 0) nr = 0;
-               else if (em->totfacesel == 1) nr = 1;
-               else
-                       nr= 1; // pupmenu("Extrude %t|Region %x1||Individual Faces %x2");
-       }
+       short transmode= 0;
 
-       if(nr<1) return;
+       if(type<1) return;
 
-       if(nr==1)  transmode= extrudeflag(obedit, em, SELECT, nor, 0);
-       else if(nr==4) transmode= extrudeflag_verts_indiv(em, SELECT, nor);
-       else if(nr==3) transmode= extrudeflag_edges_indiv(em, SELECT, nor);
+       if(type==1)  transmode= extrudeflag(obedit, em, SELECT, nor, 0);
+       else if(type==4) transmode= extrudeflag_verts_indiv(em, SELECT, nor);
+       else if(type==3) transmode= extrudeflag_edges_indiv(em, SELECT, nor);
        else transmode= extrudeflag_face_indiv(em, SELECT, nor);
 
+       EM_stats_update(em);
+
        if(transmode==0) {
-               BKE_report(op->reports, RPT_ERROR, "Not a valid selection for extrude");
+               BKE_report(op->reports, RPT_WARNING, "Not a valid selection for extrude");
        }
        else {
                EM_fgon_flags(em);
@@ -677,12 +701,11 @@ void extrude_mesh(Scene *scene, Object *obedit, EditMesh *em, wmOperator *op)
                        * This shouldn't be necessary, derived queries should be
                        * automatically building this data if invalid. Or something.
                        */
-//             DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
-               object_handle_update(scene, obedit);
+               DAG_id_tag_update(obedit->data, 0);
 
                /* individual faces? */
 //             BIF_TransformSetUndo("Extrude");
-               if(nr==2) {
+               if(type==2) {
 //                     initTransform(TFM_SHRINKFATTEN, CTX_NO_PET|CTX_NO_MIRROR);
 //                     Transform();
                }
@@ -690,7 +713,7 @@ void extrude_mesh(Scene *scene, Object *obedit, EditMesh *em, wmOperator *op)
 //                     initTransform(TFM_TRANSLATION, CTX_NO_PET|CTX_NO_MIRROR);
                        if(transmode=='n') {
                                mul_m4_v3(obedit->obmat, nor);
-                               sub_v3_v3v3(nor, nor, obedit->obmat[3]);
+                               sub_v3_v3(nor, obedit->obmat[3]);
 //                             BIF_setSingleAxisConstraint(nor, "along normal");
                        }
 //                     Transform();
@@ -700,17 +723,16 @@ void extrude_mesh(Scene *scene, Object *obedit, EditMesh *em, wmOperator *op)
 }
 
 // XXX should be a menu item
-static int mesh_extrude_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int mesh_extrude_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
 {
-       Scene *scene= CTX_data_scene(C);
        Object *obedit= CTX_data_edit_object(C);
        EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data);
        
-       extrude_mesh(scene, obedit, em, op);
+       extrude_mesh(obedit, em, op, RNA_enum_get(op->ptr, "type"));
 
        BKE_mesh_end_editmesh(obedit->data, em);
 
-       DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+       DAG_id_tag_update(obedit->data, 0);
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
 
        return OPERATOR_FINISHED;
@@ -719,25 +741,101 @@ static int mesh_extrude_invoke(bContext *C, wmOperator *op, wmEvent *event)
 /* extrude without transform */
 static int mesh_extrude_exec(bContext *C, wmOperator *op)
 {
-       Scene *scene= CTX_data_scene(C);
        Object *obedit= CTX_data_edit_object(C);
        EditMesh *em= BKE_mesh_get_editmesh(obedit->data);
 
-       extrude_mesh(scene, obedit, em, op);
+       extrude_mesh(obedit, em, op, RNA_enum_get(op->ptr, "type"));
 
-       DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+       DAG_id_tag_update(obedit->data, 0);
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
 
        BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;
 }
 
+static EnumPropertyItem extrude_items[] = {
+               {1, "REGION", 0, "Region", ""},
+               {2, "FACES", 0, "Individual Faces", ""},
+               {3, "EDGES", 0, "Only Edges", ""},
+               {4, "VERTS", 0, "Only Vertices", ""},
+               {0, NULL, 0, NULL, NULL}};
+
+
+static EnumPropertyItem *mesh_extrude_itemf(bContext *C, PointerRNA *UNUSED(ptr), int *free)
+{
+       EnumPropertyItem *item= NULL;
+       Object *obedit= CTX_data_edit_object(C);
+       EditMesh *em;
+
+       int totitem= 0;
+
+       if(obedit==NULL || obedit->type != OB_MESH)
+               return extrude_items;
+
+       em = BKE_mesh_get_editmesh(obedit->data);
+
+       EM_stats_update(em);
+
+       if(em->selectmode & SCE_SELECT_VERTEX) {
+               if(em->totvertsel==0) {}
+               else if(em->totvertsel==1) { RNA_enum_item_add(&item, &totitem, &extrude_items[3]); }
+               else if(em->totedgesel==0) { RNA_enum_item_add(&item, &totitem, &extrude_items[3]); }
+               else if(em->totfacesel==0) {
+                       RNA_enum_item_add(&item, &totitem, &extrude_items[2]);
+                       RNA_enum_item_add(&item, &totitem, &extrude_items[3]);
+               }
+               else if(em->totfacesel==1) {
+                       RNA_enum_item_add(&item, &totitem, &extrude_items[0]);
+                       RNA_enum_item_add(&item, &totitem, &extrude_items[2]);
+                       RNA_enum_item_add(&item, &totitem, &extrude_items[3]);
+               }
+               else {
+                       RNA_enum_item_add(&item, &totitem, &extrude_items[0]);
+                       RNA_enum_item_add(&item, &totitem, &extrude_items[1]);
+                       RNA_enum_item_add(&item, &totitem, &extrude_items[2]);
+                       RNA_enum_item_add(&item, &totitem, &extrude_items[3]);
+               }
+       }
+       else if(em->selectmode & SCE_SELECT_EDGE) {
+               if (em->totedgesel==0) {}
+               else if (em->totedgesel==1) { RNA_enum_item_add(&item, &totitem, &extrude_items[2]); }
+               else if(em->totfacesel==0) { RNA_enum_item_add(&item, &totitem, &extrude_items[2]); }
+               else if(em->totfacesel==1) {
+                       RNA_enum_item_add(&item, &totitem, &extrude_items[0]);
+                       RNA_enum_item_add(&item, &totitem, &extrude_items[2]);
+               }
+               else {
+                       RNA_enum_item_add(&item, &totitem, &extrude_items[0]);
+                       RNA_enum_item_add(&item, &totitem, &extrude_items[1]);
+                       RNA_enum_item_add(&item, &totitem, &extrude_items[2]);
+               }
+       }
+       else {
+               if (em->totfacesel == 0) {}
+               else if (em->totfacesel == 1) { RNA_enum_item_add(&item, &totitem, &extrude_items[0]); }
+               else {
+                       RNA_enum_item_add(&item, &totitem, &extrude_items[0]);
+                       RNA_enum_item_add(&item, &totitem, &extrude_items[1]);
+               }
+       }
+
+       if(item) {
+               RNA_enum_item_end(&item, &totitem);
+               *free= 1;
+               return item;
+       }
+       else {
+               return NULL;
+       }
+}
 
 void MESH_OT_extrude(wmOperatorType *ot)
 {
+       PropertyRNA *prop;
+
        /* identifiers */
        ot->name= "Extrude";
-       ot->description= "Extrude selected vertices, edges or faces.";
+       ot->description= "Extrude selected vertices, edges or faces";
        ot->idname= "MESH_OT_extrude";
 
        /* api callbacks */
@@ -747,9 +845,15 @@ void MESH_OT_extrude(wmOperatorType *ot)
 
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+       /* properties */
+       prop= RNA_def_enum(ot->srna, "type", extrude_items, 0, "Type", "");
+       RNA_def_property_flag(prop, PROP_HIDDEN);
+       RNA_def_enum_funcs(prop, mesh_extrude_itemf);
+       ot->prop= prop;
 }
 
-static int split_mesh(bContext *C, wmOperator *op)
+static int split_mesh(bContext *C, wmOperator *UNUSED(op))
 {
        Object *obedit= CTX_data_edit_object(C);
        EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data);
@@ -764,7 +868,7 @@ static int split_mesh(bContext *C, wmOperator *op)
 
        WM_cursor_wait(0);
 
-       DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+       DAG_id_tag_update(obedit->data, 0);
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
 
        BKE_mesh_end_editmesh(obedit->data, em);
@@ -775,7 +879,7 @@ void MESH_OT_split(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Split";
-       ot->description= "Split selected geometry into separate disconnected mesh.";
+       ot->description= "Split selected geometry into separate disconnected mesh";
        ot->idname= "MESH_OT_split";
 
        /* api callbacks */
@@ -824,7 +928,7 @@ static int extrude_repeat_mesh(bContext *C, wmOperator *op)
 
        EM_fgon_flags(em);
 
-       DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+       DAG_id_tag_update(obedit->data, 0);
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
 
        BKE_mesh_end_editmesh(obedit->data, em);
@@ -835,12 +939,12 @@ void MESH_OT_extrude_repeat(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Extrude Repeat Mesh";
-       ot->description= "Extrude selected vertices, edges or faces repeatedly.";
+       ot->description= "Extrude selected vertices, edges or faces repeatedly";
        ot->idname= "MESH_OT_extrude_repeat";
 
        /* api callbacks */
        ot->exec= extrude_repeat_mesh;
-       ot->poll= ED_operator_editmesh;
+       ot->poll= ED_operator_editmesh_region_view3d;
 
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -876,7 +980,7 @@ static int spin_mesh(bContext *C, wmOperator *op, float *dvec, int steps, float
        cent[2]-= obedit->obmat[3][2];
        mul_m3_v3(imat, cent);
 
-       phi= degr*M_PI/360.0;
+       phi= degr*(float)M_PI/360.0f;
        phi/= steps;
        if(ts->editbutflag & B_CLOCKWISE) phi= -phi;
 
@@ -928,7 +1032,7 @@ static int spin_mesh(bContext *C, wmOperator *op, float *dvec, int steps, float
 
                EM_fgon_flags(em);
 
-               DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+               DAG_id_tag_update(obedit->data, 0);
        }
 
        BKE_mesh_end_editmesh(obedit->data, em);
@@ -942,18 +1046,18 @@ static int spin_mesh_exec(bContext *C, wmOperator *op)
 
        ok= spin_mesh(C, op, NULL, RNA_int_get(op->ptr,"steps"), RNA_float_get(op->ptr,"degrees"), RNA_boolean_get(op->ptr,"dupli"));
        if(ok==0) {
-               BKE_report(op->reports, RPT_ERROR, "No valid vertices are selected");
+               BKE_report(op->reports, RPT_WARNING, "No valid vertices are selected");
                return OPERATOR_CANCELLED;
        }
 
-       DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+       DAG_id_tag_update(obedit->data, 0);
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
 
        return OPERATOR_FINISHED;
 }
 
 /* get center and axis, in global coords */
-static int spin_mesh_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int spin_mesh_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
 {
        Scene *scene = CTX_data_scene(C);
        View3D *v3d = CTX_wm_view3d(C);
@@ -969,7 +1073,7 @@ void MESH_OT_spin(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Spin";
-       ot->description= "Extrude selected vertices in a circle around the cursor in indicated viewport.";
+       ot->description= "Extrude selected vertices in a circle around the cursor in indicated viewport";
        ot->idname= "MESH_OT_spin";
 
        /* api callbacks */
@@ -981,11 +1085,11 @@ void MESH_OT_spin(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 
        /* props */
-       RNA_def_int(ot->srna, "steps", 9, 0, INT_MAX, "Steps", "Steps", 0, INT_MAX);
+       RNA_def_int(ot->srna, "steps", 9, 0, INT_MAX, "Steps", "Steps", 0, 128);
        RNA_def_boolean(ot->srna, "dupli", 0, "Dupli", "Make Duplicates");
        RNA_def_float(ot->srna, "degrees", 90.0f, -FLT_MAX, FLT_MAX, "Degrees", "Degrees", -360.0f, 360.0f);
 
-       RNA_def_float_vector(ot->srna, "center", 3, NULL, -FLT_MAX, FLT_MAX, "Center", "Center in global view space", -FLT_MAX, FLT_MAX);
+       RNA_def_float_vector_xyz(ot->srna, "center", 3, NULL, -FLT_MAX, FLT_MAX, "Center", "Center in global view space", -FLT_MAX, FLT_MAX);
        RNA_def_float_vector(ot->srna, "axis", 3, NULL, -1.0f, 1.0f, "Axis", "Axis in global view space", -FLT_MAX, FLT_MAX);
 
 }
@@ -1028,7 +1132,7 @@ static int screw_mesh_exec(bContext *C, wmOperator *op)
                }
        }
        if(v1==NULL || v2==NULL) {
-               BKE_report(op->reports, RPT_ERROR, "You have to select a string of connected vertices too");
+               BKE_report(op->reports, RPT_WARNING, "You have to select a string of connected vertices too");
                BKE_mesh_end_editmesh(obedit->data, em);
                return OPERATOR_CANCELLED;
        }
@@ -1040,28 +1144,26 @@ static int screw_mesh_exec(bContext *C, wmOperator *op)
 
        VECCOPY(nor, obedit->obmat[2]);
 
-       if(nor[0]*dvec[0]+nor[1]*dvec[1]+nor[2]*dvec[2]>0.000) {
-               dvec[0]= -dvec[0];
-               dvec[1]= -dvec[1];
-               dvec[2]= -dvec[2];
+       if(nor[0]*dvec[0]+nor[1]*dvec[1]+nor[2]*dvec[2]>0.0f) {
+               negate_v3(dvec);
        }
 
        if(spin_mesh(C, op, dvec, turns*steps, 360.0f*turns, 0)) {
-               DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+               DAG_id_tag_update(obedit->data, 0);
                WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
 
                BKE_mesh_end_editmesh(obedit->data, em);
                return OPERATOR_FINISHED;
        }
        else {
-               BKE_report(op->reports, RPT_ERROR, "No valid vertices are selected");
+               BKE_report(op->reports, RPT_WARNING, "No valid vertices are selected");
                BKE_mesh_end_editmesh(obedit->data, em);
                return OPERATOR_CANCELLED;
        }
 }
 
 /* get center and axis, in global coords */
-static int screw_mesh_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int screw_mesh_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
 {
        Scene *scene = CTX_data_scene(C);
        View3D *v3d = CTX_wm_view3d(C);
@@ -1077,7 +1179,7 @@ void MESH_OT_screw(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Screw";
-       ot->description= "Extrude selected vertices in screw-shaped rotation around the cursor in indicated viewport.";
+       ot->description= "Extrude selected vertices in screw-shaped rotation around the cursor in indicated viewport";
        ot->idname= "MESH_OT_screw";
 
        /* api callbacks */
@@ -1092,7 +1194,7 @@ void MESH_OT_screw(wmOperatorType *ot)
        RNA_def_int(ot->srna, "steps", 9, 0, INT_MAX, "Steps", "Steps", 0, 256);
        RNA_def_int(ot->srna, "turns", 1, 0, INT_MAX, "Turns", "Turns", 0, 256);
 
-       RNA_def_float_vector(ot->srna, "center", 3, NULL, -FLT_MAX, FLT_MAX, "Center", "Center in global view space", -FLT_MAX, FLT_MAX);
+       RNA_def_float_vector_xyz(ot->srna, "center", 3, NULL, -FLT_MAX, FLT_MAX, "Center", "Center in global view space", -FLT_MAX, FLT_MAX);
        RNA_def_float_vector(ot->srna, "axis", 3, NULL, -1.0f, 1.0f, "Axis", "Axis in global view space", -FLT_MAX, FLT_MAX);
 }
 
@@ -1142,19 +1244,19 @@ static void erase_vertices(EditMesh *em, ListBase *l)
        }
 }
 
-void delete_mesh(Object *obedit, EditMesh *em, wmOperator *op, int event)
+static void delete_mesh(EditMesh *em, wmOperator *op, int event)
 {
        EditFace *efa, *nextvl;
        EditVert *eve,*nextve;
        EditEdge *eed,*nexted;
        int count;
-       char *str="Erase";
+       /* const char *str="Erase"; */
 
 
        if(event<1) return;
 
        if(event==10 ) {
-               str= "Erase Vertices";
+               /* str= "Erase Vertices"; */
                erase_edges(em, &em->edges);
                erase_faces(em, &em->faces);
                erase_vertices(em, &em->verts);
@@ -1163,10 +1265,10 @@ void delete_mesh(Object *obedit, EditMesh *em, wmOperator *op, int event)
                if(!EdgeLoopDelete(em, op))
                        return;
 
-               str= "Erase Edge Loop";
+               /* str= "Erase Edge Loop"; */
        }
        else if(event==4) {
-               str= "Erase Edges & Faces";
+               /* str= "Erase Edges & Faces"; */
                efa= em->faces.first;
                while(efa) {
                        nextvl= efa->next;
@@ -1208,7 +1310,7 @@ void delete_mesh(Object *obedit, EditMesh *em, wmOperator *op, int event)
                }
        }
        else if(event==1) {
-               str= "Erase Edges";
+               /* str= "Erase Edges"; */
                // faces first
                efa= em->faces.first;
                while(efa) {
@@ -1253,18 +1355,18 @@ void delete_mesh(Object *obedit, EditMesh *em, wmOperator *op, int event)
 
        }
        else if(event==2) {
-               str="Erase Faces";
+               /* str="Erase Faces"; */
                delfaceflag(em, SELECT);
        }
        else if(event==3) {
-               str= "Erase All";
+               /* str= "Erase All"; */
                if(em->verts.first) free_vertlist(em, &em->verts);
                if(em->edges.first) free_edgelist(em, &em->edges);
                if(em->faces.first) free_facelist(em, &em->faces);
                if(em->selected.first) BLI_freelistN(&(em->selected));
        }
        else if(event==5) {
-               str= "Erase Only Faces";
+               /* str= "Erase Only Faces"; */
                efa= em->faces.first;
                while(efa) {
                        nextvl= efa->next;
@@ -1300,9 +1402,9 @@ static int delete_mesh_exec(bContext *C, wmOperator *op)
        if(type==6)
                return WM_operator_name_call(C, "MESH_OT_delete_edgeloop", WM_OP_EXEC_DEFAULT, NULL);
 
-       delete_mesh(obedit, em, op, type);
+       delete_mesh(em, op, type);
 
-       DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+       DAG_id_tag_update(obedit->data, 0);
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
 
        BKE_mesh_end_editmesh(obedit->data, em);
@@ -1313,7 +1415,7 @@ void MESH_OT_delete(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Delete";
-       ot->description= "Delete selected vertices, edges or faces.";
+       ot->description= "Delete selected vertices, edges or faces";
        ot->idname= "MESH_OT_delete";
 
        /* api callbacks */
@@ -1326,7 +1428,7 @@ void MESH_OT_delete(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 
        /*props */
-       RNA_def_enum(ot->srna, "type", prop_mesh_delete_types, 10, "Type", "Method used for deleting mesh data");
+       ot->prop= RNA_def_enum(ot->srna, "type", prop_mesh_delete_types, 10, "Type", "Method used for deleting mesh data");
 }
 
 
@@ -1372,7 +1474,7 @@ static void alter_co(float *co, EditEdge *edge, float smooth, float fractal, int
                vec1[2]+= fac*nor2[2];
 
                /* falloff for multi subdivide */
-               smooth *= sqrt(fabs(1.0f - 2.0f*fabs(0.5f-perc)));
+               smooth *= sqrtf(fabs(1.0f - 2.0f*fabsf(0.5f-perc)));
 
                vec1[0]*= smooth*len;
                vec1[1]*= smooth*len;
@@ -1394,7 +1496,7 @@ static void alter_co(float *co, EditEdge *edge, float smooth, float fractal, int
                vec1[0]= fac*(float)(0.5-BLI_drand());
                vec1[1]= fac*(float)(0.5-BLI_drand());
                vec1[2]= fac*(float)(0.5-BLI_drand());
-               add_v3_v3v3(co, co, vec1);
+               add_v3_v3(co, vec1);
        }
 }
 
@@ -1470,6 +1572,7 @@ static void facecopy(EditMesh *em, EditFace *source, EditFace *target)
        if (target->v4)
                interp_weights_face_v3( w[3],v1, v2, v3, v4, target->v4->co);
 
+       CustomData_em_validate_data(&em->fdata, target->data, target->v4 ? 4 : 3);
        CustomData_em_interp(&em->fdata, &source->data, NULL, (float*)w, 1, target->data);
 }
 
@@ -1545,16 +1648,16 @@ static void fill_quad_single(EditMesh *em, EditFace *efa, struct GHash *gh, int
                hold = addfacelist(em, verts[i],verts[i+1],v[right],NULL,NULL,NULL);
                facecopy(em, efa,hold);
                if(i+1 != (vertsize-1)/2) {
-            if(seltype == SUBDIV_SELECT_INNER) {
-                          hold->e2->f2 |= EDGEINNER;
-            }
+                       if(seltype == SUBDIV_SELECT_INNER) {
+                               hold->e2->f2 |= EDGEINNER;
+                       }
                }
                hold = addfacelist(em, verts[vertsize-2-i],verts[vertsize-1-i],v[left],NULL,NULL,NULL);
                facecopy(em, efa,hold);
                if(i+1 != (vertsize-1)/2) {
-            if(seltype == SUBDIV_SELECT_INNER) {
-                               hold->e3->f2 |= EDGEINNER;
-            }
+                       if(seltype == SUBDIV_SELECT_INNER) {
+                                hold->e3->f2 |= EDGEINNER;
+                       }
                }
        }
 }
@@ -1621,9 +1724,9 @@ static void fill_tri_single(EditMesh *em, EditFace *efa, struct GHash *gh, int n
        for(i=0;i<(vertsize-1);i++) {
                hold = addfacelist(em, verts[i],verts[i+1],v[op],NULL,NULL,NULL);
                if(i+1 != vertsize-1) {
-            if(seltype == SUBDIV_SELECT_INNER) {
-                               hold->e2->f2 |= EDGEINNER;
-            }
+                       if(seltype == SUBDIV_SELECT_INNER) {
+                                hold->e2->f2 |= EDGEINNER;
+                       }
                }
                facecopy(em, efa,hold);
        }
@@ -1634,7 +1737,7 @@ static void fill_quad_double_op(EditMesh *em, EditFace *efa, struct GHash *gh, i
        EditEdge *cedge[2]={NULL, NULL};
        EditVert *v[4], **verts[2];
        EditFace *hold;
-       short start=0, end, left, right, vertsize,i;
+       short start=0, /*end,*/ left, /* right,*/ vertsize,i;
 
        v[0] = efa->v1;
        v[1] = efa->v2;
@@ -1655,9 +1758,9 @@ static void fill_quad_double_op(EditMesh *em, EditFace *efa, struct GHash *gh, i
        // the array to the correct direction
 
        if(verts[0][0] != v[start]) {flipvertarray(verts[0],numcuts+2);}
-       end     = (start+1)%4;
+       /* end  = (start+1)%4; */ /* UNUSED */
        left   = (start+2)%4;
-       right  = (start+3)%4;
+       /* right  = (start+3)%4; */ /* UNUSED */
        if(verts[1][0] != v[left]) {flipvertarray(verts[1],numcuts+2);}
        /*
        We should have something like this now
@@ -2211,7 +2314,7 @@ static void fill_quad_quadruple(EditMesh *em, EditFace *efa, struct GHash *gh, i
                           0|---*---*---|0
                                |           |
                           1*           *1
-                    2  |           |   4
+                        2  |           |   4
                           2*           *2
                                |           |
                           3|---*---*---|3
@@ -2542,7 +2645,7 @@ static EditVert *subdivideedgenum(EditMesh *em, EditEdge *edge, int curpoint, in
        return ev;
 }
 
-void esubdivideflag(Object *obedit, EditMesh *em, int flag, float smooth, float fractal, int beauty, int numcuts, int seltype)
+void esubdivideflag(Object *obedit, EditMesh *em, int flag, float smooth, float fractal, int beauty, int numcuts, int corner_pattern, int seltype)
 {
        EditFace *ef;
        EditEdge *eed, *cedge, *sort[4];
@@ -2570,15 +2673,15 @@ void esubdivideflag(Object *obedit, EditMesh *em, int flag, float smooth, float
                                        eve->f2= 0;
                                        switch(mmd->axis){
                                                case 0:
-                                                       if (fabs(eve->co[0]) < mmd->tolerance)
+                                                       if (fabsf(eve->co[0]) < mmd->tolerance)
                                                                eve->f2 |= 1;
                                                        break;
                                                case 1:
-                                                       if (fabs(eve->co[1]) < mmd->tolerance)
+                                                       if (fabsf(eve->co[1]) < mmd->tolerance)
                                                                eve->f2 |= 2;
                                                        break;
                                                case 2:
-                                                       if (fabs(eve->co[2]) < mmd->tolerance)
+                                                       if (fabsf(eve->co[2]) < mmd->tolerance)
                                                                eve->f2 |= 4;
                                                        break;
                                        }
@@ -2676,7 +2779,7 @@ void esubdivideflag(Object *obedit, EditMesh *em, int flag, float smooth, float
                }
        }
 
-       gh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
+       gh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "subdivideedgenum gh");
 
        // If we are knifing, We only need the selected edges that were cut, so deselect if it was not cut
        if(beauty & B_KNIFE) {
@@ -2710,7 +2813,7 @@ void esubdivideflag(Object *obedit, EditMesh *em, int flag, float smooth, float
                }
        }
 
-//     DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+//     DAG_id_tag_update(obedit->data, 0);
        // Now for each face in the mesh we need to figure out How many edges were cut
        // and which filling method to use for that face
        for(ef = em->faces.first;ef;ef = ef->next) {
@@ -2786,7 +2889,7 @@ void esubdivideflag(Object *obedit, EditMesh *em, int flag, float smooth, float
                                           (ef->e2->f & flag && ef->e4->f & flag)) {
                                                fill_quad_double_op(em, ef, gh, numcuts);
                                        }else{
-                                               switch(0) { // XXX scene->toolsettings->cornertype) {
+                                               switch(corner_pattern) {
                                                        case 0: fill_quad_double_adj_path(em, ef, gh, numcuts); break;
                                                        case 1: fill_quad_double_adj_inner(em, ef, gh, numcuts); break;
                                                        case 2: fill_quad_double_adj_fan(em, ef, gh, numcuts); break;
@@ -2894,6 +2997,13 @@ void esubdivideflag(Object *obedit, EditMesh *em, int flag, float smooth, float
                }
        }
 
+       //third pass: unhide edges that have both verts visible
+       //(these were missed if all faces were hidden, bug #21976)
+       for(eed=em->edges.first; eed; eed=eed->next){
+               if(eed->v1->h == 0 && eed->v2->h == 0)
+                       eed->h &= ~1;
+       }
+
        // Free the ghash and call MEM_freeN on all the value entries to return
        // that memory
        BLI_ghash_free(gh, NULL, (GHashValFreeFP)MEM_freeN);
@@ -3041,21 +3151,21 @@ static void givequadverts(EditFace *efa, EditFace *efa1, EditVert **v1, EditVert
 
        if VTEST(efa1, 1, efa) {
                *v3= efa1->v1;
-               *v4= efa1->v2;
+               *v4= (efa1->v2 == *v2)? efa1->v3: efa1->v2;
                vindex[2]= 0;
-               vindex[3]= 1;
+               vindex[3]= (efa1->v2 == *v2)? 2: 1;
        }
        else if VTEST(efa1, 2, efa) {
                *v3= efa1->v2;
-               *v4= efa1->v3;
+               *v4= (efa1->v3 == *v2)? efa1->v1: efa1->v3;
                vindex[2]= 1;
-               vindex[3]= 2;
+               vindex[3]= (efa1->v3 == *v2)? 0: 2;
        }
        else if VTEST(efa1, 3, efa) {
                *v3= efa1->v3;
-               *v4= efa1->v1;
+               *v4= (efa1->v1 == *v2)? efa1->v2: efa1->v1;
                vindex[2]= 2;
-               vindex[3]= 0;
+               vindex[3]= (efa1->v1 == *v2)? 1: 0;
        }
        else
                *v3= *v4= NULL;
@@ -3114,13 +3224,13 @@ static float measure_facepair(EditVert *v1, EditVert *v2, EditVert *v3, EditVert
        normal_tri_v3( noA2,v1->co, v3->co, v4->co);
 
        if(noA1[0] == noA2[0] && noA1[1] == noA2[1] && noA1[2] == noA2[2]) normalADiff = 0.0;
-       else normalADiff = RAD2DEG(angle_v2v2(noA1, noA2));
+       else normalADiff = RAD2DEGF(angle_v2v2(noA1, noA2));
                //if(!normalADiff) normalADiff = 179;
        normal_tri_v3( noB1,v2->co, v3->co, v4->co);
        normal_tri_v3( noB2,v4->co, v1->co, v2->co);
 
        if(noB1[0] == noB2[0] && noB1[1] == noB2[1] && noB1[2] == noB2[2]) normalBDiff = 0.0;
-       else normalBDiff = RAD2DEG(angle_v2v2(noB1, noB2));
+       else normalBDiff = RAD2DEGF(angle_v2v2(noB1, noB2));
                //if(!normalBDiff) normalBDiff = 179;
 
        measure += (normalADiff/360) + (normalBDiff/360);
@@ -3135,10 +3245,10 @@ static float measure_facepair(EditVert *v1, EditVert *v2, EditVert *v3, EditVert
        diff = 0.0;
 
        diff = (
-               fabs(RAD2DEG(angle_v2v2(edgeVec1, edgeVec2)) - 90) +
-               fabs(RAD2DEG(angle_v2v2(edgeVec2, edgeVec3)) - 90) +
-               fabs(RAD2DEG(angle_v2v2(edgeVec3, edgeVec4)) - 90) +
-               fabs(RAD2DEG(angle_v2v2(edgeVec4, edgeVec1)) - 90)) / 360;
+               fabsf(RAD2DEGF(angle_v2v2(edgeVec1, edgeVec2)) - 90) +
+               fabsf(RAD2DEGF(angle_v2v2(edgeVec2, edgeVec3)) - 90) +
+               fabsf(RAD2DEGF(angle_v2v2(edgeVec3, edgeVec4)) - 90) +
+               fabsf(RAD2DEGF(angle_v2v2(edgeVec4, edgeVec1)) - 90)) / 360;
        if(!diff) return 0.0;
 
        measure +=  diff;
@@ -3160,7 +3270,7 @@ static float measure_facepair(EditVert *v1, EditVert *v2, EditVert *v3, EditVert
        return measure;
 }
 
-#define T2QUV_LIMIT 0.005
+#define T2QUV_LIMIT 0.005f
 #define T2QCOL_LIMIT 3
 static int compareFaceAttribs(EditMesh *em, EditFace *f1, EditFace *f2, EditEdge *eed)
 {
@@ -3364,7 +3474,7 @@ void join_triangles(EditMesh *em)
                                efaa= (EVPtr *)eed->tmp.p;
                                v1 = v2 = v3 = v4 = NULL;
                                givequadverts(efaa[0], efaa[1], &v1, &v2, &v3, &v4, vindex);
-                               if((v1 && v2 && v3 && v4) && (exist_face(em, v1, v2, v3, v4)==0)){ /*exist_face is very slow! Needs to be adressed.*/
+                               if((v1 && v2 && v3 && v4) && (exist_face(em, v1, v2, v3, v4)==0)){ /*exist_face is very slow! Needs to be addressed.*/
                                        /*flag for delete*/
                                        eed->f1 |= T2QDELETE;
                                        /*create new quad and select*/
@@ -3399,8 +3509,8 @@ void join_triangles(EditMesh *em)
 
 #define FACE_MARKCLEAR(f) (f->f1 = 1)
 
-/* quick hack, basically a copy of beauty_fill */
-void edge_flip(EditMesh *em)
+/* quick hack, basically a copy of beautify_fill */
+static void edge_flip(EditMesh *em)
 {
        EditVert *v1, *v2, *v3, *v4;
        EditEdge *eed, *nexted;
@@ -3501,7 +3611,7 @@ static const EnumPropertyItem direction_items[]= {
 #define AXIS_X         1
 #define AXIS_Y         2
 
-static const EnumPropertyItem axis_items[]= {
+static const EnumPropertyItem axis_items_xy[]= {
        {AXIS_X, "X", 0, "X", ""},
        {AXIS_Y, "Y", 0, "Y", ""},
        {0, NULL, 0, NULL, NULL}};
@@ -3533,7 +3643,7 @@ static void edge_rotate(EditMesh *em, wmOperator *op, EditEdge *eed, int dir)
                return;
 
        /* how many edges does each face have */
-       if(face[0]->e4) fac1= 4;
+        if(face[0]->e4) fac1= 4;
        else fac1= 3;
 
        if(face[1]->e4) fac2= 4;
@@ -3587,11 +3697,11 @@ static void edge_rotate(EditMesh *em, wmOperator *op, EditEdge *eed, int dir)
 
        hiddenedges = MEM_mallocN(sizeof(EditVert*)*numhidden+1, "RotateEdgeHiddenVerts");
        if(!hiddenedges) {
-        BKE_report(op->reports, RPT_ERROR, "Memory allocation failed");
-        return;
-    }
+               BKE_report(op->reports, RPT_ERROR, "Memory allocation failed");
+               return;
+       }
 
-    numhidden = 0;
+       numhidden = 0;
        for(srchedge=em->edges.first; srchedge; srchedge=srchedge->next)
                if(srchedge->h && (srchedge->v1->f & SELECT || srchedge->v2->f & SELECT))
                        hiddenedges[numhidden++] = srchedge;
@@ -3604,10 +3714,10 @@ static void edge_rotate(EditMesh *em, wmOperator *op, EditEdge *eed, int dir)
                newFace[1]= EM_face_from_faces(em, face[1], face[0], p[1][1], p[1][2], 4+p[0][1], -1);
        }
        else if(fac1 == 4 && fac2 == 3) {
-               if(dir == DIRECTION_CW) {
+               if(dir == DIRECTION_CCW) {
                        newFace[0]= EM_face_from_faces(em, face[0], face[1], p[0][1], p[0][2], p[0][3], 4+p[1][1]);
                        newFace[1]= EM_face_from_faces(em, face[1], face[0], p[1][1], p[1][2], 4+p[0][1], -1);
-               } else if (dir == DIRECTION_CCW) {
+               } else if (dir == DIRECTION_CW) {
                        newFace[0]= EM_face_from_faces(em, face[0], face[1], p[0][2], 4+p[1][1], p[0][0], p[0][1]);
                        newFace[1]= EM_face_from_faces(em, face[1], face[0], 4+p[0][2], p[1][0], p[1][1], -1);
 
@@ -3616,10 +3726,10 @@ static void edge_rotate(EditMesh *em, wmOperator *op, EditEdge *eed, int dir)
                }
        }
        else if(fac1 == 3 && fac2 == 4) {
-               if(dir == DIRECTION_CW) {
+               if(dir == DIRECTION_CCW) {
                        newFace[0]= EM_face_from_faces(em, face[0], face[1], p[0][1], p[0][2], 4+p[1][1], -1);
                        newFace[1]= EM_face_from_faces(em, face[1], face[0], p[1][1], p[1][2], p[1][3], 4+p[0][1]);
-               } else if (dir == DIRECTION_CCW) {
+               } else if (dir == DIRECTION_CW) {
                        newFace[0]= EM_face_from_faces(em, face[0], face[1], p[0][0], p[0][1], 4+p[1][2], -1);
                        newFace[1]= EM_face_from_faces(em, face[1], face[0], p[1][1], p[1][2], 4+p[0][1], 4+p[0][2]);
 
@@ -3629,10 +3739,10 @@ static void edge_rotate(EditMesh *em, wmOperator *op, EditEdge *eed, int dir)
 
        }
        else if(fac1 == 4 && fac2 == 4) {
-               if(dir == DIRECTION_CW) {
+               if(dir == DIRECTION_CCW) {
                        newFace[0]= EM_face_from_faces(em, face[0], face[1], p[0][1], p[0][2], p[0][3], 4+p[1][1]);
                        newFace[1]= EM_face_from_faces(em, face[1], face[0], p[1][1], p[1][2], p[1][3], 4+p[0][1]);
-               } else if (dir == DIRECTION_CCW) {
+               } else if (dir == DIRECTION_CW) {
                        newFace[0]= EM_face_from_faces(em, face[0], face[1], p[0][2], p[0][3], 4+p[1][1], 4+p[1][2]);
                        newFace[1]= EM_face_from_faces(em, face[1], face[0], p[1][2], p[1][3], 4+p[0][1], 4+p[0][2]);
 
@@ -3643,7 +3753,7 @@ static void edge_rotate(EditMesh *em, wmOperator *op, EditEdge *eed, int dir)
        else
                return; /* This should never happen */
 
-       if(dir == DIRECTION_CW || (fac1 == 3 && fac2 == 3)) {
+       if(dir == DIRECTION_CCW || (fac1 == 3 && fac2 == 3)) {
                verts[0][p[0][1]]->f |= SELECT;
                verts[1][p[1][1]]->f |= SELECT;
        }
@@ -3680,7 +3790,6 @@ static void edge_rotate(EditMesh *em, wmOperator *op, EditEdge *eed, int dir)
        free_editface(em, face[1]);
 }
 
-// XXX ton please check
 /* only accepts 1 selected edge, or 2 selected faces */
 static int edge_rotate_selected(bContext *C, wmOperator *op)
 {
@@ -3688,7 +3797,7 @@ static int edge_rotate_selected(bContext *C, wmOperator *op)
        EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data);
        EditEdge *eed;
        EditFace *efa;
-       int dir = RNA_int_get(op->ptr, "direction"); // dir == 2 when clockwise and ==1 for counter CW.
+       int dir = RNA_enum_get(op->ptr, "direction"); // dir == 2 when clockwise and ==1 for counter CW.
        short edgeCount = 0;
 
        /*clear new flag for new edges, count selected edges */
@@ -3722,7 +3831,7 @@ static int edge_rotate_selected(bContext *C, wmOperator *op)
                }
                else
                {
-                       BKE_report(op->reports, RPT_ERROR, "Select one edge or two adjacent faces");
+                       BKE_report(op->reports, RPT_WARNING, "Select one edge or two adjacent faces");
                        BKE_mesh_end_editmesh(obedit->data, em);
                        return OPERATOR_CANCELLED;
                }
@@ -3737,7 +3846,7 @@ static int edge_rotate_selected(bContext *C, wmOperator *op)
                }
        }
        else  {
-               BKE_report(op->reports, RPT_ERROR, "Select one edge or two adjacent faces");
+               BKE_report(op->reports, RPT_WARNING, "Select one edge or two adjacent faces");
                BKE_mesh_end_editmesh(obedit->data, em);
                return OPERATOR_CANCELLED;
        }
@@ -3747,7 +3856,7 @@ static int edge_rotate_selected(bContext *C, wmOperator *op)
 
        BKE_mesh_end_editmesh(obedit->data, em);
 
-       DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+       DAG_id_tag_update(obedit->data, 0);
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
 
        return OPERATOR_FINISHED;
@@ -3757,7 +3866,7 @@ void MESH_OT_edge_rotate(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Rotate Selected Edge";
-       ot->description= "Rotate selected edge or adjoining faces.";
+       ot->description= "Rotate selected edge or adjoining faces";
        ot->idname= "MESH_OT_edge_rotate";
 
        /* api callbacks */
@@ -3768,7 +3877,7 @@ void MESH_OT_edge_rotate(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 
        /* props */
-       RNA_def_enum(ot->srna, "direction", direction_items, DIRECTION_CW, "direction", "direction to rotate edge around.");
+       RNA_def_enum(ot->srna, "direction", direction_items, DIRECTION_CW, "Direction", "Direction to rotate the edge around.");
 }
 
 
@@ -3776,7 +3885,7 @@ void MESH_OT_edge_rotate(wmOperatorType *ot)
 
   /* XXX old bevel not ported yet */
 
-void bevel_menu(EditMesh *em)
+static void bevel_menu(EditMesh *em)
 {
        BME_Mesh *bm;
        BME_TransData_Head *td;
@@ -4039,7 +4148,7 @@ useless:
 
        // populate the SlideVerts
 
-       vertgh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
+       vertgh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "EdgeSlide gh");
        look = vertlist;
        while(look) {
                i=0;
@@ -4149,7 +4258,7 @@ useless:
                        return 0;
                }
 
-               if(me->drawflag & ME_DRAW_EDGELEN) {
+               if(me->drawflag & ME_DRAWEXTRA_EDGELEN) {
                        if(!(tempsv->up->f & SELECT)) {
                                tempsv->up->f |= SELECT;
                                tempsv->up->f2 |= 16;
@@ -4207,7 +4316,7 @@ useless:
 
                for (uvlay_idx=0; uvlay_idx<uvlay_tot; uvlay_idx++) {
 
-                       uvarray[uvlay_idx] = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
+                       uvarray[uvlay_idx] = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "EdgeSlideUV gh");
 
                        for(ev=em->verts.first;ev;ev=ev->next) {
                                ev->tmp.l = 0;
@@ -4556,7 +4665,7 @@ useless:
                                                        mvalo[0] = -1;
                                        } else if(ELEM(event, RIGHTARROWKEY, WHEELUPMOUSE)) { // Scroll through Control Edges
                                                look = vertlist;
-                                               while(look) {
+                                                while(look) {
                                                        if(nearest == (EditVert*)look->link) {
                                                                if(look->next == NULL) {
                                                                        nearest =  (EditVert*)vertlist->link;
@@ -4570,7 +4679,7 @@ useless:
                                                }
                                        } else if(ELEM(event, LEFTARROWKEY, WHEELDOWNMOUSE)) { // Scroll through Control Edges
                                                look = vertlist;
-                                               while(look) {
+                                                while(look) {
                                                        if(look->next) {
                                                                if(look->next->link == nearest) {
                                                                        nearest = (EditVert*)look->link;
@@ -4598,11 +4707,11 @@ useless:
                } else {
                        draw = 0;
                }
-//             DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+//             DAG_id_tag_update(obedit->data, 0);
        }
 
 
-       if(me->drawflag & ME_DRAW_EDGELEN) {
+       if(me->drawflag & ME_DRAWEXTRA_EDGELEN) {
                look = vertlist;
                while(look) {
                        tempsv  = BLI_ghash_lookup(vertgh,(EditVert*)look->link);
@@ -4618,7 +4727,7 @@ useless:
 
        if(!immediate)
                EM_automerge(0);
-//     DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+//     DAG_id_tag_update(obedit->data, 0);
 //     scrarea_queue_winredraw(curarea);
 
        //BLI_ghash_free(edgesgh, freeGHash, NULL);
@@ -4650,7 +4759,7 @@ useless:
 }
 #endif // END OF XXX
 
-int EdgeLoopDelete(EditMesh *em, wmOperator *op)
+int EdgeLoopDelete(EditMesh *UNUSED(em), wmOperator *UNUSED(op))
 {
 #if 0 //XXX won't work with new edgeslide
 
@@ -4669,7 +4778,7 @@ int EdgeLoopDelete(EditMesh *em, wmOperator *op)
        EM_select_more(em);
        removedoublesflag(em, 1,0, 0.001);
        EM_select_flush(em);
-       //      DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+       //      DAG_id_tag_update(obedit->data, 0);
        return 1;
 #endif
        return 0;
@@ -4708,7 +4817,7 @@ void mesh_set_face_flags(EditMesh *em, short mode)
        add_numbut(12, TOG|SHO, "Sort", 0, 0, &m_sort, NULL);
 
        if (!do_clever_numbuts((mode ? "Set Flags" : "Clear Flags"), 13, REDRAW))
-               return;
+                return;
 
        /* these 2 cant both be on */
        if (mode) /* are we seeting*/
@@ -4823,12 +4932,12 @@ static int mesh_rip_invoke(bContext *C, wmOperator *op, wmEvent *event)
        }
 
        if(efa) {
-               BKE_report(op->reports, RPT_ERROR, "Can't perform ripping with faces selected this way");
+               BKE_report(op->reports, RPT_WARNING, "Can't perform ripping with faces selected this way");
                BKE_mesh_end_editmesh(obedit->data, em);
                return OPERATOR_CANCELLED;
        }
        if(sefa==NULL) {
-               BKE_report(op->reports, RPT_ERROR, "No proper selection or faces included");
+               BKE_report(op->reports, RPT_WARNING, "No proper selection or faces included");
                BKE_mesh_end_editmesh(obedit->data, em);
                return OPERATOR_CANCELLED;
        }
@@ -4893,7 +5002,7 @@ static int mesh_rip_invoke(bContext *C, wmOperator *op, wmEvent *event)
        }
 
        if(seed==NULL) {        // never happens?
-               BKE_report(op->reports, RPT_ERROR, "No proper edge found to start");
+               BKE_report(op->reports, RPT_WARNING, "No proper edge found to start");
                BKE_mesh_end_editmesh(obedit->data, em);
                return OPERATOR_CANCELLED;
        }
@@ -4978,7 +5087,7 @@ static int mesh_rip_invoke(bContext *C, wmOperator *op, wmEvent *event)
                }
        }
 
-       DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+       DAG_id_tag_update(obedit->data, 0);
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
 
        BKE_mesh_end_editmesh(obedit->data, em);
@@ -4994,7 +5103,7 @@ void MESH_OT_rip(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Rip";
-       ot->description= "Rip selection from mesh (quads only).";
+       ot->description= "Rip selection from mesh (quads only)";
        ot->idname= "MESH_OT_rip";
 
        /* api callbacks */
@@ -5005,8 +5114,8 @@ void MESH_OT_rip(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 
        /* to give to transform */
-       Properties_Proportional(ot);
-       RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", "");
+       /* XXX Transform this in a macro */
+       Transform_Properties(ot, P_CONSTRAINT|P_MIRROR);
 }
 
 
@@ -5023,7 +5132,7 @@ static void shape_propagate(Object *obedit, EditMesh *em, wmOperator *op)
        if(me->key){
                ky = me->key;
        } else {
-               BKE_report(op->reports, RPT_ERROR, "Object Has No Key");
+               BKE_report(op->reports, RPT_WARNING, "Object Has No Key");
                return;
        }
 
@@ -5038,7 +5147,7 @@ static void shape_propagate(Object *obedit, EditMesh *em, wmOperator *op)
                        }
                }
        } else {
-               BKE_report(op->reports, RPT_ERROR, "Object Has No Blendshapes");
+               BKE_report(op->reports, RPT_WARNING, "Object Has No Blendshapes");
                return;
        }
 
@@ -5051,7 +5160,7 @@ static void shape_propagate(Object *obedit, EditMesh *em, wmOperator *op)
        }
 #endif
 
-       DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+       DAG_id_tag_update(obedit->data, 0);
        return;
 }
 
@@ -5064,7 +5173,7 @@ static int shape_propagate_to_all_exec(bContext *C, wmOperator *op)
 
        shape_propagate(obedit, em, op);
 
-       DAG_id_flush_update(&me->id, OB_RECALC_DATA);
+       DAG_id_tag_update(&me->id, 0);
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
 
        return OPERATOR_FINISHED;
@@ -5075,7 +5184,7 @@ void MESH_OT_shape_propagate_to_all(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Shape Propagate";
-       ot->description= "Apply selected vertex locations to all other shape keys.";
+       ot->description= "Apply selected vertex locations to all other shape keys";
        ot->idname= "MESH_OT_shape_propagate_to_all";
 
        /* api callbacks */
@@ -5093,27 +5202,38 @@ static int blend_from_shape_exec(bContext *C, wmOperator *op)
        Key *key= me->key;
        EditMesh *em= BKE_mesh_get_editmesh(me);
        EditVert *eve;
-       KeyBlock *kb;
-       float *data, co[3];
+       KeyBlock *kb, *refkb= NULL;
+       float *data, *refdata= NULL, co[3];
        float blend= RNA_float_get(op->ptr, "blend");
        int shape= RNA_enum_get(op->ptr, "shape");
-       int add= RNA_int_get(op->ptr, "add");
+       int add= RNA_boolean_get(op->ptr, "add");
        int blended= 0;
 
        if(key && (kb= BLI_findlink(&key->block, shape))) {
                data= kb->data;
 
+               if(add) {
+                       refkb= BLI_findlink(&key->block, kb->relative);
+                       if(refkb)
+                               refdata = refkb->data;
+               }
+
                for(eve=em->verts.first; eve; eve=eve->next){
                        if(eve->f & SELECT) {
                                if(eve->keyindex >= 0 && eve->keyindex < kb->totelem) {
-                                       VECCOPY(co, data + eve->keyindex*3);
+                                       copy_v3_v3(co, data + eve->keyindex*3);
 
                                        if(add) {
-                                               mul_v3_fl(co, blend);
-                                               add_v3_v3v3(eve->co, eve->co, co);
+                                               /* in add mode, we add relative shape key offset */
+                                               if(refdata && eve->keyindex < refkb->totelem)
+                                                       sub_v3_v3v3(co, co, refdata + eve->keyindex*3);
+
+                                               madd_v3_v3fl(eve->co, co, blend);
                                        }
-                                       else
+                                       else {
+                                               /* in blend mode, we interpolate to the shape key */
                                                interp_v3_v3v3(eve->co, eve->co, co, blend);
+                                       }
 
                                        blended= 1;
                                }
@@ -5126,13 +5246,13 @@ static int blend_from_shape_exec(bContext *C, wmOperator *op)
        if(!blended)
                return OPERATOR_CANCELLED;
 
-       DAG_id_flush_update(&me->id, OB_RECALC_DATA);
+       DAG_id_tag_update(&me->id, 0);
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, me);
 
        return OPERATOR_FINISHED;
 }
 
-static EnumPropertyItem *shape_itemf(bContext *C, PointerRNA *ptr, int *free)
+static EnumPropertyItem *shape_itemf(bContext *C, PointerRNA *UNUSED(ptr), int *free)
 {      
        Object *obedit= CTX_data_edit_object(C);
        Mesh *me= (obedit) ? obedit->data : NULL;
@@ -5170,7 +5290,7 @@ void MESH_OT_blend_from_shape(wmOperatorType *ot)
 
        /* identifiers */
        ot->name= "Blend From Shape";
-       ot->description= "Blend in shape from a shape key.";
+       ot->description= "Blend in shape from a shape key";
        ot->idname= "MESH_OT_blend_from_shape";
 
        /* api callbacks */
@@ -5185,7 +5305,7 @@ void MESH_OT_blend_from_shape(wmOperatorType *ot)
        prop= RNA_def_enum(ot->srna, "shape", shape_items, 0, "Shape", "Shape key to use for blending.");
        RNA_def_enum_funcs(prop, shape_itemf);
        RNA_def_float(ot->srna, "blend", 1.0f, -FLT_MAX, FLT_MAX, "Blend", "Blending factor.", -2.0f, 2.0f);
-       RNA_def_boolean(ot->srna, "add", 1, "Add", "Add rather then blend between shapes.");
+       RNA_def_boolean(ot->srna, "add", 0, "Add", "Add rather then blend between shapes.");
 }
 
 /************************ Merge Operator *************************/
@@ -5294,7 +5414,7 @@ static void freecollections(ListBase *allcollections)
 
 /*Begin UV Edge Collapse Code
        Like Edge subdivide, Edge Collapse should handle UV's intelligently, but since UV's are a per-face attribute, normal edge collapse will fail
-       in areas such as the boundries of 'UV islands'. So for each edge collection we need to build a set of 'welded' UV vertices and edges for it.
+       in areas such as the boundaries of 'UV islands'. So for each edge collection we need to build a set of 'welded' UV vertices and edges for it.
        The welded UV edges can then be sorted and collapsed.
 */
 typedef struct wUV{
@@ -5627,7 +5747,7 @@ static int collapseEdges(EditMesh *em)
        CollectedEdge *curredge;
        Collection *edgecollection;
 
-       int totedges, groupcount, mergecount,vcount;
+       int totedges, mergecount,vcount /*, groupcount*/;
        float avgcount[3];
 
        allcollections.first = 0;
@@ -5636,7 +5756,7 @@ static int collapseEdges(EditMesh *em)
        mergecount = 0;
 
        build_edgecollection(em, &allcollections);
-       groupcount = BLI_countlist(&allcollections);
+       /*groupcount = BLI_countlist(&allcollections);*/ /*UNUSED*/
 
 
        for(edgecollection = allcollections.first; edgecollection; edgecollection = edgecollection->next){
@@ -5726,7 +5846,7 @@ static void em_snap_to_center(EditMesh *em)
 
        for (eve=em->verts.first; eve; eve=eve->next) {
                if (eve->f & SELECT) {
-                       add_v3_v3v3(cent, cent, eve->co);
+                       add_v3_v3(cent, eve->co);
                        i++;
                }
        }
@@ -5789,6 +5909,7 @@ static int merge_exec(bContext *C, wmOperator *op)
        Object *obedit= CTX_data_edit_object(C);
        EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data);
        int count= 0, uvs= RNA_boolean_get(op->ptr, "uvs");
+       EditSelection *ese;
 
        switch(RNA_enum_get(op->ptr, "type")) {
                case 3:
@@ -5798,10 +5919,21 @@ static int merge_exec(bContext *C, wmOperator *op)
                        count = merge_target(C, em, 1, uvs);
                        break;
                case 1:
-                       count = merge_firstlast(em, 0, uvs);
+                       ese= (EditSelection *)em->selected.last;
+                       if(ese && ese->type == EDITVERT) {
+                               count = merge_firstlast(em, 0, uvs);
+                       } else {
+                               BKE_report(op->reports, RPT_WARNING, "no last selected vertex set");
+                       }
                        break;
                case 6:
-                       count = merge_firstlast(em, 1, uvs);
+                       ese= (EditSelection *)em->selected.first;
+                       if(ese && ese->type == EDITVERT) {
+                               count = merge_firstlast(em, 1, uvs);
+                       }
+                       else {
+                               BKE_report(op->reports, RPT_WARNING, "no last selected vertex set");
+                       }
                        break;
                case 5:
                        count = collapseEdges(em);
@@ -5811,11 +5943,13 @@ static int merge_exec(bContext *C, wmOperator *op)
        if(!count)
                return OPERATOR_CANCELLED;
 
-       BKE_reportf(op->reports, RPT_INFO, "Removed %d vertices.", count);
+       recalc_editnormals(em);
+       
+       BKE_reportf(op->reports, RPT_INFO, "Removed %d vert%s.", count, (count==1)?"ex":"ices");
 
        BKE_mesh_end_editmesh(obedit->data, em);
 
-       DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+       DAG_id_tag_update(obedit->data, 0);
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
 
        return OPERATOR_FINISHED;
@@ -5829,12 +5963,16 @@ static EnumPropertyItem merge_type_items[]= {
        {5, "COLLAPSE", 0, "Collapse", ""},
        {0, NULL, 0, NULL, NULL}};
 
-static EnumPropertyItem *merge_type_itemf(bContext *C, PointerRNA *ptr, int *free)
+static EnumPropertyItem *merge_type_itemf(bContext *C, PointerRNA *UNUSED(ptr), int *free)
 {      
        Object *obedit= CTX_data_edit_object(C);
        EnumPropertyItem *item= NULL;
        int totitem= 0;
 
+       if (C==NULL) {
+               return merge_type_items;
+       }
+
        if(obedit && obedit->type == OB_MESH) {
                EditMesh *em= BKE_mesh_get_editmesh(obedit->data);
 
@@ -5867,7 +6005,7 @@ void MESH_OT_merge(wmOperatorType *ot)
 
        /* identifiers */
        ot->name= "Merge";
-       ot->description= "Merge selected vertices.";
+       ot->description= "Merge selected vertices";
        ot->idname= "MESH_OT_merge";
 
        /* api callbacks */
@@ -5908,30 +6046,34 @@ static int select_vertex_path_exec(bContext *C, wmOperator *op)
        EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data);
        EditVert *eve, *s, *t;
        EditEdge *eed;
-       EditSelection *ese;
        PathEdge *newpe, *currpe;
        PathNode *currpn;
        PathNode *Q;
        int v, *previous, pathvert, pnindex; /*pnindex redundant?*/
-       int unbalanced, totnodes;
-       short physical;
+       int unbalanced, totnodes;
        float *cost;
+       int type= RNA_enum_get(op->ptr, "type");
        Heap *heap; /*binary heap for sorting pointers to PathNodes based upon a 'cost'*/
 
        s = t = NULL;
+       for(eve=em->verts.first; eve; eve=eve->next) {
+               if(eve->f&SELECT) {
+                       if(s == NULL) s= eve;
+                       else if(t == NULL) t= eve;
+                       else {
+                               /* more than two vertices are selected,
+                                  show warning message and cancel operator */
+                               s = t = NULL;
+                               break;
+                       }
 
-       ese = ((EditSelection*)em->selected.last);
-       if(ese && ese->type == EDITVERT && ese->prev && ese->prev->type == EDITVERT){
-               physical= pupmenu("Distance Method? %t|Edge Length%x1|Topological%x0");
-
-               t = (EditVert*)ese->data;
-               s = (EditVert*)ese->prev->data;
+               }
 
                /*need to find out if t is actually reachable by s....*/
-               for(eve=em->verts.first; eve; eve=eve->next){
-                       eve->f1 = 0;
-               }
+               eve->f1 = 0;
+       }
 
+       if(s != NULL && t != NULL) {
                s->f1 = 1;
 
                unbalanced = 1;
@@ -5976,7 +6118,7 @@ static int select_vertex_path_exec(bContext *C, wmOperator *op)
 
                                                newpe = MEM_mallocN(sizeof(PathEdge), "Path Edge");
                                                newpe->v = ((PathNode*)eed->v2->tmp.p)->u;
-                                               if(physical){
+                                               if (type == PATH_SELECT_EDGE_LENGTH) {
                                                                newpe->w = len_v3v3(eed->v1->co, eed->v2->co);
                                                }
                                                else newpe->w = 1;
@@ -5988,7 +6130,7 @@ static int select_vertex_path_exec(bContext *C, wmOperator *op)
                                                currpn = ((PathNode*)eed->v2->tmp.p);
                                                newpe = MEM_mallocN(sizeof(PathEdge), "Path Edge");
                                                newpe->v = ((PathNode*)eed->v1->tmp.p)->u;
-                                               if(physical){
+                                               if (type == PATH_SELECT_EDGE_LENGTH) {
                                                                newpe->w = len_v3v3(eed->v1->co, eed->v2->co);
                                                }
                                                else newpe->w = 1;
@@ -6052,7 +6194,7 @@ static int select_vertex_path_exec(bContext *C, wmOperator *op)
        }
        else {
                BKE_mesh_end_editmesh(obedit->data, em);
-               BKE_report(op->reports, RPT_ERROR, "Path Selection requires that exactly two vertices be selected");
+               BKE_report(op->reports, RPT_WARNING, "Path Selection requires that exactly two vertices be selected");
                return OPERATOR_CANCELLED;
        }
 
@@ -6071,12 +6213,11 @@ void MESH_OT_select_vertex_path(wmOperatorType *ot)
 
        /* identifiers */
        ot->name= "Select Vertex Path";
-       ot->description= "Select shortest path between two vertices by distance type.";
+       ot->description= "Select shortest path between two vertices by distance type";
        ot->idname= "MESH_OT_select_vertex_path";
 
        /* api callbacks */
        ot->exec= select_vertex_path_exec;
-       ot->invoke= WM_menu_invoke;
        ot->poll= ED_operator_editmesh;
 
        /* flags */
@@ -6088,7 +6229,7 @@ void MESH_OT_select_vertex_path(wmOperatorType *ot)
 
 /********************** Region/Loop Operators *************************/
 
-static int region_to_loop(bContext *C, wmOperator *op)
+static int region_to_loop(bContext *C, wmOperator *UNUSED(op))
 {
        Object *obedit= CTX_data_edit_object(C);
        EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data);
@@ -6120,6 +6261,7 @@ static int region_to_loop(bContext *C, wmOperator *op)
        }
 
        em->selectmode = SCE_SELECT_EDGE;
+       CTX_data_tool_settings(C)->selectmode= em->selectmode;
        EM_selectmode_set(em);
 
        BKE_mesh_end_editmesh(obedit->data, em);
@@ -6133,7 +6275,7 @@ void MESH_OT_region_to_loop(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Region to Loop";
-       ot->description= "Select a region as a loop of connected edges.";
+       ot->description= "Select a region as a loop of connected edges";
        ot->idname= "MESH_OT_region_to_loop";
 
        /* api callbacks */
@@ -6268,7 +6410,7 @@ static int loop_bisect(EditMesh *em, Collection *edgecollection){
        else return(2);
 }
 
-static int loop_to_region(bContext *C, wmOperator *op)
+static int loop_to_region(bContext *C, wmOperator *UNUSED(op))
 {
        Object *obedit= CTX_data_edit_object(C);
        EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data);
@@ -6309,7 +6451,7 @@ void MESH_OT_loop_to_region(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Loop to Region";
-       ot->description= "Select a loop of connected edges as a region.";
+       ot->description= "Select a loop of connected edges as a region";
        ot->idname= "MESH_OT_loop_to_region";
 
        /* api callbacks */
@@ -6337,7 +6479,7 @@ static int mesh_rotate_uvs(bContext *C, wmOperator *op)
        int dir= RNA_enum_get(op->ptr, "direction");
 
        if (!EM_texFaceCheck(em)) {
-               BKE_report(op->reports, RPT_ERROR, "Mesh has no uv/image layers.");
+               BKE_report(op->reports, RPT_WARNING, "Mesh has no uv/image layers.");
                BKE_mesh_end_editmesh(obedit->data, em);
                return OPERATOR_CANCELLED;
        }
@@ -6393,7 +6535,7 @@ static int mesh_rotate_uvs(bContext *C, wmOperator *op)
        if(!change)
                return OPERATOR_CANCELLED;
 
-       DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+       DAG_id_tag_update(obedit->data, 0);
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
 
        return OPERATOR_FINISHED;
@@ -6411,7 +6553,7 @@ static int mesh_mirror_uvs(bContext *C, wmOperator *op)
        int axis= RNA_enum_get(op->ptr, "axis");
 
        if (!EM_texFaceCheck(em)) {
-               BKE_report(op->reports, RPT_ERROR, "Mesh has no uv/image layers.");
+               BKE_report(op->reports, RPT_WARNING, "Mesh has no uv/image layers.");
                BKE_mesh_end_editmesh(obedit->data, em);
                return OPERATOR_CANCELLED;
        }
@@ -6482,7 +6624,7 @@ static int mesh_mirror_uvs(bContext *C, wmOperator *op)
        if(!change)
                return OPERATOR_CANCELLED;
 
-       DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+       DAG_id_tag_update(obedit->data, 0);
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
 
        return OPERATOR_FINISHED;
@@ -6499,7 +6641,7 @@ static int mesh_rotate_colors(bContext *C, wmOperator *op)
        int dir= RNA_enum_get(op->ptr, "direction");
 
        if (!EM_vertColorCheck(em)) {
-               BKE_report(op->reports, RPT_ERROR, "Mesh has no color layers.");
+               BKE_report(op->reports, RPT_WARNING, "Mesh has no color layers.");
                BKE_mesh_end_editmesh(obedit->data, em);
                return OPERATOR_CANCELLED;
        }
@@ -6538,7 +6680,7 @@ static int mesh_rotate_colors(bContext *C, wmOperator *op)
        if(!change)
                return OPERATOR_CANCELLED;
 
-       DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+       DAG_id_tag_update(obedit->data, 0);
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
 
        return OPERATOR_FINISHED;
@@ -6556,7 +6698,7 @@ static int mesh_mirror_colors(bContext *C, wmOperator *op)
        int axis= RNA_enum_get(op->ptr, "axis");
 
        if (!EM_vertColorCheck(em)) {
-               BKE_report(op->reports, RPT_ERROR, "Mesh has no color layers");
+               BKE_report(op->reports, RPT_WARNING, "Mesh has no color layers");
                BKE_mesh_end_editmesh(obedit->data, em);
                return OPERATOR_CANCELLED;
        }
@@ -6594,7 +6736,7 @@ static int mesh_mirror_colors(bContext *C, wmOperator *op)
        if(!change)
                return OPERATOR_CANCELLED;
 
-       DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+       DAG_id_tag_update(obedit->data, 0);
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
 
        return OPERATOR_FINISHED;
@@ -6604,7 +6746,7 @@ void MESH_OT_uvs_rotate(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Rotate UVs";
-       ot->description= "Rotate selected UVs.";
+       ot->description= "Rotate selected UVs";
        ot->idname= "MESH_OT_uvs_rotate";
 
        /* api callbacks */
@@ -6622,7 +6764,7 @@ void MESH_OT_uvs_mirror(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Mirror UVs";
-       ot->description= "Mirror selected UVs.";
+       ot->description= "Mirror selected UVs";
        ot->idname= "MESH_OT_uvs_mirror";
 
        /* api callbacks */
@@ -6633,14 +6775,14 @@ void MESH_OT_uvs_mirror(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 
        /* props */
-       RNA_def_enum(ot->srna, "axis", axis_items, DIRECTION_CW, "Axis", "Axis to mirror UVs around.");
+       RNA_def_enum(ot->srna, "axis", axis_items_xy, DIRECTION_CW, "Axis", "Axis to mirror UVs around.");
 }
 
 void MESH_OT_colors_rotate(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Rotate Colors";
-       ot->description= "Rotate UV/image color layer.";
+       ot->description= "Rotate UV/image color layer";
        ot->idname= "MESH_OT_colors_rotate";
 
        /* api callbacks */
@@ -6658,7 +6800,7 @@ void MESH_OT_colors_mirror(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Mirror Colors";
-       ot->description= "Mirror UV/image color layer.";
+       ot->description= "Mirror UV/image color layer";
        ot->idname= "MESH_OT_colors_mirror";
 
        /* api callbacks */
@@ -6669,7 +6811,7 @@ void MESH_OT_colors_mirror(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 
        /* props */
-       RNA_def_enum(ot->srna, "axis", axis_items, DIRECTION_CW, "Axis", "Axis to mirror colors around.");
+       RNA_def_enum(ot->srna, "axis", axis_items_xy, DIRECTION_CW, "Axis", "Axis to mirror colors around.");
 }
 
 /********************** Subdivide Operator *************************/
@@ -6682,6 +6824,7 @@ static int subdivide_exec(bContext *C, wmOperator *op)
        int cuts= RNA_int_get(op->ptr,"number_cuts");
        float smooth= 0.292f*RNA_float_get(op->ptr, "smoothness");
        float fractal= RNA_float_get(op->ptr, "fractal")/100;
+       int corner_cut_pattern= RNA_enum_get(op->ptr,"corner_cut_pattern");
        int flag= 0;
 
        if(smooth != 0.0f)
@@ -6689,19 +6832,19 @@ static int subdivide_exec(bContext *C, wmOperator *op)
        if(fractal != 0.0f)
                flag |= B_FRACTAL;
 
-       esubdivideflag(obedit, em, 1, smooth, fractal, ts->editbutflag|flag, cuts, 0);
+       esubdivideflag(obedit, em, 1, smooth, fractal, ts->editbutflag|flag, cuts, corner_cut_pattern, 0);
 
-       DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+       DAG_id_tag_update(obedit->data, 0);
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
 
        return OPERATOR_FINISHED;
 }
 
 void MESH_OT_subdivide(wmOperatorType *ot)
-{
+{      
        /* identifiers */
        ot->name= "Subdivide";
-       ot->description= "Subdivide selected edges.";
+       ot->description= "Subdivide selected edges";
        ot->idname= "MESH_OT_subdivide";
 
        /* api callbacks */
@@ -6713,15 +6856,16 @@ void MESH_OT_subdivide(wmOperatorType *ot)
 
        /* properties */
        RNA_def_int(ot->srna, "number_cuts", 1, 1, INT_MAX, "Number of Cuts", "", 1, 10);
+       RNA_def_float(ot->srna, "smoothness", 0.0f, 0.0f, FLT_MAX, "Smoothness", "Smoothness factor.", 0.0f, 1.0f);
        RNA_def_float(ot->srna, "fractal", 0.0, 0.0f, FLT_MAX, "Fractal", "Fractal randomness factor.", 0.0f, 1000.0f);
-       RNA_def_float(ot->srna, "smoothness", 0.0f, 0.0f, FLT_MAX, "Smoothness", "Smoothness factor.", 0.0f, 1000.0f);
+       RNA_def_enum(ot->srna, "corner_cut_pattern", corner_type_items, SUBDIV_CORNER_INNERVERT, "Corner Cut Pattern", "Topology pattern to use to fill a face after cutting across its corner");
 }
 
 /********************** Fill Operators *************************/
 
 /* note; the EM_selectmode_set() calls here illustrate how badly constructed it all is... from before the
 edge/face flags, with very mixed results.... */
-static void beauty_fill(EditMesh *em)
+static void beautify_fill(EditMesh *em)
 {
        EditVert *v1, *v2, *v3, *v4;
        EditEdge *eed, *nexted;
@@ -6944,7 +7088,7 @@ static void fill_mesh(EditMesh *em)
                }
        }
 
-       if(BLI_edgefill(0, em->mat_nr)) {
+       if(BLI_edgefill(em->mat_nr)) {
                efa= fillfacebase.first;
                while(efa) {
                        /* normals default pointing up */
@@ -6956,14 +7100,14 @@ static void fill_mesh(EditMesh *em)
        }
 
        BLI_end_edgefill();
-       beauty_fill(em);
+       beautify_fill(em);
 
        WM_cursor_wait(0);
        EM_select_flush(em);
 
 }
 
-static int fill_mesh_exec(bContext *C, wmOperator *op)
+static int fill_mesh_exec(bContext *C, wmOperator *UNUSED(op))
 {
        Object *obedit= CTX_data_edit_object(C);
        EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data);
@@ -6972,7 +7116,7 @@ static int fill_mesh_exec(bContext *C, wmOperator *op)
 
        BKE_mesh_end_editmesh(obedit->data, em);
 
-       DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+       DAG_id_tag_update(obedit->data, 0);
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
 
        return OPERATOR_FINISHED;
@@ -6983,7 +7127,7 @@ void MESH_OT_fill(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Fill";
-       ot->description= "Create a segment, edge or face.";
+       ot->description= "Create a segment, edge or face";
        ot->idname= "MESH_OT_fill";
 
        /* api callbacks */
@@ -6994,46 +7138,224 @@ void MESH_OT_fill(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
-static int beauty_fill_exec(bContext *C, wmOperator *op)
+static int beautify_fill_exec(bContext *C, wmOperator *UNUSED(op))
 {
        Object *obedit= CTX_data_edit_object(C);
        EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data);
 
-       beauty_fill(em);
+       beautify_fill(em);
 
        BKE_mesh_end_editmesh(obedit->data, em);
 
-       DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+       DAG_id_tag_update(obedit->data, 0);
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
 
        return OPERATOR_FINISHED;
 }
 
-void MESH_OT_beauty_fill(wmOperatorType *ot)
+void MESH_OT_beautify_fill(wmOperatorType *ot)
 {
        /* identifiers */
-       ot->name= "Beauty Fill";
-       ot->description= "Arrange geometry on a selected surface to avoid skinny faces.";
-       ot->idname= "MESH_OT_beauty_fill";
+       ot->name= "Beautify Fill";
+       ot->description= "Rearrange geometry on a selected surface to avoid skinny faces";
+       ot->idname= "MESH_OT_beautify_fill";
 
        /* api callbacks */
-       ot->exec= beauty_fill_exec;
+       ot->exec= beautify_fill_exec;
        ot->poll= ED_operator_editmesh;
 
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
+/* ********************** SORT FACES ******************* */
+
+static void permutate(void *list, int num, int size, int *index)
+{
+       void *buf;
+       int len;
+       int i;
+
+       len = num * size;
+
+       buf = MEM_mallocN(len, "permutate");
+       memcpy(buf, list, len);
+       
+       for (i = 0; i < num; i++) {
+               memcpy((char *)list + (i * size), (char *)buf + (index[i] * size), size);
+       }
+       MEM_freeN(buf);
+}
+
+/* sort faces on view axis */
+static float *face_sort_floats;
+static int float_sort(const void *v1, const void *v2)
+{
+       float x1, x2;
+       
+       x1 = face_sort_floats[((int *) v1)[0]];
+       x2 = face_sort_floats[((int *) v2)[0]];
+       
+       if( x1 > x2 ) return 1;
+       else if( x1 < x2 ) return -1;
+       return 0;
+}
+
+
+static int sort_faces_exec(bContext *C, wmOperator *op)
+{
+       RegionView3D *rv3d= ED_view3d_context_rv3d(C);
+       View3D *v3d= CTX_wm_view3d(C);
+       Object *ob= CTX_data_edit_object(C);
+       Scene *scene= CTX_data_scene(C);
+       Mesh *me;
+       CustomDataLayer *layer;
+       int i, *index;
+       int event;
+       float reverse = 1;
+       // XXX int ctrl= 0;
+       
+       if (!v3d) return OPERATOR_CANCELLED;
+
+       /* This operator work in Object Mode, not in edit mode.
+        * After talk with Campbell we agree that there is no point to port this to EditMesh right now.
+        * so for now, we just exit_editmode and enter_editmode at the end of this function.
+        */
+       ED_object_exit_editmode(C, EM_FREEDATA);
+
+       me= ob->data;
+       if(me->totface==0) {
+               ED_object_enter_editmode(C, 0);
+               return OPERATOR_FINISHED;
+       }
+
+       event= RNA_enum_get(op->ptr, "type");
+
+       // XXX
+       //if(ctrl)
+       //      reverse = -1;
+       
+       /* create index list */
+       index= (int *)MEM_mallocN(sizeof(int) * me->totface, "sort faces");
+       for (i = 0; i < me->totface; i++) {
+               index[i] = i;
+       }
+       
+       face_sort_floats = (float *) MEM_mallocN(sizeof(float) * me->totface, "sort faces float");
+
+       /* sort index list instead of faces itself 
+        * and apply this permutation to all face layers
+        */
+       if (event == 5) {
+               /* Random */
+               for(i=0; i<me->totface; i++) {
+                       face_sort_floats[i] = BLI_frand();
+               }
+               qsort(index, me->totface, sizeof(int), float_sort);             
+       } else {
+               MFace *mf;
+               float vec[3];
+               float mat[4][4];
+               float cur[3];
+               
+               if (event == 1)
+                       mul_m4_m4m4(mat, OBACT->obmat, rv3d->viewmat); /* apply the view matrix to the object matrix */
+               else if (event == 2) { /* sort from cursor */
+                       if( v3d && v3d->localvd ) {
+                               VECCOPY(cur, v3d->cursor);
+                       } else {
+                               VECCOPY(cur, scene->cursor);
+                       }
+                       invert_m4_m4(mat, OBACT->obmat);
+                       mul_m4_v3(mat, cur);
+               }
+               
+               mf= me->mface;
+
+               for(i=0; i<me->totface; i++, mf++) {
+                       if (event==3) {
+                               face_sort_floats[i] = ((float)mf->mat_nr)*reverse;
+                       } else if (event==4) {
+                               /*selected first*/
+                               if (mf->flag & ME_FACE_SEL)
+                                       face_sort_floats[i] = 0.0;
+                               else
+                                       face_sort_floats[i] = reverse;
+                       } else {
+                               /* find the faces center */
+                               add_v3_v3v3(vec, (me->mvert+mf->v1)->co, (me->mvert+mf->v2)->co);
+                               if (mf->v4) {
+                                       add_v3_v3(vec, (me->mvert+mf->v3)->co);
+                                       add_v3_v3(vec, (me->mvert+mf->v4)->co);
+                                       mul_v3_fl(vec, 0.25f);
+                               } else {
+                                       add_v3_v3(vec, (me->mvert+mf->v3)->co);
+                                       mul_v3_fl(vec, 1.0f/3.0f);
+                               } /* done */
+                               
+                               if (event == 1) { /* sort on view axis */
+                                       mul_m4_v3(mat, vec);
+                                       face_sort_floats[i] = vec[2] * reverse;
+                               } else if(event == 2) { /* distance from cursor*/
+                                       face_sort_floats[i] = len_v3v3(cur, vec) * reverse; /* back to front */
+                               }
+                       }
+               }
+               qsort(index, me->totface, sizeof(int), float_sort);
+       }
+       
+       MEM_freeN(face_sort_floats);
+       for(i = 0; i < me->fdata.totlayer; i++) {
+               layer = &me->fdata.layers[i];
+               permutate(layer->data, me->totface, CustomData_sizeof(layer->type), index);
+       }
+
+       MEM_freeN(index);
+       DAG_id_tag_update(ob->data, 0);
+
+       /* Return to editmode. */
+       ED_object_enter_editmode(C, 0);
+
+       return OPERATOR_FINISHED;
+}
+
+void MESH_OT_sort_faces(wmOperatorType *ot)
+{
+       static EnumPropertyItem type_items[]= {
+               { 1, "VIEW_AXIS", 0, "View Axis", "" },
+               { 2, "CURSOR_DISTANCE", 0, "Cursor Distance", "" },
+               { 3, "MATERIAL", 0, "Material", "" },
+               { 4, "SELECTED", 0, "Selected", "" },
+               { 5, "RANDOMIZE", 0, "Randomize", "" },
+               { 0, NULL, 0, NULL, NULL }};
+
+       /* identifiers */
+       ot->name= "Sort Faces"; // XXX (Ctrl to reverse)%t|
+       ot->description= "The faces of the active Mesh Object are sorted, based on the current view.";
+       ot->idname= "MESH_OT_sort_faces";
+
+       /* api callbacks */
+       ot->invoke= WM_menu_invoke;
+       ot->exec= sort_faces_exec;
+       ot->poll= ED_operator_editmesh;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+       /* properties */
+       ot->prop= RNA_def_enum(ot->srna, "type", type_items, 0, "Type", "");
+}
+
 /********************** Quad/Tri Operators *************************/
 
-static int quads_convert_to_tris_exec(bContext *C, wmOperator *op)
+static int quads_convert_to_tris_exec(bContext *C, wmOperator *UNUSED(op))
 {
        Object *obedit= CTX_data_edit_object(C);
        EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data);
 
        convert_to_triface(em,0);
 
-       DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+       DAG_id_tag_update(obedit->data, 0);
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
 
        BKE_mesh_end_editmesh(obedit->data, em);
@@ -7044,7 +7366,7 @@ void MESH_OT_quads_convert_to_tris(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Quads to Tris";
-       ot->description= "Convert selected quads to triangles.";
+       ot->description= "Convert selected quads to triangles";
        ot->idname= "MESH_OT_quads_convert_to_tris";
 
        /* api callbacks */
@@ -7055,14 +7377,14 @@ void MESH_OT_quads_convert_to_tris(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
-static int tris_convert_to_quads_exec(bContext *C, wmOperator *op)
+static int tris_convert_to_quads_exec(bContext *C, wmOperator *UNUSED(op))
 {
        Object *obedit= CTX_data_edit_object(C);
        EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data);
 
        join_triangles(em);
 
-       DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+       DAG_id_tag_update(obedit->data, 0);
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
 
        BKE_mesh_end_editmesh(obedit->data, em);
@@ -7073,7 +7395,7 @@ void MESH_OT_tris_convert_to_quads(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Tris to Quads";
-       ot->description= "Convert selected triangles to quads.";
+       ot->description= "Convert selected triangles to quads";
        ot->idname= "MESH_OT_tris_convert_to_quads";
 
        /* api callbacks */
@@ -7084,14 +7406,14 @@ void MESH_OT_tris_convert_to_quads(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
-static int edge_flip_exec(bContext *C, wmOperator *op)
+static int edge_flip_exec(bContext *C, wmOperator *UNUSED(op))
 {
        Object *obedit= CTX_data_edit_object(C);
        EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data);
 
        edge_flip(em);
 
-       DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+       DAG_id_tag_update(obedit->data, 0);
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
 
        BKE_mesh_end_editmesh(obedit->data, em);
@@ -7102,7 +7424,7 @@ void MESH_OT_edge_flip(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Edge Flip";
-       ot->description= "Flip selected edge or adjoining faces.";
+       ot->description= "Flip selected edge or adjoining faces";
        ot->idname= "MESH_OT_edge_flip";
 
        /* api callbacks */
@@ -7127,9 +7449,11 @@ static void mesh_set_smooth_faces(EditMesh *em, short smooth)
                        else efa->flag &= ~ME_SMOOTH;
                }
        }
+
+       recalc_editnormals(em);
 }
 
-static int mesh_faces_shade_smooth_exec(bContext *C, wmOperator *op)
+static int mesh_faces_shade_smooth_exec(bContext *C, wmOperator *UNUSED(op))
 {
        Object *obedit= CTX_data_edit_object(C);
        EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data);
@@ -7138,7 +7462,7 @@ static int mesh_faces_shade_smooth_exec(bContext *C, wmOperator *op)
 
        BKE_mesh_end_editmesh(obedit->data, em);
 
-       DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+       DAG_id_tag_update(obedit->data, 0);
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
 
        return OPERATOR_FINISHED;
@@ -7148,7 +7472,7 @@ void MESH_OT_faces_shade_smooth(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Shade Smooth";
-       ot->description= "Display faces 'smooth' (using vertex normals).";
+       ot->description= "Display faces 'smooth' (using vertex normals)";
        ot->idname= "MESH_OT_faces_shade_smooth";
 
        /* api callbacks */
@@ -7159,14 +7483,14 @@ void MESH_OT_faces_shade_smooth(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
-static int mesh_faces_shade_flat_exec(bContext *C, wmOperator *op)
+static int mesh_faces_shade_flat_exec(bContext *C, wmOperator *UNUSED(op))
 {
        Object *obedit= CTX_data_edit_object(C);
        EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data);
 
        mesh_set_smooth_faces(em, 0);
 
-       DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
+       DAG_id_tag_update(obedit->data, 0);
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
 
        return OPERATOR_FINISHED;
@@ -7176,7 +7500,7 @@ void MESH_OT_faces_shade_flat(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Shade Flat";
-       ot->description= "Display faces 'flat'.";
+       ot->description= "Display faces 'flat'";
        ot->idname= "MESH_OT_faces_shade_flat";
 
        /* api callbacks */
@@ -7245,7 +7569,7 @@ void MESH_OT_select_axis(wmOperatorType *ot)
                {-1, "ALIGNED",  0, "Aligned Axis", ""},
                {0, NULL, 0, NULL, NULL}};
        
-       static EnumPropertyItem axis_items[] = {
+       static EnumPropertyItem axis_items_xyz[] = {
                {0, "X_AXIS", 0, "X Axis", ""},
                {1, "Y_AXIS", 0, "Y Axis", ""},
                {2, "Z_AXIS", 0, "Z Axis", ""},
@@ -7253,7 +7577,7 @@ void MESH_OT_select_axis(wmOperatorType *ot)
 
        /* identifiers */
        ot->name= "Select Axis";
-       ot->description= "Select all data in the mesh on a single axis.";
+       ot->description= "Select all data in the mesh on a single axis";
        ot->idname= "MESH_OT_select_axis";
 
        /* api callbacks */
@@ -7265,6 +7589,6 @@ void MESH_OT_select_axis(wmOperatorType *ot)
 
        /* properties */
        RNA_def_enum(ot->srna, "mode", axis_mode_items, 0, "Axis Mode", "Axis side to use when selecting");
-       RNA_def_enum(ot->srna, "axis", axis_items, 0, "Axis", "Select the axis to compare each vertex on");
+       RNA_def_enum(ot->srna, "axis", axis_items_xyz, 0, "Axis", "Select the axis to compare each vertex on");
 }