[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