[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