Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2012-10-20 13:48:41 +0400
committerCampbell Barton <ideasman42@gmail.com>2012-10-20 13:48:41 +0400
commita7a723283b9ec72888850999993287b598ceaecd (patch)
treed70d719afdf934e4bb07bae3d3f56724fa1b9572 /source/blender
parent95a414955ce2d15c62adde665ced18804ca98945 (diff)
add BM_edge_find_double() and use in bmesh decimator to fix crash.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/bmesh/intern/bmesh_decimate.c27
-rw-r--r--source/blender/bmesh/intern/bmesh_queries.c22
-rw-r--r--source/blender/bmesh/intern/bmesh_queries.h1
3 files changed, 49 insertions, 1 deletions
diff --git a/source/blender/bmesh/intern/bmesh_decimate.c b/source/blender/bmesh/intern/bmesh_decimate.c
index 122f24955c6..519bdba02a9 100644
--- a/source/blender/bmesh/intern/bmesh_decimate.c
+++ b/source/blender/bmesh/intern/bmesh_decimate.c
@@ -503,8 +503,31 @@ static void bm_decim_edge_collapse(BMesh *bm, BMEdge *e,
BMEdge *e_first;
e_iter = e_first = v->e;
do {
+ //BLI_assert(BM_edge_find_double(e_iter) == NULL);
+#ifdef USE_SAFETY_CHECKS
+ /* note! - this check is slow, but we can't avoid it - Campbell */
+ BMEdge *e_double;
+
+ e_double = BM_edge_find_double(e_iter);
+
+ if (UNLIKELY(e_double != NULL)) {
+ int e_index = BM_elem_index_get(e_double);
+ if (BM_edge_splice(bm, e_double, e_iter)) {
+ if (eheap_table[e_index]) {
+ BLI_heap_remove(eheap, eheap_table[e_index]);
+ eheap_table[e_index] = NULL;
+ }
+ }
+ }
+
+ /* if this happens, the e_double check could be put in a while loop,
+ * so as to keep removing doubles while they are found. so far this isnt needed */
+ BLI_assert(BM_edge_find_double(e_iter) == NULL);
+#endif
+
bm_decim_build_edge_cost_single(e_iter, vquadrics, eheap, eheap_table);
} while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first);
+
}
}
}
@@ -566,9 +589,11 @@ void BM_mesh_decimate(BMesh *bm, const float factor)
}
#endif
-
/* free vars */
MEM_freeN(vquadrics);
MEM_freeN(eheap_table);
BLI_heap_free(eheap, NULL);
+
+ /* testing only */
+ // BM_mesh_validate(bm);
}
diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c
index 6bf4e3db1d3..9520b0298d8 100644
--- a/source/blender/bmesh/intern/bmesh_queries.c
+++ b/source/blender/bmesh/intern/bmesh_queries.c
@@ -1064,6 +1064,28 @@ BMEdge *BM_edge_exists(BMVert *v1, BMVert *v2)
}
/**
+ * Returns an edge sharing the same vertices as this one.
+ * This isn't an invalid state but tools should clean up these cases before
+ * returning the mesh to the user.
+ */
+BMEdge *BM_edge_find_double(BMEdge *e)
+{
+ BMVert *v = e->v1;
+ BMVert *v_other = e->v2;
+
+ BMEdge *e_iter;
+
+ e_iter = e;
+ while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e) {
+ if (UNLIKELY(BM_vert_in_edge(e_iter, v_other))) {
+ return e_iter;
+ }
+ }
+
+ return NULL;
+}
+
+/**
* Given a set of vertices \a varr, find out if
* all those vertices overlap an existing face.
*
diff --git a/source/blender/bmesh/intern/bmesh_queries.h b/source/blender/bmesh/intern/bmesh_queries.h
index 84a5ffacec7..166b8a54f8a 100644
--- a/source/blender/bmesh/intern/bmesh_queries.h
+++ b/source/blender/bmesh/intern/bmesh_queries.h
@@ -74,6 +74,7 @@ BMLoop *BM_face_find_shortest_loop(BMFace *f);
BMLoop *BM_face_find_longest_loop(BMFace *f);
BMEdge *BM_edge_exists(BMVert *v1, BMVert *v2);
+BMEdge *BM_edge_find_double(BMEdge *e);
int BM_face_exists_overlap(BMesh *bm, BMVert **varr, int len, BMFace **r_existface);