[Bf-blender-cvs] [455ca1b] master: BMesh decimate, improve behavior with weights

Campbell Barton noreply at git.blender.org
Thu Jun 4 18:58:45 CEST 2015


Commit: 455ca1b28f140482f2834c9bba0adc730aff6637
Author: Campbell Barton
Date:   Thu Jun 4 19:49:59 2015 +1000
Branches: master
https://developer.blender.org/rB455ca1b28f140482f2834c9bba0adc730aff6637

BMesh decimate, improve behavior with weights

Add slider to adjust the influence of weights relative to geometry distortion.
This allows subtle influences to be applied - without drastic changes in behavior.

===================================================================

M	release/scripts/startup/bl_ui/properties_data_modifier.py
M	source/blender/blenloader/intern/versioning_270.c
M	source/blender/bmesh/tools/bmesh_decimate.h
M	source/blender/bmesh/tools/bmesh_decimate_collapse.c
M	source/blender/makesdna/DNA_modifier_types.h
M	source/blender/makesrna/intern/rna_modifier.c
M	source/blender/modifiers/intern/MOD_decimate.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index d6d4e03..381c9ad 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -262,24 +262,37 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
         row.prop(md, "decimate_type", expand=True)
 
         if decimate_type == 'COLLAPSE':
+            has_vgroup = bool(md.vertex_group)
             layout.prop(md, "ratio")
 
             split = layout.split()
-            row = split.row(align=True)
+
+            col = split.column()
+            row = col.row(align=True)
             row.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
             row.prop(md, "invert_vertex_group", text="", icon='ARROW_LEFTRIGHT')
 
-            split.prop(md, "use_collapse_triangulate")
+            layout_info = col
+
+            col = split.column()
+            row = col.row()
+            row.active = has_vgroup
+            row.prop(md, "vertex_group_factor")
+
+            col.prop(md, "use_collapse_triangulate")
+
         elif decimate_type == 'UNSUBDIV':
             layout.prop(md, "iterations")
+            layout_info = layout
         else:  # decimate_type == 'DISSOLVE':
             layout.prop(md, "angle_limit")
             layout.prop(md, "use_dissolve_boundaries")
             layout.label("Delimit:")
             row = layout.row()
             row.prop(md, "delimit")
+            layout_info = layout
 
-        layout.label(text=iface_("Face Count: %d") % md.face_count, translate=False)
+        layout_info.label(text=iface_("Faces: %d") % md.face_count, translate=False)
 
     def DISPLACE(self, layout, ob, md):
         has_texture = (md.texture is not None)
diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c
index df98544..37c2556 100644
--- a/source/blender/blenloader/intern/versioning_270.c
+++ b/source/blender/blenloader/intern/versioning_270.c
@@ -830,5 +830,19 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
 				scene->r.simplify_particles_render = scene->r.simplify_particles;
 			}
 		}
+
+		if (!DNA_struct_elem_find(fd->filesdna, "DecimateModifierData", "float", "defgrp_factor")) {
+			Object *ob;
+
+			for (ob = main->object.first; ob; ob = ob->id.next) {
+				ModifierData *md;
+				for (md = ob->modifiers.first; md; md = md->next) {
+					if (md->type == eModifierType_Decimate) {
+						DecimateModifierData *dmd = (DecimateModifierData *)md;
+						dmd->defgrp_factor = 1.0f;
+					}
+				}
+			}
+		}
 	}
 }
diff --git a/source/blender/bmesh/tools/bmesh_decimate.h b/source/blender/bmesh/tools/bmesh_decimate.h
index 17b55be..b0a85b0 100644
--- a/source/blender/bmesh/tools/bmesh_decimate.h
+++ b/source/blender/bmesh/tools/bmesh_decimate.h
@@ -42,8 +42,4 @@ void BM_mesh_decimate_dissolve(
         BMesh *bm, const float angle_limit, const bool do_dissolve_boundaries,
         const BMO_Delimit delimit);
 
-/* 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__ */
diff --git a/source/blender/bmesh/tools/bmesh_decimate_collapse.c b/source/blender/bmesh/tools/bmesh_decimate_collapse.c
index 3bcf9a3..6b6219c 100644
--- a/source/blender/bmesh/tools/bmesh_decimate_collapse.c
+++ b/source/blender/bmesh/tools/bmesh_decimate_collapse.c
@@ -212,10 +212,15 @@ static bool bm_edge_collapse_is_degenerate_flip(BMEdge *e, const float optimize_
  *
  * This avoids cases where a flat (or near flat) areas get very un-even geometry.
  */
-static float bm_decim_build_edge_cost_single__topology(BMEdge *e)
+static float bm_decim_build_edge_cost_single_squared__topology(BMEdge *e)
 {
 	return fabsf(dot_v3v3(e->v1->no, e->v2->no)) / min_ff(-len_squared_v3v3(e->v1->co, e->v2->co), -FLT_EPSILON);
 }
+static float bm_decim_build_edge_cost_single__topology(BMEdge *e)
+{
+	return fabsf(dot_v3v3(e->v1->no, e->v2->no)) / min_ff(-len_v3v3(e->v1->co, e->v2->co), -FLT_EPSILON);
+}
+
 #endif  /* USE_TOPOLOGY_FALLBACK */
 
 static void bm_decim_build_edge_cost_single(
@@ -253,15 +258,6 @@ static void bm_decim_build_edge_cost_single(
 	else {
 		goto clear;
 	}
-
-	if (vweights) {
-		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 */
-			goto clear;
-		}
-	}
 	/* end sanity check */
 
 
@@ -270,21 +266,21 @@ static void bm_decim_build_edge_cost_single(
 	q1 = &vquadrics[BM_elem_index_get(e->v1)];
 	q2 = &vquadrics[BM_elem_index_get(e->v2)];
 
-	if (vweights == NULL) {
-		cost = (BLI_quadric_evaluate(q1, optimize_co) +
-		        BLI_quadric_evaluate(q2, optimize_co));
-	}
-	else {
-		/* 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)]));
-	}
+	cost = (BLI_quadric_evaluate(q1, optimize_co) +
+	        BLI_quadric_evaluate(q2, optimize_co));
+
+
 	// print("COST %.12f\n");
 
 	/* note, 'cost' shouldn't be negative but happens sometimes with small values.
 	 * this can cause faces that make up a flat surface to over-collapse, see [#37121] */
 	cost = fabsf(cost);
 
+	/* edge weights can be 2 max, ((2 * 2) ^ 2) == 16x max,
+	 * a high weight means being inserted into the heap ahead of 16x better edges.
+	 * but thats fine since its the purpose of weighting. */
+#define VWEIGHT_SCALE 2
+
 #ifdef USE_TOPOLOGY_FALLBACK
 	if (UNLIKELY(cost < TOPOLOGY_FALLBACK_EPS)) {
 		/* subtract existing cost to further differentiate edges from one another
@@ -292,10 +288,35 @@ static void bm_decim_build_edge_cost_single(
 		 * keep topology cost below 0.0 so their values don't interfere with quadric cost,
 		 * (and they get handled first).
 		 * */
-		cost = bm_decim_build_edge_cost_single__topology(e) - cost;
-		BLI_assert(cost <= 0.0f);
+		if (vweights == NULL) {
+			cost = bm_decim_build_edge_cost_single_squared__topology(e) - cost;
+		}
+		else {
+			/* with weights we need to use the real length so we can scale them properly */
+			float e_weight = (vweights[BM_elem_index_get(e->v1)] +
+			                  vweights[BM_elem_index_get(e->v2)]);
+			cost = bm_decim_build_edge_cost_single__topology(e) - cost;
+			/* note, this is rather arbitrary max weight is 2 here,
+			 * allow for skipping edges 4x the length, based on weights */
+			if (e_weight) {
+				e_weight *= VWEIGHT_SCALE;
+				cost *= 1.0f + SQUARE(e_weight);
+			}
+
+			BLI_assert(cost <= 0.0f);
+		}
 	}
+	else
 #endif
+	if (vweights) {
+		float e_weight = 2.0f - (vweights[BM_elem_index_get(e->v1)] +
+		                         vweights[BM_elem_index_get(e->v2)]);
+		if (e_weight) {
+			e_weight *= VWEIGHT_SCALE;
+			cost += (BM_edge_calc_length(e) * SQUARE(e_weight));
+		}
+	}
+#undef VWEIGHT_SCALE
 
 	eheap_table[BM_elem_index_get(e)] = BLI_heap_insert(eheap, cost, e);
 	return;
@@ -950,7 +971,9 @@ static void bm_decim_edge_collapse(
 		int i;
 
 		if (vweights) {
-			vweights[v_other_index] += vweights[v_clear_index];
+			float v_other_weight = interpf(vweights[v_other_index], vweights[v_clear_index], customdata_fac);
+			CLAMP(v_other_weight, 0.0f, 1.0f);
+			vweights[v_other_index] = v_other_weight;
 		}
 
 		e = NULL;  /* paranoid safety check */
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index f3c61f0..1fc66b9 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -431,10 +431,11 @@ typedef struct DecimateModifierData {
 	float angle;    /* (mode == MOD_DECIM_MODE_DISSOLVE) */
 
 	char defgrp_name[64];  /* MAX_VGROUP_NAME */
+	float defgrp_factor;
 	short flag, mode;
 
 	/* runtime only */
-	int face_count, pad2;
+	int face_count;
 } DecimateModifierData;
 
 enum {
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 1c719b1..6f1f6f9 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -1506,6 +1506,13 @@ static void rna_def_modifier_decimate(BlenderRNA *brna)
 	RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_DECIM_FLAG_TRIANGULATE);
 	RNA_def_property_ui_text(prop, "Triangulate", "Keep triangulated faces resulting from decimation (collapse only)");
 	RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+	prop = RNA_def_property(srna, "vertex_group_factor", PROP_FLOAT, PROP_FACTOR);
+	RNA_def_property_float_sdna(prop, NULL, "defgrp_factor");
+	RNA_def_property_range(prop, 0, 1.0f);
+	RNA_def_property_ui_range(prop, 0, 1, 1, 4);
+	RNA_def_property_ui_text(prop, "Factor", "Vertex group strength");
+	RNA_def_property_update(prop, 0, "rna_Modifier_update");
 	/* end collapse-only option */
 
 	/* (mode == MOD_DECIM_MODE_DISSOLVE) */
diff --git a/source/blender/modifiers/intern/MOD_decimate.c b/source/blender/modifiers/intern/MOD_decimate.c
index 7c13774..878015c 100644
--- a/source/blender/modifiers/intern/MOD_decimate.c
+++ b/source/blender/modifiers/intern/MOD_decimate.c
@@ -61,6 +61,7 @@ static void initData(ModifierData *md)
 
 	dmd->percent = 1.0;
 	dmd->angle   = DEG2RADF(5.0f);
+	dmd->defgrp_factor = 1.0;
 }
 
 static void copyData(ModifierData *md, ModifierData *target)
@@ -78,7 +79,9 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
 	CustomDataMask dataMask = 0;
 
 	/* ask for vertexgroups if we need them */
-	if (dmd->defgrp_name[0]) dataMask |= CD_MASK_MDEFORMVERT;
+	if (dmd->defgrp_name[0] && (dmd->defgrp_factor > 0.0f)) {
+		dataMask |= CD_MASK_MDEFORMVERT;
+	}
 
 	return dataMask;
 }
@@ -130,7 +133,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
 	}
 
 	if (dmd->mode == MOD_DECIM_MODE_COLLAPSE) {
-		if (dmd->defgrp_name[0]) {
+		if (dmd->defgrp_name[0] && (dmd->defgrp_factor > 0.0f)) 

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list