fix [#33320] Decimate modifer in collapse is inconsistent when limiting to a vertex...
authorCampbell Barton <ideasman42@gmail.com>
Wed, 28 Nov 2012 02:49:06 +0000 (02:49 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Wed, 28 Nov 2012 02:49:06 +0000 (02:49 +0000)
source/blender/bmesh/tools/bmesh_decimate.h
source/blender/bmesh/tools/bmesh_decimate_collapse.c
source/blender/modifiers/intern/MOD_decimate.c

index 4d382d65659eeec754816ec7ed0009f2b2da38f4..4a557c20ae3c1f7b9db7ad7c4c4ce202130540f6 100644 (file)
@@ -37,5 +37,8 @@ void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const int
                                   BMEdge **einput_arr, const int einput_len);
 void BM_mesh_decimate_dissolve(BMesh *bm, const float angle_limit, const int do_dissolve_boundaries);
 
+/* these weights are accumulated so too high values may reach 'inf' too quickly */
+#define BM_MESH_DECIM_WEIGHT_MAX 100000.0f
+#define BM_MESH_DECIM_WEIGHT_EPS (1.0f / BM_MESH_DECIM_WEIGHT_MAX)
 
 #endif /* __BMESH_DECIMATE_H__ */
index eeb1774b83b2a5113ab9d87f7cc0fb0f79fab19a..02283aa6e28f359dfe32f77436e25aefe3e6d67f 100644 (file)
@@ -223,8 +223,8 @@ static void bm_decim_build_edge_cost_single(BMEdge *e,
        }
 
        if (vweights) {
-               if ((vweights[BM_elem_index_get(e->v1)] < FLT_EPSILON) &&
-                   (vweights[BM_elem_index_get(e->v2)] < FLT_EPSILON))
+               if ((vweights[BM_elem_index_get(e->v1)] >= BM_MESH_DECIM_WEIGHT_MAX) &&
+                   (vweights[BM_elem_index_get(e->v2)] >= BM_MESH_DECIM_WEIGHT_MAX))
                {
                        /* skip collapsing this edge */
                        eheap_table[BM_elem_index_get(e)] = NULL;
@@ -244,8 +244,9 @@ static void bm_decim_build_edge_cost_single(BMEdge *e,
                        BLI_quadric_evaluate(q2, optimize_co));
        }
        else {
-               cost = ((BLI_quadric_evaluate(q1, optimize_co) * vweights[BM_elem_index_get(e->v1)]) +
-                       (BLI_quadric_evaluate(q2, optimize_co) * vweights[BM_elem_index_get(e->v2)]));
+               /* add 1.0 so planar edges are still weighted against */
+               cost = (((BLI_quadric_evaluate(q1, optimize_co) + 1.0f) * vweights[BM_elem_index_get(e->v1)]) +
+                       ((BLI_quadric_evaluate(q2, optimize_co) + 1.0f) * vweights[BM_elem_index_get(e->v2)]));
        }
        // print("COST %.12f\n");
 
@@ -877,9 +878,7 @@ static void bm_decim_edge_collapse(BMesh *bm, BMEdge *e,
                int i;
 
                if (vweights) {
-                       const int fac = CLAMPIS(customdata_fac, 0.0f, 1.0f);
-                       vweights[BM_elem_index_get(v_other)] = (vweights[v_clear_index]              * (1.0f - fac)) +
-                                                              (vweights[BM_elem_index_get(v_other)] * fac);
+                       vweights[BM_elem_index_get(v_other)] = vweights[v_clear_index] + vweights[BM_elem_index_get(v_other)];
                }
 
                e = NULL;  /* paranoid safety check */
index 3f8eaa438c9e0d318ba435800f8c402c439f1170..28cdfa810fa0524c3e17569d7ea96f213725a568 100644 (file)
@@ -145,12 +145,14 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
 
                                if (dmd->flag & MOD_DECIM_FLAG_INVERT_VGROUP) {
                                        for (i = 0; i < vert_tot; i++) {
-                                               vweights[i] = 1.0f - defvert_find_weight(&dvert[i], defgrp_index);
+                                               const float f = 1.0f - defvert_find_weight(&dvert[i], defgrp_index);
+                                               vweights[i] = f > BM_MESH_DECIM_WEIGHT_EPS ? (1.0f / f) : BM_MESH_DECIM_WEIGHT_MAX;
                                        }
                                }
                                else {
                                        for (i = 0; i < vert_tot; i++) {
-                                               vweights[i] = defvert_find_weight(&dvert[i], defgrp_index);
+                                               const float f = defvert_find_weight(&dvert[i], defgrp_index);
+                                               vweights[i] = f > BM_MESH_DECIM_WEIGHT_EPS ? (1.0f / f) : BM_MESH_DECIM_WEIGHT_MAX;
                                        }
                                }
                        }