split dissolve_disk into dissolve_vert dissolve_disk as agreed. also made dissolve...
authorJoseph Eagar <joeedh@gmail.com>
Sun, 1 Mar 2009 06:23:22 +0000 (06:23 +0000)
committerJoseph Eagar <joeedh@gmail.com>
Sun, 1 Mar 2009 06:23:22 +0000 (06:23 +0000)
source/blender/bmesh/bmesh.h
source/blender/bmesh/intern/bmesh_mods.c
source/blender/bmesh/intern/bmesh_operators.c
source/blender/bmesh/intern/bmesh_polygon.c
source/blender/bmesh/intern/editmesh_to_bmesh.c
source/blender/bmesh/operators/dissolveops.c
source/blender/bmesh/operators/extrudeops.c
source/blender/editors/mesh/editmesh_tools.c

index 5b1753a9902380c3044a87d9b15bacf72c280c36..f581e4b1054c27b47749d409cd6519b7bdcf53e3 100644 (file)
@@ -195,7 +195,12 @@ void BM_Collapse_Vert(struct BMesh *bm, struct BMEdge *ke, struct BMVert *kv, fl
 struct BMVert *BM_Split_Edge(struct BMesh *bm, struct BMVert *v, struct BMEdge *e, struct BMEdge **ne, float percent, int calcnorm);
 struct BMVert  *BM_Split_Edge_Multi(struct BMesh *bm, struct BMEdge *e, int numcuts);
 BMEdge *BM_Connect_Verts(BMesh *bm, BMVert *v1, BMVert *v2, BMFace **nf);
-void BM_Dissolve_Disk(BMesh *bm, BMVert *v);
+
+/*dissolves vert surrounded by faces*/
+int BM_Dissolve_Disk(BMesh *bm, BMVert *v);
+
+/*dissolves vert, in more situations then BM_Dissolve_Disk.*/
+int BM_Dissolve_Vert(BMesh *bm, BMVert *v);
 
 /*Interpolation*/
 void BM_Data_Interp_From_Verts(struct BMesh *bm, struct BMVert *v1, struct BMVert *v2, struct BMVert *v, float fac);
index ce59856f8239674017d4fe4ccba2e89e8961a2ab..e7e0a2e5b2495b9bd7714f21b954f1a9f1d6cd49 100644 (file)
  * 
  */
 #if 1
-void BM_Dissolve_Disk(BMesh *bm, BMVert *v) {
-       BMFace *f, *f2;
-       BMEdge *e, *keepedge=NULL, *baseedge=NULL;
-       BMLoop *loop;
-       int done, len;
+int BM_Dissolve_Vert(BMesh *bm, BMVert *v) {
+       BMIter iter;
+       BMEdge *e;
+       int len=0;
+
+       if (!v) return 0;
+       
+       e = BMIter_New(&iter, bm, BM_EDGES_OF_VERT, v);
+       for (; e; e=BMIter_Step(&iter)) {
+               len++;
+       }
+       
+       if (len == 1) {
+               bmesh_ke(bm, v->edge);
+               bmesh_kv(bm, v);
+               return 1;
+       }
 
        if(BM_Nonmanifold_Vert(bm, v)) {
                if (!v->edge) bmesh_kv(bm, v);
                else if (!v->edge->loop) {
                        bmesh_ke(bm, v->edge);
                        bmesh_kv(bm, v);
-               }
-               return;
+               } else return 0;
+
+               return 1;
+       }
+
+       return BM_Dissolve_Disk(bm, v);
+}
+
+int BM_Dissolve_Disk(BMesh *bm, BMVert *v) {
+       BMFace *f, *f2;
+       BMEdge *e, *keepedge=NULL, *baseedge=NULL;
+       BMLoop *loop;
+       int done, len;
+
+       if(BM_Nonmanifold_Vert(bm, v)) {
+               return 0;
        }
        
        if(v->edge){
@@ -88,9 +114,6 @@ void BM_Dissolve_Disk(BMesh *bm, BMVert *v) {
                /*collapse the vertex*/
                BM_Collapse_Vert(bm, v->edge, v, 1.0, 0);
                BM_Join_Faces(bm, f, f2, NULL, 0, 0);
-       } else if (len == 1) {
-               bmesh_ke(bm, v->edge);
-               bmesh_kv(bm, v);
        }
 
        if(keepedge){
@@ -106,7 +129,7 @@ void BM_Dissolve_Disk(BMesh *bm, BMVert *v) {
                                        /*return if couldn't join faces in manifold
                                          conditions.*/
                                        //!disabled for testing why bad things happen
-                                       if (!f) return;
+                                       if (!f) return 0;
                                }
 
                                if(f){
@@ -126,6 +149,8 @@ void BM_Dissolve_Disk(BMesh *bm, BMVert *v) {
                /*join two remaining faces*/
                BM_Join_Faces(bm, f, f2, NULL, 0, 0);
        }
+
+       return 1;
 }
 #else
 void BM_Dissolve_Disk(BMesh *bm, BMVert *v){
index ca10129b4abe32b286d0f3520b2dbea030d678eb..3e2c3d9c4aa54caca2c56fa8e96ef429efdc0084 100644 (file)
@@ -800,6 +800,7 @@ void BMO_RaiseError(BMesh *bm, BMOperator *owner, int errcode, char *msg)
        bmop_error *err = MEM_callocN(sizeof(bmop_error), "bmop_error");
        
        err->errorcode = errcode;
+       if (!msg) msg = bmop_error_messages[errcode];
        err->msg = msg;
        err->op = owner;
        
@@ -825,7 +826,7 @@ int BMO_PopError(BMesh *bm, char **msg, BMOperator **op)
        if (errorcode) {
                bmop_error *err = bm->errorstack.first;
                
-               BLI_remlink(&bm->errorstack, &bm->errorstack.first);
+               BLI_remlink(&bm->errorstack, bm->errorstack.first);
                MEM_freeN(err);
        }
 
index 73f713c55910f6116b6aeb29444b4e938bc0d0b7..f4fcd607d27478a3d9d7f0755482bdbc8ef6144b 100644 (file)
@@ -339,11 +339,10 @@ int linecrosses(float *v1, float *v2, float *v3, float *v4)
        return w1 == w2 && w2 == w3 && w3 == w4 && w4==w5;
 }
 
-int goodline(float (*projectverts)[3], int v1i, int v2i, int nvert)
+int goodline(float (*projectverts)[3], int v1i, int v2i, int nvert, float *outv)
 {
-       /*the hardcoded stuff here, 200000, 0.999, and 1.0001 may be problems
+       /*the hardcoded stuff here, 0.999 and 1.0001, may be problems
          in the future, not sure. - joeedh*/
-       static float outv[3] = {2000.0f, 2000.0f, 0.0f};
        float v1[3], v2[3], p[3], vv1[3], vv2[3], mid[3], a[3], b[3];
        int i = 0, lcount=0;
        
@@ -398,7 +397,7 @@ int goodline(float (*projectverts)[3], int v1i, int v2i, int nvert)
  *
 */
 
-static BMLoop *find_ear(BMFace *f, float (*verts)[3], int nvert)
+static BMLoop *find_ear(BMFace *f, float (*verts)[3], int nvert, float *outv)
 {
        BMVert *v1, *v2, *v3;
        BMLoop *bestear = NULL, *l;
@@ -415,12 +414,13 @@ static BMLoop *find_ear(BMFace *f, float (*verts)[3], int nvert)
 
                if (BM_Edge_Exist(v1, v3)) isear = 0;
 
-               if (isear && !goodline(verts, v1->head.eflag2, v3->head.eflag2, nvert)) isear = 0;
+               if (isear && !goodline(verts, v1->head.eflag2, v3->head.eflag2,
+                                      nvert, outv)) isear = 0;
                if(isear){
                        angle = VecAngle3(verts[v1->head.eflag2], verts[v2->head.eflag2], verts[v3->head.eflag2]);
-                       if(!bestear || ABS(angle-40.0) < bestangle){
+                       if(!bestear || ABS(angle-40.0f) < bestangle){
                                bestear = l;
-                               bestangle = ABS(40.0-angle);
+                               bestangle = ABS(40.0f-angle);
                        }
                }
                l = (BMLoop*)(l->head.next);
@@ -450,6 +450,7 @@ void BM_Triangulate_Face(BMesh *bm, BMFace *f, float (*projectverts)[3], int new
 {
        int i, done, nvert;
        BMLoop *l, *newl, *nextloop;
+       float outv[3] = {-1.0e30f, -1.0e30f, -1.0e30f};
 
        /*copy vertex coordinates to vertspace array*/
        i = 0;
@@ -458,9 +459,15 @@ void BM_Triangulate_Face(BMesh *bm, BMFace *f, float (*projectverts)[3], int new
                VECCOPY(projectverts[i], l->v->co);
                l->v->head.eflag2 = i; /*warning, abuse! never duplicate in tools code! never you hear?*/ /*actually, get rid of this completely, use a new structure for this....*/
                i++;
+
+               outv[0] = MAX2(outv[0], l->v->co[0])+1.0f;
+               outv[1] = MAX2(outv[1], l->v->co[1])+1.0f;
+               outv[2] = MAX2(outv[2], l->v->co[2])+1.0f;
+
                l = (BMLoop*)(l->head.next);
        }while(l != f->loopbase);
        
+       
        //bmesh_update_face_normal(bm, f, projectverts);
 
        compute_poly_normal(f->no, projectverts, f->len);       
@@ -472,7 +479,7 @@ void BM_Triangulate_Face(BMesh *bm, BMFace *f, float (*projectverts)[3], int new
        done = 0;
        while(!done && f->len > 3){
                done = 1;
-               l = find_ear(f, projectverts, nvert);
+               l = find_ear(f, projectverts, nvert, outv);
                if(l) {
                        done = 0;
                        f = bmesh_sfme(bm, f, ((BMLoop*)(l->head.prev))->v, ((BMLoop*)(l->head.next))->v, &newl);
index 12b5f55f9eeb5acea9f496964554188da1d3e937..dfe97297161f600f53a9c22d651b54a34861d0f4 100644 (file)
@@ -259,8 +259,23 @@ static void fuse_fgon(BMesh *bm, BMFace *f)
 static BM_fgonconvert(BMesh *bm, EditMesh *em, int numCol, int numTex)
 {
        EditFace *efa;
+       BMFace *f;
+       BMIter iter;
        struct fgonsort *sortblock, *sb, *sb1;
        int a, b, amount=0;
+       
+       /*
+       for (efa=em->faces.first; efa; efa=efa->next) {
+               f = editface_to_BMFace(bm, em, efa, numCol, numTex);
+       }
+
+       for (f=bm->polys.first; f; f=f->head.next) {
+               fuse_fgon(bm, f);
+       }
+
+       return;*/
+
+       EM_fgon_flags(em);
 
        /*zero out efa->tmp, we store fgon index here*/
        for(efa = em->faces.first; efa; efa = efa->next){ 
index c9e29c9f94a8cc8e5c1fe0ea29a8e644576d2491..c4a59116b00389c4891988d8f387577062771491 100644 (file)
@@ -85,7 +85,11 @@ void dissolveverts_exec(BMesh *bm, BMOperator *op)
                len = 0;
                for (v=BMIter_New(&iter, bm, BM_VERTS, NULL); v; v=BMIter_Step(&iter)) {
                        if (BMO_TestFlag(bm, v, VERT_MARK)) {
-                               BM_Dissolve_Disk(bm, v);
+                               if (!BM_Dissolve_Vert(bm, v)) {
+                                       BMO_RaiseError(bm, op,
+                                             BMERR_DISSOLVEDISK_FAILED, NULL);
+                                       return;
+                               }
                                found = 1;
                                len++;
                        }
index 81776d673e7ec55354874b17d4cf654830dec2c8..dcc5d70e04eb9f0673e1dbd383080616a421a06f 100644 (file)
@@ -33,6 +33,8 @@ void extrude_edge_context_exec(BMesh *bm, BMOperator *op)
 
 #if 1
        for (e=BMIter_New(&iter, bm, BM_EDGES, NULL);e;e=BMIter_Step(&iter)) {
+               if (!BMO_TestFlag(bm, e, EXT_INPUT)) continue;
+
                found = 0;
                f = BMIter_New(&fiter, bm, BM_FACES_OF_EDGE, e);
                for (rlen=0; f; f=BMIter_Step(&fiter), rlen++) {
index 3bc59fe90945b533cf8aefc90f912c154e6af64f..7a617e6d34017c4f82a663adbb0696a9b51e5368 100644 (file)
@@ -1102,15 +1102,30 @@ static void erase_vertices(EditMesh *em, ListBase *l)
        }
 }
 
-void delete_mesh(Object *obedit, EditMesh *em, wmOperator *op, int event)
+/* Note, these values must match delete_mesh() event values */
+static EnumPropertyItem prop_mesh_delete_types[] = {
+       {10,"VERT",             "Vertices", ""},
+       {1, "EDGE",             "Edges", ""},
+       {2, "FACE",             "Faces", ""},
+       {3, "ALL",              "All", ""},
+       {4, "EDGE_FACE","Edges & Faces", ""},
+       {5, "ONLY_FACE","Only Faces", ""},
+       {6, "EDGE_LOOP","Edge Loop", ""},
+       {7, "COLLAPSE","Collapse", ""},
+       {0, NULL, NULL, NULL}
+};
+
+static int delete_mesh_exec(bContext *C, wmOperator *op)
 {
+       Object *obedit= CTX_data_edit_object(C);
+       EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
        EditFace *efa, *nextvl;
        EditVert *eve,*nextve;
        EditEdge *eed,*nexted;
        int count;
        char *str="Erase";
+       int event = RNA_enum_get(op->ptr, "type");
 
-       
        if(event<1) return;
 
        if(event==10 ) {
@@ -1121,19 +1136,27 @@ void delete_mesh(Object *obedit, EditMesh *em, wmOperator *op, int event)
        } 
        else if(event==7) {
                BMesh *bm = editmesh_to_bmesh(em);
-               BMOperator op;
+               BMOperator bmop;
                EditMesh *em2;
+               char *errmsg;
                
-               BMO_Init_Op(&op, BMOP_DISSOLVE_VERTS);
-               BMO_HeaderFlag_To_Slot(bm, &op, BMOP_DISVERTS_VERTIN, 
+               BMO_Init_Op(&bmop, BMOP_DISSOLVE_VERTS);
+               BMO_HeaderFlag_To_Slot(bm, &bmop, BMOP_DISVERTS_VERTIN, 
                                                BM_SELECT, BM_VERT);
-               BMO_Exec_Op(bm, &op);
+               BMO_Exec_Op(bm, &bmop);
                
-               BMO_Finish_Op(bm, &op);
+               BMO_Finish_Op(bm, &bmop);
                
+               if (BMO_GetError(bm, &errmsg, NULL)) {
+                       BKE_report(op->reports, RPT_ERROR, errmsg);
+                       BMO_ClearStack(bm);
+                       return OPERATOR_CANCELLED;
+               }
+
                em2 = bmesh_to_editmesh(bm);
                set_editMesh(em, em2);
                MEM_freeN(em2);
+               BM_Free_Mesh(bm);
        }
        else if(event==6) {
                if(!EdgeLoopDelete(em, op))
@@ -1254,29 +1277,6 @@ void delete_mesh(Object *obedit, EditMesh *em, wmOperator *op, int event)
 
        EM_fgon_flags(em);      // redo flags and indices for fgons
 
-//     DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
-}
-
-/* Note, these values must match delete_mesh() event values */
-static EnumPropertyItem prop_mesh_delete_types[] = {
-       {10,"VERT",             "Vertices", ""},
-       {1, "EDGE",             "Edges", ""},
-       {2, "FACE",             "Faces", ""},
-       {3, "ALL",              "All", ""},
-       {4, "EDGE_FACE","Edges & Faces", ""},
-       {5, "ONLY_FACE","Only Faces", ""},
-       {6, "EDGE_LOOP","Edge Loop", ""},
-       {7, "COLLAPSE","Collapse", ""},
-       {0, NULL, NULL, NULL}
-};
-
-static int delete_mesh_exec(bContext *C, wmOperator *op)
-{
-       Object *obedit= CTX_data_edit_object(C);
-       EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
-       
-       delete_mesh(obedit,em, op,RNA_enum_get(op->ptr, "type"));
-       
        WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
        
        return OPERATOR_FINISHED;