merge with 2.5 (not trunk, last merge message said that on accident) at r22252
[blender.git] / source / blender / editors / mesh / editmesh_add.c
index c24670aa8564fbee2c69189aeb5b07799dfee1a5..ff0814661ebd84cb6a5cfff6434a16e01a6eca2b 100644 (file)
@@ -60,6 +60,7 @@
 #include "BKE_object.h"
 #include "BKE_utildefines.h"
 #include "BKE_report.h"
+#include "BKE_tessmesh.h"
 
 #include "WM_api.h"
 #include "WM_types.h"
@@ -71,6 +72,8 @@
 #include "ED_util.h"
 #include "ED_view3d.h"
 
+#include "bmesh.h"
+
 #include "mesh_intern.h"
 
 /* bpymenu removed XXX */
@@ -116,127 +119,6 @@ static short icoface[20][3] = {
        {10,9,11}
 };
 
-/* *************** add-click-mesh (extrude) operator ************** */
-
-static int dupli_extrude_cursor(bContext *C, wmOperator *op, wmEvent *event)
-{
-       ViewContext vc;
-       EditVert *eve, *v1;
-       float min[3], max[3];
-       int done= 0;
-       
-       em_setup_viewcontext(C, &vc);
-       
-       INIT_MINMAX(min, max);
-       
-       for(v1= vc.em->verts.first;v1; v1=v1->next) {
-               if(v1->f & SELECT) {
-                       DO_MINMAX(v1->co, min, max);
-                       done= 1;
-               }
-       }
-
-       /* call extrude? */
-       if(done) {
-               EditEdge *eed;
-               float vec[3], cent[3], mat[3][3];
-               float nor[3]= {0.0, 0.0, 0.0};
-               
-               /* check for edges that are half selected, use for rotation */
-               done= 0;
-               for(eed= vc.em->edges.first; eed; eed= eed->next) {
-                       if( (eed->v1->f & SELECT)+(eed->v2->f & SELECT) == SELECT ) {
-                               if(eed->v1->f & SELECT) VecSubf(vec, eed->v1->co, eed->v2->co);
-                               else VecSubf(vec, eed->v2->co, eed->v1->co);
-                               VecAddf(nor, nor, vec);
-                               done= 1;
-                       }
-               }
-               if(done) Normalize(nor);
-               
-               /* center */
-               VecAddf(cent, min, max);
-               VecMulf(cent, 0.5f);
-               VECCOPY(min, cent);
-               
-               Mat4MulVecfl(vc.obedit->obmat, min);    // view space
-               view3d_get_view_aligned_coordinate(&vc, min, event->mval);
-               Mat4Invert(vc.obedit->imat, vc.obedit->obmat); 
-               Mat4MulVecfl(vc.obedit->imat, min); // back in object space
-               
-               VecSubf(min, min, cent);
-               
-               /* calculate rotation */
-               Mat3One(mat);
-               if(done) {
-                       float dot;
-                       
-                       VECCOPY(vec, min);
-                       Normalize(vec);
-                       dot= INPR(vec, nor);
-
-                       if( fabs(dot)<0.999) {
-                               float cross[3], si, q1[4];
-                               
-                               Crossf(cross, nor, vec);
-                               Normalize(cross);
-                               dot= 0.5f*saacos(dot);
-                               si= (float)sin(dot);
-                               q1[0]= (float)cos(dot);
-                               q1[1]= cross[0]*si;
-                               q1[2]= cross[1]*si;
-                               q1[3]= cross[2]*si;
-                               
-                               QuatToMat3(q1, mat);
-                       }
-               }
-               
-               extrudeflag(vc.obedit, vc.em, SELECT, nor);
-               rotateflag(vc.em, SELECT, cent, mat);
-               translateflag(vc.em, SELECT, min);
-               
-               recalc_editnormals(vc.em);
-       }
-       else {
-               float mat[3][3],imat[3][3];
-               float *curs= give_cursor(vc.scene, vc.v3d);
-               
-               VECCOPY(min, curs);
-               view3d_get_view_aligned_coordinate(&vc, min, event->mval);
-               
-               eve= addvertlist(vc.em, 0, NULL);
-
-               Mat3CpyMat4(mat, vc.obedit->obmat);
-               Mat3Inv(imat, mat);
-               
-               VECCOPY(eve->co, min);
-               Mat3MulVecfl(imat, eve->co);
-               VecSubf(eve->co, eve->co, vc.obedit->obmat[3]);
-               
-               eve->f= SELECT;
-       }
-       
-       //retopo_do_all();
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, vc.obedit); 
-       DAG_object_flush_update(vc.scene, vc.obedit, OB_RECALC_DATA);
-       
-       return OPERATOR_FINISHED;
-}
-
-void MESH_OT_dupli_extrude_cursor(wmOperatorType *ot)
-{
-       /* identifiers */
-       ot->name= "Duplicate or Extrude at 3D Cursor";
-       ot->idname= "MESH_OT_dupli_extrude_cursor";
-       
-       /* api callbacks */
-       ot->invoke= dupli_extrude_cursor;
-       ot->poll= ED_operator_editmesh;
-       
-       /* flags */
-       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
-}
-
 
 /* ********************** */
 
@@ -666,12 +548,53 @@ void addfaces_from_edgenet(EditMesh *em)
 // XXX DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
 }
 
-static void addedgeface_mesh(EditMesh *em, wmOperator *op)
+static void addedgeface_mesh(Mesh *me, BMEditMesh *bem, wmOperator *op)
 {
+       EditMesh *em;
        EditVert *eve, *neweve[4];
        EditEdge *eed;
        EditFace *efa;
        short amount=0;
+       
+       /*return if bmesh vert connect does anything.*/
+       if (bem->selectmode & SCE_SELECT_VERTEX) {
+               BMesh *bm = bem->bm;
+               BMOperator bmop;
+               int len, ok;
+               
+               EDBM_InitOpf(bem, &bmop, op, "connectverts verts=%hv", BM_SELECT);
+               BMO_Exec_Op(bem->bm, &bmop);
+
+               len = BMO_GetSlot(&bmop, "edgeout")->len;               
+
+               ok = EDBM_FinishOp(bem, &bmop, op, 1);
+               if (!ok) return OPERATOR_CANCELLED;
+
+               if (len) return;        
+       }
+
+       /*return if bmesh face dissolve finds stuff to
+         dissolve.  this entire tool should be
+         bmeshafied eventually, but until then
+         hacks like this to integrate with it
+         are necassary.*/
+       if (bem->selectmode & SCE_SELECT_VERTEX) {
+               BMesh *bm = bem->bm;
+               BMOperator bmop;
+               int len, ok;
+               
+               EDBM_InitOpf(bem, &bmop, op, "dissolvefaces faces=%hf", BM_SELECT);
+               BMO_Exec_Op(bem->bm, &bmop);
+
+               len = BMO_GetSlot(&bmop, "regionout")->len;             
+               
+               ok = EDBM_FinishOp(bem, &bmop, op, 1);
+               if (!ok) return OPERATOR_CANCELLED;
+
+               if (len) return;        
+       }
+
+       em = BKE_mesh_get_editmesh(me);
 
        /* how many selected ? */
        if(em->selectmode & SCE_SELECT_EDGE) {
@@ -691,16 +614,19 @@ static void addedgeface_mesh(EditMesh *em, wmOperator *op)
        if(amount==2) {
                eed= addedgelist(em, neweve[0], neweve[1], NULL);
                EM_select_edge(eed, 1);
-
+               
+               BKE_mesh_end_editmesh(me, em);
                // XXX          DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); 
                return;
        }
        else if(amount > 4) {
                addfaces_from_edgenet(em);
+               BKE_mesh_end_editmesh(me, em);
                return;
        }
        else if(amount<2) {
                BKE_report(op->reports, RPT_ERROR, "More vertices are needed to make an edge/face");
+               BKE_mesh_end_editmesh(me, em);
                return;
        }
 
@@ -739,6 +665,7 @@ static void addedgeface_mesh(EditMesh *em, wmOperator *op)
                                
                                if(count++ > 4){
                                        addfaces_from_edgenet(em);
+                                       BKE_mesh_end_editmesh(me, em);
                                        return;
                                } else {
                                /* if 4 edges exist, we just create the face, convex or not */
@@ -780,40 +707,10 @@ static void addedgeface_mesh(EditMesh *em, wmOperator *op)
                
                recalc_editnormals(em);
        }
-       }
-
-static int addedgeface_mesh_exec(bContext *C, wmOperator *op)
-{
-       Object *obedit= CTX_data_edit_object(C);
-       EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data));
-       
-       addedgeface_mesh(em, op);
-       
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
-       
-       DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA);     
-       
-       BKE_mesh_end_editmesh(obedit->data, em);
-       return OPERATOR_FINISHED;
-}
 
-void MESH_OT_edge_face_add(wmOperatorType *ot)
-{
-       /* identifiers */
-       ot->name= "Make Edge/Face";
-       ot->idname= "MESH_OT_edge_face_add";
-       
-       /* api callbacks */
-       ot->exec= addedgeface_mesh_exec;
-       ot->poll= ED_operator_editmesh;
-       
-       /* flags */
-       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
-       
+       BKE_mesh_end_editmesh(me, em);
 }
 
-
-
 /* ************************ primitives ******************* */
 
 // HACK: these can also be found in cmoview.tga.c, but are here so that they can be found by linker
@@ -1104,7 +1001,9 @@ static void make_prim(Object *obedit, int type, float mat[4][4], int tot, int se
                        }
 
                        dia*=200;
-                       for(a=1; a<subdiv; a++) esubdivideflag(obedit, em, 2, dia, 0, B_SPHERE,1,0);
+
+                       for(a=1; a<subdiv; a++) esubdivideflag(obedit, em, 2, dia, 0.0, 0, 1, 0);
+                       
                        /* and now do imat */
                        eve= em->verts.first;
                        while(eve) {
@@ -1281,9 +1180,9 @@ static float new_primitive_matrix(bContext *C, float primmat[][4])
        
        Mat4One(primmat);
        
-       if(rv3d)
+       if(rv3d && (U.flag & USER_ADD_VIEWALIGNED)) {
                Mat3CpyMat4(vmat, rv3d->viewmat);
-       else
+       else
                Mat3One(vmat);
        
        /* inverse transform for view and object */
@@ -1658,50 +1557,3 @@ void MESH_OT_primitive_ico_sphere_add(wmOperatorType *ot)
        RNA_def_int(ot->srna, "subdivisions", 2, 0, 6, "Subdivisions", "", 0, 8);
        RNA_def_float(ot->srna, "size", 1.0f, 0.0f, FLT_MAX, "Size", "", 0.001f, 100.00);
 }
-
-/****************** add duplicate operator ***************/
-
-static int mesh_duplicate_exec(bContext *C, wmOperator *op)
-{
-       Scene *scene= CTX_data_scene(C);
-       Object *ob= CTX_data_edit_object(C);
-       EditMesh *em= BKE_mesh_get_editmesh(ob->data);
-
-       adduplicateflag(em, SELECT);
-
-       BKE_mesh_end_editmesh(ob->data, em);
-
-       DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
-       WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, ob);
-       
-       return OPERATOR_FINISHED;
-}
-
-static int mesh_duplicate_invoke(bContext *C, wmOperator *op, wmEvent *event)
-{
-       WM_cursor_wait(1);
-       mesh_duplicate_exec(C, op);
-       WM_cursor_wait(0);
-       
-       RNA_int_set(op->ptr, "mode", TFM_TRANSLATION);
-       WM_operator_name_call(C, "TFM_OT_transform", WM_OP_INVOKE_REGION_WIN, op->ptr);
-       
-       return OPERATOR_FINISHED;
-}
-
-void MESH_OT_duplicate(wmOperatorType *ot)
-{
-       /* identifiers */
-       ot->name= "Duplicate";
-       ot->idname= "MESH_OT_duplicate";
-       
-       /* api callbacks */
-       ot->invoke= mesh_duplicate_invoke;
-       ot->exec= mesh_duplicate_exec;
-       
-       ot->poll= ED_operator_editmesh;
-       
-       /* to give to transform */
-       RNA_def_int(ot->srna, "mode", TFM_TRANSLATION, 0, INT_MAX, "Mode", "", 0, INT_MAX);
-}
-