[Bf-blender-cvs] [f11ab3b] temp-modifier-deltamush-experimental: Add smoothing type as an option

Campbell Barton noreply at git.blender.org
Mon Mar 30 16:15:37 CEST 2015


Commit: f11ab3b16823cafdbd2ac1729e70dddf7d5c6255
Author: Campbell Barton
Date:   Tue Mar 31 01:12:16 2015 +1100
Branches: temp-modifier-deltamush-experimental
https://developer.blender.org/rBf11ab3b16823cafdbd2ac1729e70dddf7d5c6255

Add smoothing type as an option

Currently have: Simple, Length-Weighted

Since in some cases simple is more radii stable, its faster too.

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

M	release/scripts/startup/bl_ui/properties_data_modifier.py
M	source/blender/makesdna/DNA_modifier_types.h
M	source/blender/makesrna/intern/rna_modifier.c
M	source/blender/modifiers/intern/MOD_deltamush.c

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

diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index 9c02c5b..4ef54d7 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -1392,10 +1392,13 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
         layout.prop(md, "iterations")
         layout.prop(md, "lambda_factor", text="Factor")
 
-        layout.label(text="Smoothing Details")
         row = layout.row()
-        row.prop(md, "use_only_smooth");
-        row.prop(md, "use_pin_boundary");
+        row.label(text="Smoothing Details")
+        row.prop(md, "smooth_type", text="")
+
+        row = layout.row()
+        row.prop(md, "use_only_smooth")
+        row.prop(md, "use_pin_boundary")
 
         layout.label(text="Vertex Group:")
         sub = layout.row(align=True)
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index cb22f3c..1abe691 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -1298,15 +1298,21 @@ typedef struct DeltaMushModifierData {
 
 	float lambda;
 	char defgrp_name[64];  /* MAX_VGROUP_NAME */
-	short repeat, flag;
 
-	unsigned int positions_num, pad;
+	unsigned int positions_num;
+	short repeat, flag;
+	char smooth_type, pad[3];
 
 	/* runtime-only cache (delta's between),
 	 * delta's between the original positions and the smoothed positions */
 	float (*positions_delta_cache)[3];
 } DeltaMushModifierData;
 
+enum {
+	MOD_DELTAMUSH_SMOOTH_SIMPLE         = 0,
+	MOD_DELTAMUSH_SMOOTH_EDGE_WEIGHT    = 1,
+};
+
 /* Delta Mush modifier flags */
 enum {
 	MOD_DELTAMUSH_INVERT_VGROUP         = (1 << 0),
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 4570a32..0245697 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -2131,6 +2131,14 @@ static void rna_def_modifier_deltamush(BlenderRNA *brna)
 	StructRNA *srna;
 	PropertyRNA *prop;
 
+	static EnumPropertyItem modifier_smooth_type_items[] = {
+		{MOD_DELTAMUSH_SMOOTH_SIMPLE, "SIMPLE", 0, "Simple",
+		 "Use the average of adjacent vertices"},
+		{MOD_DELTAMUSH_SMOOTH_EDGE_WEIGHT, "LENGTH_WEIGHTED", 0, "Length Weight",
+		 "Use the average of adjacent vertices weighted by the length"},
+		{0, NULL, 0, NULL, NULL}
+	};
+
 	srna = RNA_def_struct(brna, "DeltaMushModifier", "Modifier");
 	RNA_def_struct_ui_text(srna, "Delta Mush Modifier", "Deformation Relaxation modifier");
 	RNA_def_struct_sdna(srna, "DeltaMushModifierData");
@@ -2149,6 +2157,12 @@ static void rna_def_modifier_deltamush(BlenderRNA *brna)
 	RNA_def_property_ui_text(prop, "Repeat", "");
 	RNA_def_property_update(prop, 0, "rna_DeltaMushModifier_update");
 
+	prop = RNA_def_property(srna, "smooth_type", PROP_ENUM, PROP_NONE);
+	RNA_def_property_enum_sdna(prop, NULL, "smooth_type");
+	RNA_def_property_enum_items(prop, modifier_smooth_type_items);
+	RNA_def_property_ui_text(prop, "Smooth Type", "");
+	RNA_def_property_update(prop, 0, "rna_DeltaMushModifier_update");
+
 	prop = RNA_def_property(srna, "invert_vertex_group", PROP_BOOLEAN, PROP_NONE);
 	RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_DELTAMUSH_INVERT_VGROUP);
 	RNA_def_property_ui_text(prop, "Invert", "Invert vertex group influence");
diff --git a/source/blender/modifiers/intern/MOD_deltamush.c b/source/blender/modifiers/intern/MOD_deltamush.c
index c511a66..b031dc6 100644
--- a/source/blender/modifiers/intern/MOD_deltamush.c
+++ b/source/blender/modifiers/intern/MOD_deltamush.c
@@ -51,24 +51,6 @@
 /* minor optimization, calculate this inline */
 #define USE_TANGENT_CALC_INLINE
 
-
-
-/* -------------------------------------------------------------------- */
-/* Smoothing Method (currently testing different methods) */
-
-/* simple median */
-#define SMOOTH_METHOD_SIMPLE 1
-/* squared edge-length median (original patch) */
-#define SMOOTH_METHOD_SQUAREDLENGTH 2
-/* use poly-loop angle weighted median */
-#define SMOOTH_METHOD_LOOPWEIGHT 3
-
-/* use one of the smoothing methods above */
-#define SMOOTH_METHOD  SMOOTH_METHOD_SQUAREDLENGTH
-/* -------------------------------------------------------------------- */
-
-
-
 static void initData(ModifierData *md)
 {
 	DeltaMushModifierData *dmmd = (DeltaMushModifierData *)md;
@@ -178,11 +160,12 @@ static void dm_get_boundaries(DerivedMesh *dm, float *smooth_weights)
 	MEM_freeN(boundaries);
 }
 
-/**
- * \note This is called many times.
- * take care when editing this function since minor changes may impact speed.
+
+/* -------------------------------------------------------------------- */
+/* Edge-Length Weighted Smoothing
  */
-static void smooth_iter(
+
+static void smooth_iter__simple(
         DeltaMushModifierData *dmmd, DerivedMesh *dm,
         float(*vertexCos)[3], unsigned int numVerts,
         const float *smooth_weights,
@@ -191,21 +174,14 @@ static void smooth_iter(
 	const float lambda = dmmd->lambda;
 	unsigned int i;
 
-	struct SmoothingData {
-		float delta[3];
-#if (SMOOTH_METHOD == SMOOTH_METHOD_SQUAREDLENGTH) || (SMOOTH_METHOD == SMOOTH_METHOD_LOOPWEIGHT)
-		float edge_lengths;
-#endif
-	} *smooth_data = MEM_callocN((size_t)numVerts * sizeof(*smooth_data), __func__);
-
-
-#if (SMOOTH_METHOD == SMOOTH_METHOD_SIMPLE)
-
 	const unsigned int numEdges = (unsigned int)dm->getNumEdges(dm);
 	const MEdge *edges = dm->getEdgeArray(dm);
-
 	float *vertex_edge_count_div;
 
+	struct SmoothingData {
+		float delta[3];
+	} *smooth_data = MEM_callocN((size_t)numVerts * sizeof(*smooth_data), __func__);
+
 	vertex_edge_count_div = MEM_callocN((size_t)numVerts * sizeof(float), __func__);
 
 	/* calculate as floats to avoid int->float conversion in #smooth_iter */
@@ -264,15 +240,34 @@ static void smooth_iter(
 	}
 
 	MEM_freeN(vertex_edge_count_div);
+	MEM_freeN(smooth_data);
+}
 
-#elif (SMOOTH_METHOD == SMOOTH_METHOD_SQUAREDLENGTH)
 
-	const float eps = FLT_EPSILON * 10.0f;
+/* -------------------------------------------------------------------- */
+/* Simple Weighting
+ *
+ * (average of surrounding verts)
+ */
 
+static void smooth_iter__length_weight(
+        DeltaMushModifierData *dmmd, DerivedMesh *dm,
+        float(*vertexCos)[3], unsigned int numVerts,
+        const float *smooth_weights,
+        unsigned int iterations)
+{
+	const float eps = FLT_EPSILON * 10.0f;
 	const unsigned int numEdges = (unsigned int)dm->getNumEdges(dm);
+	const float lambda = dmmd->lambda;
 	const MEdge *edges = dm->getEdgeArray(dm);
-
 	float *vertex_edge_count;
+	unsigned int i;
+
+	struct SmoothingData {
+		float delta[3];
+		float edge_lengths;
+	} *smooth_data = MEM_callocN((size_t)numVerts * sizeof(*smooth_data), __func__);
+
 
 	/* calculate as floats to avoid int->float conversion in #smooth_iter */
 	vertex_edge_count = MEM_callocN((size_t)numVerts * sizeof(float), __func__);
@@ -345,79 +340,28 @@ static void smooth_iter(
 	}
 
 	MEM_freeN(vertex_edge_count);
+	MEM_freeN(smooth_data);
+}
 
 
-#elif (SMOOTH_METHOD == SMOOTH_METHOD_LOOPWEIGHT)
-
-	const float eps = FLT_EPSILON * 10.0f;
-
-	/* -------------------------------------------------------------------- */
-	/* Main Loop */
-
-	while (iterations--) {
-
-		{
-			const MPoly *mpoly = dm->getPolyArray(dm);
-			const MLoop *mloop = dm->getLoopArray(dm);
-			unsigned int mpoly_num, j;
-			mpoly_num = (unsigned int)dm->getNumPolys(dm);
-			for (i = 0; i < mpoly_num; i++) {
-				const MPoly *p = &mpoly[i];
-				const MLoop *ml = &mloop[p->loopstart];
-				const unsigned int totloop = (unsigned int)p->totloop;
-				for (j = 0; j < totloop; j++) {
-					/* TODO, optimize (just testing method right now) */
-					const unsigned int v_prev = ml[((totloop + j) - 1) % totloop].v;
-					const unsigned int v_curr = ml[((totloop + j)    ) % totloop].v;
-					const unsigned int v_next = ml[((totloop + j) + 1) % totloop].v;
-					const float *co_prev = vertexCos[v_prev];
-					const float *co_curr = vertexCos[v_curr];
-					const float *co_next = vertexCos[v_next];
-					float angle = angle_v3v3v3(co_prev, co_curr, co_next);
-					struct SmoothingData *sd = &smooth_data[v_curr];
-					float co_mid[3];
-
-					mid_v3_v3v3(co_mid, co_prev, co_next);
-					madd_v3_v3fl(sd->delta, co_mid, angle);
-					sd->edge_lengths += angle;
-				}
-			}
-		}
-
-		if (smooth_weights == NULL) {
-			/* fast-path */
-			for (i = 0; i < numVerts; i++) {
-				struct SmoothingData *sd = &smooth_data[i];
-				if (sd->edge_lengths > eps) {
-					mul_v3_fl(sd->delta, 1.0f / sd->edge_lengths);
-					interp_v3_v3v3(vertexCos[i], vertexCos[i], sd->delta, lambda);
-				}
-				/* zero for the next iteration (saves memset on entire array) */
-				memset(sd, 0, sizeof(*sd));
-			}
-		}
-		else {
-
-			for (i = 0; i < numVerts; i++) {
-				SmoothingData *sd = &smooth_data[i];
-
-				if (sd->edge_lengths > eps) {
-					float lambda_w = smooth_weights[i];
-					mul_v3_fl(sd->delta, 1.0f / sd->edge_lengths);
-					interp_v3_v3v3(vertexCos[i], vertexCos[i], sd->delta, lambda_w);
-				}
-
-				memset(sd, 0, sizeof(*sd));
-			}
-		}
+static void smooth_iter(
+        DeltaMushModifierData *dmmd, DerivedMesh *dm,
+        float(*vertexCos)[3], unsigned int numVerts,
+        const float *smooth_weights,
+        unsigned int iterations)
+{
+	switch (dmmd->smooth_type) {
+		case MOD_DELTAMUSH_SMOOTH_EDGE_WEIGHT:
+			smooth_iter__length_weight(dmmd, dm, vertexCos, numVerts, smooth_weights, iterations);
+			break;
+
+		/* case MOD_DELTAMUSH_SMOOTH_SIMPLE: */
+		default:
+			smooth_iter__simple(dmmd, dm, vertexCos, numVerts, smooth_weights, iterations);
+			break;
 	}
-
-#endif
-
-	MEM_freeN(smooth_data);
 }
 
-
 static void smooth_verts(
         DeltaMushModifierData *dmmd, DerivedMesh *dm,
         MDeformVert *dvert, const int defgrp_index,
@@ -444,8 +388,6 @@ static void smooth_verts(
 		}
 	}
 
-
-	/* no need to memset each time, 'smooth_iter' cleans up after its self */
 	smooth_iter(dmmd, dm, vertexCos, numVerts, smooth_weights, (unsigned int)dmmd->repeat);
 
 	if (smooth_weights) {




More information about the Bf-blender-cvs mailing list