converted more mixed tab/space indentations to tabs. only whitespace changes.
[blender.git] / source / blender / editors / mesh / editmesh_tools.c
index 5d6d9e3..83840f0 100644 (file)
  * ***** 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
@@ -52,11 +57,13 @@ editmesh_tool.c: UI called tools for editmesh, geometry changes here, otherwise
 
 #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_depsgraph.h"
@@ -80,7 +87,7 @@ editmesh_tool.c: UI called tools for editmesh, geometry changes here, otherwise
 #include "mesh_intern.h"
 
 /* XXX */
-static void waitcursor(int val) {}
+static void waitcursor(int UNUSED(val)) {}
 #define add_numbut(a, b, c, d, e, f, g) {}
 
 /* XXX */
@@ -482,11 +489,12 @@ static int removedoublesflag_exec(bContext *C, wmOperator *op)
        if(count) {
                recalc_editnormals(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_reportf(op->reports, RPT_INFO, "Removed %d vertices", count);
+       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;
@@ -494,6 +502,8 @@ static int removedoublesflag_exec(bContext *C, wmOperator *op)
 
 void MESH_OT_remove_doubles(wmOperatorType *ot)
 {
+       PropertyRNA *prop;
+
        /* identifiers */
        ot->name= "Remove Doubles";
        ot->description= "Remove duplicate vertices";
@@ -506,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;
 
@@ -519,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;
@@ -551,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;
@@ -609,14 +643,39 @@ 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, short type)
+static void extrude_mesh(Object *obedit, EditMesh *em, wmOperator *op, short type)
 {
        float nor[3]= {0.0, 0.0, 0.0};
        short transmode= 0;
@@ -631,7 +690,7 @@ void extrude_mesh(Scene *scene, Object *obedit, EditMesh *em, wmOperator *op, sh
        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);
@@ -642,7 +701,7 @@ void extrude_mesh(Scene *scene, Object *obedit, EditMesh *em, wmOperator *op, sh
                        * 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);
+               DAG_id_tag_update(obedit->data, 0);
 
                /* individual faces? */
 //             BIF_TransformSetUndo("Extrude");
@@ -664,17 +723,16 @@ void extrude_mesh(Scene *scene, Object *obedit, EditMesh *em, wmOperator *op, sh
 }
 
 // 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, RNA_int_get(op->ptr, "type"));
+       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;
@@ -683,20 +741,19 @@ 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, RNA_int_get(op->ptr, "type"));
+       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;
 }
 
-EnumPropertyItem extrude_items[] = {
+static EnumPropertyItem extrude_items[] = {
                {1, "REGION", 0, "Region", ""},
                {2, "FACES", 0, "Individual Faces", ""},
                {3, "EDGES", 0, "Only Edges", ""},
@@ -704,7 +761,7 @@ EnumPropertyItem extrude_items[] = {
                {0, NULL, 0, NULL, NULL}};
 
 
-static EnumPropertyItem *extrude_itemf(bContext *C, PointerRNA *ptr, int *free)
+static EnumPropertyItem *mesh_extrude_itemf(bContext *C, PointerRNA *UNUSED(ptr), int *free)
 {
        EnumPropertyItem *item= NULL;
        Object *obedit= CTX_data_edit_object(C);
@@ -712,7 +769,7 @@ static EnumPropertyItem *extrude_itemf(bContext *C, PointerRNA *ptr, int *free)
 
        int totitem= 0;
 
-       if(!obedit)
+       if(obedit==NULL || obedit->type != OB_MESH)
                return extrude_items;
 
        em = BKE_mesh_get_editmesh(obedit->data);
@@ -792,11 +849,11 @@ void MESH_OT_extrude(wmOperatorType *ot)
        /* properties */
        prop= RNA_def_enum(ot->srna, "type", extrude_items, 0, "Type", "");
        RNA_def_property_flag(prop, PROP_HIDDEN);
-       RNA_def_enum_funcs(prop, extrude_itemf);
+       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);
@@ -811,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);
@@ -871,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);
@@ -887,7 +944,7 @@ void MESH_OT_extrude_repeat(wmOperatorType *ot)
 
        /* 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;
@@ -923,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;
 
@@ -975,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);
@@ -989,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);
@@ -1075,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;
        }
@@ -1087,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);
@@ -1189,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);
@@ -1210,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;
@@ -1255,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) {
@@ -1300,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;
@@ -1347,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);
@@ -1419,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;
@@ -1517,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);
 }
 
@@ -1681,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;
@@ -1702,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
@@ -2617,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;
                                        }
@@ -2699,7 +2755,7 @@ void esubdivideflag(Object *obedit, EditMesh *em, int flag, float smooth, float
 
                                // Beauty Long Edges
                                else {
-                                        for(j=0;j<2;j++) {
+                                       for(j=0;j<2;j++) {
                                                hold = -1;
                                                for(i=0;i<4;i++) {
                                                        if(length[i] < 0) {
@@ -2757,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) {
@@ -2913,8 +2969,8 @@ void esubdivideflag(Object *obedit, EditMesh *em, int flag, float smooth, float
                        }
                }
        }
-        if(em->selectmode & SCE_SELECT_VERTEX) {
-                for(eed = em->edges.first;eed;eed = eed->next) {
+       if(em->selectmode & SCE_SELECT_VERTEX) {
+               for(eed = em->edges.first;eed;eed = eed->next) {
                        if(eed->f & SELECT) {
                                eed->v1->f |= SELECT;
                                eed->v2->f |= SELECT;
@@ -2941,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);
@@ -3161,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);
@@ -3182,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;
@@ -3207,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)
 {
@@ -3447,7 +3510,7 @@ void join_triangles(EditMesh *em)
 #define FACE_MARKCLEAR(f) (f->f1 = 1)
 
 /* quick hack, basically a copy of beautify_fill */
-void edge_flip(EditMesh *em)
+static void edge_flip(EditMesh *em)
 {
        EditVert *v1, *v2, *v3, *v4;
        EditEdge *eed, *nexted;
@@ -3548,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}};
@@ -3580,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;
@@ -3768,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;
                }
@@ -3783,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;
        }
@@ -3793,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;
@@ -3822,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;
@@ -3998,8 +4061,8 @@ useless:
                }
                // Make sure loop is not 2 edges of same face
                if(ct > 1) {
-                  BKE_report(op->reports, RPT_ERROR, "Loop crosses itself");
-                  return 0;
+                       BKE_report(op->reports, RPT_ERROR, "Loop crosses itself");
+                       return 0;
                }
        }
        // Get # of selected verts
@@ -4116,11 +4179,11 @@ useless:
                        for(eed=em->edges.first;eed;eed=eed->next) {
                                if(editedge_containsVert(eed, ev)) {
                                        if(!(eed->f & SELECT)) {
-                                                if(!tempsv->up) {
-                                                        tempsv->up = eed;
-                                                } else if (!(tempsv->down)) {
-                                                        tempsv->down = eed;
-                                                }
+                                               if(!tempsv->up) {
+                                                       tempsv->up = eed;
+                                               } else if (!(tempsv->down)) {
+                                                       tempsv->down = eed;
+                                               }
                                        }
                                }
                        }
@@ -4132,33 +4195,33 @@ useless:
                                        for(efa = em->faces.first;efa;efa=efa->next) {
                                                if(editface_containsEdge(efa, eed)) {
                                                        if(editedge_containsVert(efa->e1, ev) && efa->e1 != eed) {
-                                                                if(!tempsv->up) {
-                                                                        tempsv->up = efa->e1;
-                                                                } else if (!(tempsv->down)) {
-                                                                        tempsv->down = efa->e1;
-                                                                }
+                                                               if(!tempsv->up) {
+                                                                       tempsv->up = efa->e1;
+                                                               } else if (!(tempsv->down)) {
+                                                                       tempsv->down = efa->e1;
+                                                               }
                                                        }
                                                        if(editedge_containsVert(efa->e2, ev) && efa->e2 != eed) {
-                                                                if(!tempsv->up) {
-                                                                        tempsv->up = efa->e2;
-                                                                } else if (!(tempsv->down)) {
-                                                                        tempsv->down = efa->e2;
-                                                                }
+                                                               if(!tempsv->up) {
+                                                                       tempsv->up = efa->e2;
+                                                               } else if (!(tempsv->down)) {
+                                                                       tempsv->down = efa->e2;
+                                                               }
                                                        }
                                                        if(editedge_containsVert(efa->e3, ev) && efa->e3 != eed) {
-                                                                if(!tempsv->up) {
-                                                                        tempsv->up = efa->e3;
-                                                                } else if (!(tempsv->down)) {
-                                                                        tempsv->down = efa->e3;
-                                                                }
+                                                               if(!tempsv->up) {
+                                                                       tempsv->up = efa->e3;
+                                                               } else if (!(tempsv->down)) {
+                                                                       tempsv->down = efa->e3;
+                                                               }
                                                        }
                                                        if(efa->e4) {
                                                                if(editedge_containsVert(efa->e4, ev) && efa->e4 != eed) {
-                                                                        if(!tempsv->up) {
-                                                                                tempsv->up = efa->e4;
-                                                                        } else if (!(tempsv->down)) {
-                                                                                tempsv->down = efa->e4;
-                                                                        }
+                                                                       if(!tempsv->up) {
+                                                                               tempsv->up = efa->e4;
+                                                                       } else if (!(tempsv->down)) {
+                                                                               tempsv->down = efa->e4;
+                                                                       }
                                                                }
                                                        }
 
@@ -4195,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;
@@ -4602,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;
@@ -4616,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;
@@ -4644,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);
@@ -4664,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);
@@ -4696,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
 
@@ -4715,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;
@@ -4754,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*/
@@ -4869,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;
        }
@@ -4939,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;
        }
@@ -5024,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);
@@ -5069,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;
        }
 
@@ -5084,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;
        }
 
@@ -5097,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;
 }
 
@@ -5110,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;
@@ -5139,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_v3(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;
                                }
@@ -5172,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;
@@ -5231,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 *************************/
@@ -5340,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{
@@ -5673,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;
@@ -5682,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){
@@ -5835,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:
@@ -5844,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);
@@ -5863,7 +5949,7 @@ static int merge_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;
@@ -5877,7 +5963,7 @@ 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;
@@ -5960,7 +6046,6 @@ 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;
@@ -5971,17 +6056,24 @@ static int select_vertex_path_exec(bContext *C, wmOperator *op)
        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) {
-               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;
@@ -6102,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;
        }
 
@@ -6137,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);
@@ -6318,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);
@@ -6387,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;
        }
@@ -6443,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;
@@ -6461,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;
        }
@@ -6532,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;
@@ -6549,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;
        }
@@ -6588,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;
@@ -6606,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;
        }
@@ -6644,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;
@@ -6683,7 +6775,7 @@ 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)
@@ -6719,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 *************************/
@@ -6742,7 +6834,7 @@ static int subdivide_exec(bContext *C, wmOperator *op)
 
        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;
@@ -6764,7 +6856,7 @@ 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, 1000.0f);
+       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_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");
 }
@@ -6996,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 */
@@ -7015,7 +7107,7 @@ static void fill_mesh(EditMesh *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);
@@ -7024,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;
@@ -7046,7 +7138,7 @@ void MESH_OT_fill(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
-static int beautify_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);
@@ -7055,7 +7147,7 @@ static int beautify_fill_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;
@@ -7126,7 +7218,7 @@ static int sort_faces_exec(bContext *C, wmOperator *op)
        if (!v3d) return OPERATOR_CANCELLED;
 
        /* This operator work in Object Mode, not in edit mode.
-        * After talk with Cambell we agree that there is no point to port this to EditMesh right now.
+        * 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);
@@ -7219,7 +7311,7 @@ static int sort_faces_exec(bContext *C, wmOperator *op)
        }
 
        MEM_freeN(index);
-       DAG_id_flush_update(ob->data, OB_RECALC_DATA);
+       DAG_id_tag_update(ob->data, 0);
 
        /* Return to editmode. */
        ED_object_enter_editmode(C, 0);
@@ -7233,7 +7325,7 @@ void MESH_OT_sort_faces(wmOperatorType *ot)
                { 1, "VIEW_AXIS", 0, "View Axis", "" },
                { 2, "CURSOR_DISTANCE", 0, "Cursor Distance", "" },
                { 3, "MATERIAL", 0, "Material", "" },
-               { 4, "SELECTION", 0, "Selection", "" },
+               { 4, "SELECTED", 0, "Selected", "" },
                { 5, "RANDOMIZE", 0, "Randomize", "" },
                { 0, NULL, 0, NULL, NULL }};
 
@@ -7256,14 +7348,14 @@ void MESH_OT_sort_faces(wmOperatorType *ot)
 
 /********************** 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);
@@ -7285,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);
@@ -7314,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);
@@ -7357,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);
@@ -7368,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;
@@ -7389,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;
@@ -7475,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", ""},
@@ -7495,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");
 }