From 618d4d1a6e4a3df8399549fa80846cdeacb7299c Mon Sep 17 00:00:00 2001 From: Andrew Wiggin Date: Sun, 23 Oct 2011 22:21:55 +0000 Subject: Add some validation checking and fix a bug in bmesh_[cut|splice][edge|vert] (used by vertex ripping) --- source/blender/bmesh/intern/bmesh_newcore.c | 69 +++++++++++++++++++---------- 1 file changed, 45 insertions(+), 24 deletions(-) (limited to 'source') diff --git a/source/blender/bmesh/intern/bmesh_newcore.c b/source/blender/bmesh/intern/bmesh_newcore.c index a4fd57c54bf..c49d2faa395 100644 --- a/source/blender/bmesh/intern/bmesh_newcore.c +++ b/source/blender/bmesh/intern/bmesh_newcore.c @@ -1521,6 +1521,9 @@ static int bmesh_splicevert(BMesh *bm, BMVert *v, BMVert *vtarget) e = v->e; } + CHECK_ELEMENT(bm, v); + CHECK_ELEMENT(bm, vtarget); + /* v is unused now, and can be killed */ BM_Kill_Vert(bm, v); @@ -1556,10 +1559,8 @@ static int bmesh_cutvert(BMesh *bm, BMVert *v, BMVert ***vout, int *len) /* Prime the stack with this unvisited edge */ BLI_array_append(stack, e); - /* Walk over edges that: - 1) have v as one of the vertices - 2) are connected to e through face loop cycles - assigning a unique index to that group of edges */ + /* Considering only edges and faces incident on vertex v, walk + the edges & faces and assign an index to each connected set */ while ((e = BLI_array_pop(stack))) { BLI_ghash_insert(visithash, e, SET_INT_IN_POINTER(maxindex)); BM_SetIndex(e, maxindex); @@ -1589,12 +1590,15 @@ static int bmesh_cutvert(BMesh *bm, BMVert *v, BMVert ***vout, int *len) continue; } + /* Loops here should alway refer to an edge that has v as an + endpoint. For each appearance of this vert in a face, there + will actually be two iterations: one for the loop heading + towards vertex v, and another for the loop heading out from + vertex v. Only need to swap the vertex on one of those times, + on the outgoing loop. */ if (l->v == v) { l->v = verts[i]; } - if (l->next->v == v) { - l->next->v = verts[i]; - } } BM_ITER(e, &eiter, bm, BM_EDGES_OF_VERT, v) { @@ -1603,27 +1607,29 @@ static int bmesh_cutvert(BMesh *bm, BMVert *v, BMVert ***vout, int *len) continue; } - BM_ITER(l, &liter, bm, BM_LOOPS_OF_EDGE, e) { - if (l->v == v) { - l->v = verts[i]; - } - if (l->next->v == v) { - l->next->v = verts[i]; - } - } - - if (e->v1 == v || e->v2 == v) { - bmesh_disk_remove_edge(e, v); - bmesh_edge_swapverts(e, v, verts[i]); - bmesh_disk_append_edge(e, verts[i]); - } + BLI_assert(e->v1 == v || e->v2 == v); + bmesh_disk_remove_edge(e, v); + bmesh_edge_swapverts(e, v, verts[i]); + bmesh_disk_append_edge(e, verts[i]); } BLI_ghash_free(visithash, NULL, NULL); BLI_array_free(stack); - *vout = verts; - *len = maxindex; + for (i = 0; i < maxindex; i++) { + CHECK_ELEMENT(bm, verts[i]); + } + + if (len != NULL) { + *len = maxindex; + } + + if (vout != NULL) { + *vout = verts; + } + else { + MEM_freeN(verts); + } return 1; } @@ -1645,10 +1651,17 @@ static int bmesh_spliceedge(BMesh *bm, BMEdge *e, BMEdge *etarget) while (e->l) { l = e->l; + BLI_assert(BM_Vert_In_Edge(etarget, l->v)); + BLI_assert(BM_Vert_In_Edge(etarget, l->next->v)); bmesh_radial_remove_loop(l, e); bmesh_radial_append(etarget, l); } + BLI_assert(bmesh_radial_length(e->l) == 0); + + CHECK_ELEMENT(bm, e); + CHECK_ELEMENT(bm, etarget); + BM_Kill_Edge(bm, e); return 1; @@ -1666,11 +1679,13 @@ static int bmesh_spliceedge(BMesh *bm, BMEdge *e, BMEdge *etarget) static int bmesh_cutedge(BMesh *bm, BMEdge *e, BMLoop *cutl) { BMEdge *ne; + int radlen; BLI_assert(cutl->e == e); BLI_assert(e->l); - if (bmesh_radial_length(e->l) < 2) { + radlen = bmesh_radial_length(e->l); + if (radlen < 2) { /* no cut required */ return 1; } @@ -1684,6 +1699,12 @@ static int bmesh_cutedge(BMesh *bm, BMEdge *e, BMLoop *cutl) bmesh_radial_append(ne, cutl); cutl->e = ne; + BLI_assert(bmesh_radial_length(e->l) == radlen - 1); + BLI_assert(bmesh_radial_length(ne->l) == 1); + + CHECK_ELEMENT(bm, ne); + CHECK_ELEMENT(bm, e); + return 1; } -- cgit v1.2.3