[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [51989] trunk/blender/source/blender/bmesh /intern/bmesh_decimate_collapse.c: decimate - degenerate edges are now added back into the heap ( with an dummy cost), so when surrounding geometry may be modified and the previously degenerate edge re-evaluated after .

Campbell Barton ideasman42 at gmail.com
Wed Nov 7 23:28:54 CET 2012


Revision: 51989
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=51989
Author:   campbellbarton
Date:     2012-11-07 22:28:50 +0000 (Wed, 07 Nov 2012)
Log Message:
-----------
decimate - degenerate edges are now added back into the heap (with an dummy cost), so when surrounding geometry may be modified and the previously degenerate edge re-evaluated after.
The C++ LOD decimator did this too.

Modified Paths:
--------------
    trunk/blender/source/blender/bmesh/intern/bmesh_decimate_collapse.c

Modified: trunk/blender/source/blender/bmesh/intern/bmesh_decimate_collapse.c
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_decimate_collapse.c	2012-11-07 22:12:19 UTC (rev 51988)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_decimate_collapse.c	2012-11-07 22:28:50 UTC (rev 51989)
@@ -52,6 +52,7 @@
 
 #define BOUNDARY_PRESERVE_WEIGHT 100.0f
 #define OPTIMIZE_EPS 0.01f  /* FLT_EPSILON is too small, see [#33106] */
+#define COST_INVALID FLT_MAX
 
 typedef enum CD_UseFlag {
 	CD_DO_VERT = (1 << 0),
@@ -200,6 +201,16 @@
 	eheap_table[BM_elem_index_get(e)] = BLI_heap_insert(eheap, cost, e);
 }
 
+
+/* use this for degenerate cases - add back to the heap with an invalid cost,
+ * this way it may be calculated again if surrounding geometry changes */
+static void bm_decim_invalid_edge_cost_single(BMEdge *e,
+                                              Heap *eheap, HeapNode **eheap_table)
+{
+	BLI_assert(eheap_table[BM_elem_index_get(e)] == NULL);
+	eheap_table[BM_elem_index_get(e)] = BLI_heap_insert(eheap, COST_INVALID, e);
+}
+
 static void bm_decim_build_edge_cost(BMesh *bm,
                                      const Quadric *vquadrics, const float *vweights,
                                      Heap *eheap, HeapNode **eheap_table)
@@ -525,7 +536,7 @@
 #endif
 }
 
-static int bm_edge_collapse_is_degenerate(BMEdge *e_first)
+static int bm_edge_collapse_is_degenerate_topology(BMEdge *e_first)
 {
 	/* simply check that there is no overlap between faces and edges of each vert,
 	 * (excluding the 2 faces attached to 'e' and 'e' its self) */
@@ -629,11 +640,6 @@
 {
 	BMVert *v_other;
 
-	/* disallow collapsing which results in degenerate cases */
-	if (bm_edge_collapse_is_degenerate(e_clear)) {
-		return FALSE;
-	}
-
 	v_other = BM_edge_other_vert(e_clear, v_clear);
 	BLI_assert(v_other != NULL);
 
@@ -781,12 +787,17 @@
 	copy_v3_v3(v_clear_no, e->v2->no);
 #endif
 
+	/* disallow collapsing which results in degenerate cases */
+	if (UNLIKELY(bm_edge_collapse_is_degenerate_topology(e))) {
+		bm_decim_invalid_edge_cost_single(e, eheap, eheap_table);  /* add back with a high cost */
+		return;
+	}
+
 	bm_decim_calc_target_co(e, optimize_co, vquadrics);
 
 	/* use for customdata merging */
 	if (LIKELY(compare_v3v3(e->v1->co, e->v2->co, FLT_EPSILON) == FALSE)) {
 		customdata_fac = line_point_factor_v3(optimize_co, e->v1->co, e->v2->co);
-
 #if 0
 		/* simple test for stupid collapse */
 		if (customdata_fac < 0.0 - FLT_EPSILON || customdata_fac > 1.0f + FLT_EPSILON) {
@@ -870,6 +881,10 @@
 		/* end optional update */
 #endif
 	}
+	else {
+		/* add back with a high cost */
+		bm_decim_invalid_edge_cost_single(e, eheap, eheap_table);
+	}
 }
 
 
@@ -925,7 +940,10 @@
 #endif
 
 	/* iterative edge collapse and maintain the eheap */
-	while ((bm->totface > face_tot_target) && (BLI_heap_is_empty(eheap) == FALSE)) {
+	while ((bm->totface > face_tot_target) &&
+	       (BLI_heap_is_empty(eheap) == FALSE) &&
+	       (BLI_heap_node_value(BLI_heap_top(eheap)) != COST_INVALID))
+	{
 		// const float value = BLI_heap_node_value(BLI_heap_top(eheap));
 		BMEdge *e = BLI_heap_popmin(eheap);
 		BLI_assert(BM_elem_index_get(e) < tot_edge_orig);  /* handy to detect corruptions elsewhere */




More information about the Bf-blender-cvs mailing list