merge with 2.5 (not trunk, last merge message said that on accident) at r22252
[blender.git] / source / blender / editors / mesh / editmesh_tools.c
index d29a4e21913a47a4ade75282cefb4da3a179994b..c1497ce1a06bf0c36be8afc704876695b1646247 100644 (file)
@@ -75,6 +75,8 @@ editmesh_tool.c: UI called tools for editmesh, geometry changes here, otherwise
 #include "BKE_utildefines.h"
 #include "BKE_bmesh.h"
 #include "BKE_report.h"
+#include "BKE_tessmesh.h"
+
 
 #include "BIF_gl.h"
 #include "BIF_glutil.h"
@@ -91,6 +93,7 @@ editmesh_tool.c: UI called tools for editmesh, geometry changes here, otherwise
 #include "UI_interface.h"
 
 #include "mesh_intern.h"
+#include "bmesh.h"
 
 /* XXX */
 static int extern_qread() {return 0;}
@@ -529,6 +532,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)
 {
+#if 0 //BMESH_TODO
        ViewContext vc;
        EditVert *eve;
        xvertsort *sortblock;
@@ -560,7 +564,7 @@ void xsortvert_flag(bContext *C, int flag)
        addlisttolist(&vc.em->verts, &tbase);
 
        MEM_freeN(sortblock);
-
+#endif
 }
 
 /* called from buttons */
@@ -643,12 +647,15 @@ void extrude_mesh(Scene *scene, Object *obedit, EditMesh *em, wmOperator *op)
        }
        else if(em->selectmode & SCE_SELECT_EDGE) {
                if (em->totedgesel==0) nr = 0;
-               else if (em->totedgesel==1) nr = 3;
+               
+               nr = 1;
+               /*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;
@@ -698,6 +705,8 @@ void extrude_mesh(Scene *scene, Object *obedit, EditMesh *em, wmOperator *op)
 
 }
 
+#if 0 
+//need to see if this really had new stuff I should merge over
 // XXX should be a menu item
 static int mesh_extrude_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {
@@ -762,6 +771,7 @@ void MESH_OT_extrude(wmOperatorType *ot)
        Properties_Constraints(ot);
        RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", "");
 }
+#endif
 
 static int split_mesh(bContext *C, wmOperator *op)
 {
@@ -800,7 +810,9 @@ void MESH_OT_split(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
-
+#if 0
+//this also showed up in a merge, need to check if it
+//needs changes ported over to new extrude code too
 static int extrude_repeat_mesh(bContext *C, wmOperator *op)
 {
        Scene *scene= CTX_data_scene(C);
@@ -863,7 +875,7 @@ void MESH_OT_extrude_repeat(wmOperatorType *ot)
        RNA_def_float(ot->srna, "offset", 2.0f, 0.0f, 100.0f, "Offset", "", 0.0f, FLT_MAX);
        RNA_def_int(ot->srna, "steps", 10, 0, 180, "Steps", "", 0, INT_MAX);
 }
-
+#endif
 /* ************************** spin operator ******************** */
 
 
@@ -1156,190 +1168,6 @@ static void erase_vertices(EditMesh *em, ListBase *l)
        }
 }
 
-void delete_mesh(Object *obedit, EditMesh *em, wmOperator *op, int event)
-{
-       EditFace *efa, *nextvl;
-       EditVert *eve,*nextve;
-       EditEdge *eed,*nexted;
-       int count;
-       char *str="Erase";
-
-
-       if(event<1) return;
-
-       if(event==10 ) {
-               str= "Erase Vertices";
-               erase_edges(em, &em->edges);
-               erase_faces(em, &em->faces);
-               erase_vertices(em, &em->verts);
-       }
-       else if(event==6) {
-               if(!EdgeLoopDelete(em, op))
-                       return;
-
-               str= "Erase Edge Loop";
-       }
-       else if(event==4) {
-               str= "Erase Edges & Faces";
-               efa= em->faces.first;
-               while(efa) {
-                       nextvl= efa->next;
-                       /* delete only faces with 1 or more edges selected */
-                       count= 0;
-                       if(efa->e1->f & SELECT) count++;
-                       if(efa->e2->f & SELECT) count++;
-                       if(efa->e3->f & SELECT) count++;
-                       if(efa->e4 && (efa->e4->f & SELECT)) count++;
-                       if(count) {
-                               BLI_remlink(&em->faces, efa);
-                               free_editface(em, efa);
-                       }
-                       efa= nextvl;
-               }
-               eed= em->edges.first;
-               while(eed) {
-                       nexted= eed->next;
-                       if(eed->f & SELECT) {
-                               remedge(em, eed);
-                               free_editedge(em, eed);
-                       }
-                       eed= nexted;
-               }
-               efa= em->faces.first;
-               while(efa) {
-                       nextvl= efa->next;
-                       event=0;
-                       if( efa->v1->f & SELECT) event++;
-                       if( efa->v2->f & SELECT) event++;
-                       if( efa->v3->f & SELECT) event++;
-                       if(efa->v4 && (efa->v4->f & SELECT)) event++;
-
-                       if(event>1) {
-                               BLI_remlink(&em->faces, efa);
-                               free_editface(em, efa);
-                       }
-                       efa= nextvl;
-               }
-       }
-       else if(event==1) {
-               str= "Erase Edges";
-               // faces first
-               efa= em->faces.first;
-               while(efa) {
-                       nextvl= efa->next;
-                       event=0;
-                       if( efa->e1->f & SELECT) event++;
-                       if( efa->e2->f & SELECT) event++;
-                       if( efa->e3->f & SELECT) event++;
-                       if(efa->e4 && (efa->e4->f & SELECT)) event++;
-
-                       if(event) {
-                               BLI_remlink(&em->faces, efa);
-                               free_editface(em, efa);
-                       }
-                       efa= nextvl;
-               }
-               eed= em->edges.first;
-               while(eed) {
-                       nexted= eed->next;
-                       if(eed->f & SELECT) {
-                               remedge(em, eed);
-                               free_editedge(em, eed);
-                       }
-                       eed= nexted;
-               }
-               /* to remove loose vertices: */
-               eed= em->edges.first;
-               while(eed) {
-                       if( eed->v1->f & SELECT) eed->v1->f-=SELECT;
-                       if( eed->v2->f & SELECT) eed->v2->f-=SELECT;
-                       eed= eed->next;
-               }
-               eve= em->verts.first;
-               while(eve) {
-                       nextve= eve->next;
-                       if(eve->f & SELECT) {
-                               BLI_remlink(&em->verts,eve);
-                               free_editvert(em, eve);
-                       }
-                       eve= nextve;
-               }
-
-       }
-       else if(event==2) {
-               str="Erase Faces";
-               delfaceflag(em, SELECT);
-       }
-       else if(event==3) {
-               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";
-               efa= em->faces.first;
-               while(efa) {
-                       nextvl= efa->next;
-                       if(efa->f & SELECT) {
-                               BLI_remlink(&em->faces, efa);
-                               free_editface(em, efa);
-                       }
-                       efa= nextvl;
-               }
-       }
-
-       EM_fgon_flags(em);      // redo flags and indices for fgons
-}
-
-/* Note, these values must match delete_mesh() event values */
-static EnumPropertyItem prop_mesh_delete_types[] = {
-       {10,"VERT",             0, "Vertices", ""},
-       {1, "EDGE",             0, "Edges", ""},
-       {2, "FACE",             0, "Faces", ""},
-       {3, "ALL",              0, "All", ""},
-       {4, "EDGE_FACE",0, "Edges & Faces", ""},
-       {5, "ONLY_FACE",0, "Only Faces", ""},
-       {6, "EDGE_LOOP",0, "Edge Loop", ""},
-       {0, NULL, 0, NULL, NULL}
-};
-
-static int delete_mesh_exec(bContext *C, wmOperator *op)
-{
-       Scene *scene= CTX_data_scene(C);
-       Object *obedit= CTX_data_edit_object(C);
-       EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data);
-
-       delete_mesh(obedit, em, op, RNA_enum_get(op->ptr, "type"));
-
-       DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
-
-       BKE_mesh_end_editmesh(obedit->data, em);
-       return OPERATOR_FINISHED;
-}
-
-void MESH_OT_delete(wmOperatorType *ot)
-{
-       /* identifiers */
-       ot->name= "Delete";
-       ot->idname= "MESH_OT_delete";
-
-       /* api callbacks */
-       ot->invoke= WM_menu_invoke;
-       ot->exec= delete_mesh_exec;
-
-       ot->poll= ED_operator_editmesh;
-
-       /* flags */
-       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");
-}
-
-
 /*GB*/
 /*-------------------------------------------------------------------------------*/
 /*--------------------------- Edge Based Subdivide ------------------------------*/
@@ -1392,7 +1220,7 @@ static void alter_co(float *co, EditEdge *edge, float smooth, float fractal, int
                co[1] += vec1[1];
                co[2] += vec1[2];
        }
-       else if(beauty & B_SPHERE) { /* subdivide sphere */
+       /*else if(beauty & B_SPHERE) { // subdivide sphere
                Normalize(co);
                co[0]*= smooth;
                co[1]*= smooth;
@@ -1405,7 +1233,7 @@ static void alter_co(float *co, EditEdge *edge, float smooth, float fractal, int
                vec1[1]= fac*(float)(0.5-BLI_drand());
                vec1[2]= fac*(float)(0.5-BLI_drand());
                VecAddf(co, co, vec1);
-       }
+       }*/
 }
 
 /* assumes in the edge is the correct interpolated vertices already */
@@ -2253,7 +2081,7 @@ static void fill_quad_quadruple(EditMesh *em, EditFace *efa, struct GHash *gh, i
 
        for(i=1;i<=numcuts;i++) {
                /* we create a fake edge for the next loop */
-               temp.v2 = innerverts[i][0]                      = verts[1][i];
+               temp.v2 = innerverts[i][0] = verts[1][i];
                temp.v1 = innerverts[i][numcuts+1]  = verts[3][i];
 
                for(j=1;j<=numcuts;j++) {
@@ -2392,7 +2220,7 @@ static void fill_tri_triple(EditMesh *em, EditFace *efa, struct GHash *gh, int n
        MEM_freeN(innerverts);
 }
 
-//Next two fill types are for knife exact only and are provided to allow for knifing through vertices
+//Next two fill types are for   exact only and are provided to allow for knifing through vertices
 //This means there is no multicut!
 static void fill_quad_doublevert(EditMesh *em, EditFace *efa, int v1, int v2)
 {
@@ -3500,13 +3328,6 @@ void edge_flip(EditMesh *em)
        MEM_freeN(efaar);
 }
 
-#define DIRECTION_CW   1
-#define DIRECTION_CCW  2
-
-static const EnumPropertyItem direction_items[]= {
-       {DIRECTION_CW, "CW", 0, "Clockwise", ""},
-       {DIRECTION_CCW, "CCW", 0, "Counter Clockwise", ""},
-       {0, NULL, 0, NULL, NULL}};
 
 #define AXIS_X         1
 #define AXIS_Y         2
@@ -3516,6 +3337,7 @@ static const EnumPropertyItem axis_items[]= {
        {AXIS_Y, "Y", 0, "Y", ""},
        {0, NULL, 0, NULL, NULL}};
 
+#if 0
 static void edge_rotate(EditMesh *em, wmOperator *op, EditEdge *eed, int dir)
 {
        EditVert **verts[2];
@@ -3690,97 +3512,7 @@ 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)
-{
-       Scene *scene= CTX_data_scene(C);
-       Object *obedit= CTX_data_edit_object(C);
-       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.
-       short edgeCount = 0;
-
-       /*clear new flag for new edges, count selected edges */
-       for(eed= em->edges.first; eed; eed= eed->next) {
-               eed->f1= 0;
-               eed->f2 &= ~2;
-               if(eed->f & SELECT) edgeCount++;
-       }
-
-       if(edgeCount>1) {
-               /* more selected edges, check faces */
-               for(efa= em->faces.first; efa; efa= efa->next) {
-                       if(efa->f & SELECT) {
-                               efa->e1->f1++;
-                               efa->e2->f1++;
-                               efa->e3->f1++;
-                               if(efa->e4) efa->e4->f1++;
-                       }
-               }
-               edgeCount= 0;
-               for(eed= em->edges.first; eed; eed= eed->next) {
-                       if(eed->f1==2) edgeCount++;
-               }
-               if(edgeCount==1) {
-                       for(eed= em->edges.first; eed; eed= eed->next) {
-                               if(eed->f1==2) {
-                                       edge_rotate(em, op, eed,dir);
-                                       break;
-                               }
-                       }
-               }
-               else
-               {
-                       BKE_report(op->reports, RPT_ERROR, "Select one edge or two adjacent faces");
-                       BKE_mesh_end_editmesh(obedit->data, em);
-                       return OPERATOR_CANCELLED;
-               }
-       }
-       else if(edgeCount==1) {
-               for(eed= em->edges.first; eed; eed= eed->next) {
-                       if(eed->f & SELECT) {
-                               EM_select_edge(eed, 0);
-                               edge_rotate(em, op, eed,dir);
-                               break;
-                       }
-               }
-       }
-       else  {
-               BKE_report(op->reports, RPT_ERROR, "Select one edge or two adjacent faces");
-               BKE_mesh_end_editmesh(obedit->data, em);
-               return OPERATOR_CANCELLED;
-       }
-
-       /* flush selected vertices (again) to edges/faces */
-       EM_select_flush(em);
-
-       BKE_mesh_end_editmesh(obedit->data, em);
-
-       DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
-
-       return OPERATOR_FINISHED;
-}
-
-void MESH_OT_edge_rotate(wmOperatorType *ot)
-{
-       /* identifiers */
-       ot->name= "Rotate Selected Edge";
-       ot->idname= "MESH_OT_edge_rotate";
-
-       /* api callbacks */
-       ot->exec= edge_rotate_selected;
-       ot->poll= ED_operator_editmesh;
-
-       /* flags */
-       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
-
-       /* props */
-       RNA_def_enum(ot->srna, "direction", direction_items, DIRECTION_CW, "direction", "direction to rotate edge around.");
-}
-
+#endif
 
 /******************* BEVEL CODE STARTS HERE ********************/
 
@@ -4660,29 +4392,6 @@ useless:
 #endif // END OF XXX
 }
 
-int EdgeLoopDelete(EditMesh *em, wmOperator *op)
-{
-
-       /* temporal flag setting so we keep UVs when deleting edge loops,
-       * this is a bit of a hack but it works how you would want in almost all cases */
-       //      short uvcalc_flag_orig = 0; // XXX scene->toolsettings->uvcalc_flag;
-       //      scene->toolsettings->uvcalc_flag |= UVCALC_TRANSFORM_CORRECT;
-
-       if(!EdgeSlide(em, op, 1, 1)) {
-               return 0;
-       }
-
-       /* restore uvcalc flag */
-       //      scene->toolsettings->uvcalc_flag = uvcalc_flag_orig;
-
-       EM_select_more(em);
-       removedoublesflag(em, 1,0, 0.001);
-       EM_select_flush(em);
-       //      DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
-       return 1;
-}
-
-
 /* -------------------- More tools ------------------ */
 #if 0
 void mesh_set_face_flags(EditMesh *em, short mode)
@@ -4790,6 +4499,7 @@ static void mesh_rip_setface(EditMesh *em, EditFace *sefa)
 /* based on mouse cursor position, it defines how is being ripped */
 static int mesh_rip_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {
+#if 0 //BMESH_TODO
        Scene *scene= CTX_data_scene(C);
        ARegion *ar= CTX_wm_region(C);
        RegionView3D *rv3d= ar->regiondata;
@@ -4994,6 +4704,7 @@ static int mesh_rip_invoke(bContext *C, wmOperator *op, wmEvent *event)
 //     RNA_enum_set(op->ptr, "proportional", 0);
 //     RNA_boolean_set(op->ptr, "mirror", 0);
 //     WM_operator_name_call(C, "TFM_OT_translate", WM_OP_INVOKE_REGION_WIN, op->ptr);
+#endif
 
        return OPERATOR_FINISHED;
 }
@@ -5063,6 +4774,7 @@ void shape_propagate(Scene *scene, Object *obedit, EditMesh *em, wmOperator *op)
 
 void shape_copy_from_lerp(EditMesh *em, KeyBlock* thisBlock, KeyBlock* fromBlock)
 {
+#if 0 //BMESH_TODO
        EditVert *ev = NULL;
        short mval[2], curval[2], event = 0, finished = 0, canceled = 0, fullcopy=0 ;
        float perc = 0;
@@ -5139,6 +4851,7 @@ void shape_copy_from_lerp(EditMesh *em, KeyBlock* thisBlock, KeyBlock* fromBlock
                        }
                }
        return;
+#endif
 }
 
 
@@ -6301,6 +6014,14 @@ void MESH_OT_loop_to_region(wmOperatorType *ot)
 // XXX please check if these functions do what you want them to
 /* texface and vertex color editmode tools for the face menu */
 
+#define DIRECTION_CW   1
+#define DIRECTION_CCW  2
+
+static const EnumPropertyItem direction_items[]= {
+       {DIRECTION_CW, "CW", 0, "Clockwise", ""},
+       {DIRECTION_CCW, "CCW", 0, "Counter Clockwise", ""},
+       {0, NULL, 0, NULL, NULL}};
+
 static int mesh_rotate_uvs(bContext *C, wmOperator *op)
 {
        Scene *scene= CTX_data_scene(C);
@@ -6648,52 +6369,6 @@ void MESH_OT_colors_mirror(wmOperatorType *ot)
        RNA_def_enum(ot->srna, "axis", axis_items, DIRECTION_CW, "Axis", "Axis to mirror colors around.");
 }
 
-/********************** Subdivide Operator *************************/
-
-static int subdivide_exec(bContext *C, wmOperator *op)
-{
-       Scene *scene = CTX_data_scene(C);
-       Object *obedit= CTX_data_edit_object(C);
-       EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data);
-       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 flag= 0;
-
-       if(smooth != 0.0f)
-               flag |= B_SMOOTH;
-       if(fractal != 0.0f)
-               flag |= B_FRACTAL;
-
-       esubdivideflag(obedit, em, 1, smooth, fractal, scene->toolsettings->editbutflag|flag, cuts, 0);
-
-       DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
-
-       return OPERATOR_FINISHED;
-}
-
-void MESH_OT_subdivide(wmOperatorType *ot)
-{
-       /* identifiers */
-       ot->name= "Subdivide";
-       ot->idname= "MESH_OT_subdivide";
-
-       /* api callbacks */
-       ot->exec= subdivide_exec;
-       ot->poll= ED_operator_editmesh;
-
-       /* flags */
-       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
-
-       /* properties */
-       RNA_def_int(ot->srna, "number_cuts", 1, 1, 10, "Number of Cuts", "", 1, INT_MAX);
-       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, 1000.0f, "Smoothness", "Smoothness factor.", 0.0f, FLT_MAX);
-}
-
-/********************** 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)
@@ -7005,14 +6680,15 @@ static int quads_convert_to_tris_exec(bContext *C, wmOperator *op)
 {
        Scene *scene= CTX_data_scene(C);
        Object *obedit= CTX_data_edit_object(C);
-       EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data);
+       BMEditMesh *em= ((Mesh *)obedit->data)->edit_btmesh;
 
-       convert_to_triface(em,0);
+       //convert_to_triface(em,0);
+       if (!EDBM_CallOpf(em, op, "triangulate faces=%hf", BM_SELECT))
+               return OPERATOR_CANCELLED;
 
        DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
        WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
 
-       BKE_mesh_end_editmesh(obedit->data, em);
        return OPERATOR_FINISHED;
 }