whitespace only, no functional change mixed tabs/spaces --> tabs.
[blender.git] / source / blender / editors / mesh / editmesh_tools.c
index 090a9aa358fa6e0a5a8792a540ac07ae361df3f6..dc1023952a6f31f45076707d82e65704f1cf2c24 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
@@ -525,7 +530,7 @@ static void xsortvert_flag__doSetX(void *userData, EditVert *UNUSED(eve), int x,
 }
 
 /* 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;
@@ -563,8 +568,31 @@ void xsortvert_flag(bContext *C, int flag)
 
 }
 
+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;
@@ -621,6 +649,31 @@ void hashvert_flag(EditMesh *em, int flag)
 
 }
 
+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 */
 static void extrude_mesh(Object *obedit, EditMesh *em, wmOperator *op, short type)
 {
@@ -675,7 +728,7 @@ static int mesh_extrude_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(even
        Object *obedit= CTX_data_edit_object(C);
        EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data);
        
-       extrude_mesh(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);
 
@@ -691,7 +744,7 @@ static int mesh_extrude_exec(bContext *C, wmOperator *op)
        Object *obedit= CTX_data_edit_object(C);
        EditMesh *em= BKE_mesh_get_editmesh(obedit->data);
 
-       extrude_mesh(obedit, em, op, RNA_int_get(op->ptr, "type"));
+       extrude_mesh(obedit, em, op, RNA_enum_get(op->ptr, "type"));
 
        DAG_id_tag_update(obedit->data, 0);
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
@@ -700,7 +753,7 @@ static int mesh_extrude_exec(bContext *C, wmOperator *op)
        return OPERATOR_FINISHED;
 }
 
-EnumPropertyItem extrude_items[] = {
+static EnumPropertyItem extrude_items[] = {
                {1, "REGION", 0, "Region", ""},
                {2, "FACES", 0, "Individual Faces", ""},
                {3, "EDGES", 0, "Only Edges", ""},
@@ -708,7 +761,7 @@ EnumPropertyItem extrude_items[] = {
                {0, NULL, 0, NULL, NULL}};
 
 
-static EnumPropertyItem *extrude_itemf(bContext *C, PointerRNA *UNUSED(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);
@@ -716,7 +769,7 @@ static EnumPropertyItem *extrude_itemf(bContext *C, PointerRNA *UNUSED(ptr), int
 
        int totitem= 0;
 
-       if(!obedit)
+       if(obedit==NULL || obedit->type != OB_MESH)
                return extrude_items;
 
        em = BKE_mesh_get_editmesh(obedit->data);
@@ -796,7 +849,7 @@ 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;
 }
 
@@ -891,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;
@@ -927,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;
 
@@ -1091,10 +1144,8 @@ 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)) {
@@ -1423,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;
@@ -2622,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;
                                        }
@@ -3173,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);
@@ -3194,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;
@@ -3219,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)
 {
@@ -3459,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;
@@ -3834,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;
@@ -5151,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;
                                }
@@ -5243,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 *************************/
@@ -5352,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{
@@ -7263,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 }};
 
@@ -7387,6 +7449,8 @@ 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 *UNUSED(op))