diff --git a/source/blender/bmesh/bmesh.h b/source/blender/bmesh/bmesh.h index 5b1753a9902..f581e4b1054 100644 --- a/source/blender/bmesh/bmesh.h +++ b/source/blender/bmesh/bmesh.h @@ -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); diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c index ce59856f823..e7e0a2e5b24 100644 --- a/source/blender/bmesh/intern/bmesh_mods.c +++ b/source/blender/bmesh/intern/bmesh_mods.c @@ -40,19 +40,45 @@ * */ #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){ diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c index ca10129b4ab..3e2c3d9c4aa 100644 --- a/source/blender/bmesh/intern/bmesh_operators.c +++ b/source/blender/bmesh/intern/bmesh_operators.c @@ -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); } diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c index 73f713c5591..f4fcd607d27 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -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); diff --git a/source/blender/bmesh/intern/editmesh_to_bmesh.c b/source/blender/bmesh/intern/editmesh_to_bmesh.c index 12b5f55f9ee..dfe97297161 100644 --- a/source/blender/bmesh/intern/editmesh_to_bmesh.c +++ b/source/blender/bmesh/intern/editmesh_to_bmesh.c @@ -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){ diff --git a/source/blender/bmesh/operators/dissolveops.c b/source/blender/bmesh/operators/dissolveops.c index c9e29c9f94a..c4a59116b00 100644 --- a/source/blender/bmesh/operators/dissolveops.c +++ b/source/blender/bmesh/operators/dissolveops.c @@ -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++; } diff --git a/source/blender/bmesh/operators/extrudeops.c b/source/blender/bmesh/operators/extrudeops.c index 81776d673e7..dcc5d70e04e 100644 --- a/source/blender/bmesh/operators/extrudeops.c +++ b/source/blender/bmesh/operators/extrudeops.c @@ -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++) { diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 3bc59fe9094..7a617e6d340 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -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;