[Bf-blender-cvs] [8ec8cfe] temp-modifier-deltamush-experimental: Add loop-angle-weighted smoothing

Campbell Barton noreply at git.blender.org
Sun Mar 29 17:37:24 CEST 2015


Commit: 8ec8cfe8b2fc7db1625b26da1782ba4263348970
Author: Campbell Barton
Date:   Mon Mar 30 02:36:49 2015 +1100
Branches: temp-modifier-deltamush-experimental
https://developer.blender.org/rB8ec8cfe8b2fc7db1625b26da1782ba4263348970

Add loop-angle-weighted smoothing

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

M	source/blender/modifiers/intern/MOD_deltamush.c

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

diff --git a/source/blender/modifiers/intern/MOD_deltamush.c b/source/blender/modifiers/intern/MOD_deltamush.c
index 3486feb..a65f765 100644
--- a/source/blender/modifiers/intern/MOD_deltamush.c
+++ b/source/blender/modifiers/intern/MOD_deltamush.c
@@ -51,10 +51,22 @@
 /* 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)
@@ -184,7 +196,7 @@ static void find_boundaries(DerivedMesh *dm, short *adjacent_counts)
 
 typedef struct SmoothingData {
 	float delta[3];
-#ifdef SMOOTH_METHOD_SQUAREDLENGTH
+#if (SMOOTH_METHOD == SMOOTH_METHOD_SQUAREDLENGTH) || (SMOOTH_METHOD == SMOOTH_METHOD_LOOPWEIGHT)
 	float edge_lengths;
 #endif
 } SmoothingData;
@@ -199,30 +211,30 @@ static void smooth_iter(
         const short *boundaries,
         unsigned int iterations)
 {
-	const float eps = FLT_EPSILON * 10.0f;
-	const unsigned int numEdges = (unsigned int)dm->getNumEdges(dm);
-	const MEdge *edges = dm->getEdgeArray(dm);
 	const float lambda = dmmd->lambda;
 	unsigned int i;
 
-	SmoothingData *smooth_data;
-	float *vertex_edge_count;
+	SmoothingData *smooth_data  = MEM_callocN((size_t)numVerts * sizeof(SmoothingData), "delta mush smoothing data");
+
 
 #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;
+
+	vertex_edge_count_div = MEM_callocN((size_t)numVerts * sizeof(float), __func__);
+
 	/* calculate as floats to avoid int->float conversion in #smooth_iter */
-	vertex_edge_count = MEM_callocN((size_t)numVerts * sizeof(float), __func__);
 	for (i = 0; i < numEdges; i++) {
-		vertex_edge_count[edges[i].v1] += 1.0f;
-		vertex_edge_count[edges[i].v2] += 1.0f;
+		vertex_edge_count_div[edges[i].v1] += 1.0f;
+		vertex_edge_count_div[edges[i].v2] += 1.0f;
 	}
 	for (i = 0; i < numVerts; i++) {
-		vertex_edge_count[i] = vertex_edge_count[i] ? (1.0f / vertex_edge_count[i]) : 1.0f;
+		vertex_edge_count_div[i] = vertex_edge_count_div[i] ? (1.0f / vertex_edge_count_div[i]) : 1.0f;
 	}
 
-	smooth_data = MEM_callocN((size_t)numVerts * sizeof(SmoothingData), "delta mush smoothing data");
-
-
 	/* -------------------------------------------------------------------- */
 	/* Main Loop */
 
@@ -250,7 +262,7 @@ static void smooth_iter(
 			/* fast-path */
 			for (i = 0; i < numVerts; i++) {
 				SmoothingData *sd = &smooth_data[i];
-				mul_v3_v3fl(vertexCos[i], sd->delta, vertex_edge_count[i]);
+				mul_v3_v3fl(vertexCos[i], sd->delta, vertex_edge_count_div[i]);
 				/* zero for the next iteration (saves memset on entire array) */
 				memset(sd, 0, sizeof(*sd));
 			}
@@ -270,7 +282,7 @@ static void smooth_iter(
 					lambda_alt *= (boundaries[i] != 0 ? 0.0f : 1.0f);
 				}
 
-				mul_v3_fl(sd->delta, vertex_edge_count[i]);
+				mul_v3_fl(sd->delta, vertex_edge_count_div[i]);
 				interp_v3_v3v3(vertexCos[i], vertexCos[i], sd->delta, lambda_alt);
 
 				memset(sd, 0, sizeof(*sd));
@@ -278,8 +290,18 @@ static void smooth_iter(
 		}
 	}
 
+	MEM_freeN(vertex_edge_count_div);
+
 #elif (SMOOTH_METHOD == SMOOTH_METHOD_SQUAREDLENGTH)
 
+	const float eps = FLT_EPSILON * 10.0f;
+
+	const unsigned int numEdges = (unsigned int)dm->getNumEdges(dm);
+	const MEdge *edges = dm->getEdgeArray(dm);
+
+	float *vertex_edge_count;
+
+
 	/* calculate as floats to avoid int->float conversion in #smooth_iter */
 	vertex_edge_count = MEM_callocN((size_t)numVerts * sizeof(float), __func__);
 	for (i = 0; i < numEdges; i++) {
@@ -287,8 +309,6 @@ static void smooth_iter(
 		vertex_edge_count[edges[i].v2] += 1.0f;
 	}
 
-	smooth_data = MEM_callocN((size_t)numVerts * sizeof(SmoothingData), "delta mush smoothing data");
-
 
 	/* -------------------------------------------------------------------- */
 	/* Main Loop */
@@ -351,10 +371,86 @@ static void smooth_iter(
 		}
 	}
 
+	MEM_freeN(vertex_edge_count);
+
+
+#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);
+					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 ((dmmd->smooth_weights == NULL) && (boundaries == NULL)) {
+			/* fast-path */
+			for (i = 0; i < numVerts; i++) {
+				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_alt = 1.0;
+
+					if (dmmd->smooth_weights) {
+						lambda_alt *= dmmd->smooth_weights[i];
+					}
+
+					if (boundaries) {
+						lambda_alt *= (boundaries[i] != 0 ? 0.0f : 1.0f);
+					}
+
+					mul_v3_fl(sd->delta, 1.0f / sd->edge_lengths);
+					interp_v3_v3v3(vertexCos[i], vertexCos[i], sd->delta, lambda_alt);
+				}
+
+				memset(sd, 0, sizeof(*sd));
+			}
+		}
+	}
+
 #endif
 
 	MEM_freeN(smooth_data);
-	MEM_freeN(vertex_edge_count);
 }




More information about the Bf-blender-cvs mailing list