[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [51438] trunk/blender/source/blender/bmesh /intern: add BM_edge_find_double() and use in bmesh decimator to fix crash.
Campbell Barton
ideasman42 at gmail.com
Sat Oct 20 11:48:43 CEST 2012
Revision: 51438
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=51438
Author: campbellbarton
Date: 2012-10-20 09:48:41 +0000 (Sat, 20 Oct 2012)
Log Message:
-----------
add BM_edge_find_double() and use in bmesh decimator to fix crash.
Modified Paths:
--------------
trunk/blender/source/blender/bmesh/intern/bmesh_decimate.c
trunk/blender/source/blender/bmesh/intern/bmesh_queries.c
trunk/blender/source/blender/bmesh/intern/bmesh_queries.h
Modified: trunk/blender/source/blender/bmesh/intern/bmesh_decimate.c
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_decimate.c 2012-10-20 08:52:54 UTC (rev 51437)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_decimate.c 2012-10-20 09:48:41 UTC (rev 51438)
@@ -503,8 +503,31 @@
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 @@
}
#endif
-
/* free vars */
MEM_freeN(vquadrics);
MEM_freeN(eheap_table);
BLI_heap_free(eheap, NULL);
+
+ /* testing only */
+ // BM_mesh_validate(bm);
}
Modified: trunk/blender/source/blender/bmesh/intern/bmesh_queries.c
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_queries.c 2012-10-20 08:52:54 UTC (rev 51437)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_queries.c 2012-10-20 09:48:41 UTC (rev 51438)
@@ -1064,6 +1064,28 @@
}
/**
+ * 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.
*
Modified: trunk/blender/source/blender/bmesh/intern/bmesh_queries.h
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_queries.h 2012-10-20 08:52:54 UTC (rev 51437)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_queries.h 2012-10-20 09:48:41 UTC (rev 51438)
@@ -74,6 +74,7 @@
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);
More information about the Bf-blender-cvs
mailing list