diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2019-09-25 22:44:39 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2019-09-25 22:51:13 +0300 |
commit | abc8d6b12ce9323ff204211a46a613e7f80241df (patch) | |
tree | 0a5fbd57a740d3d9de13cdbff8a5aa605fdac509 /source | |
parent | ae755c0167652ad95900d880c3e85a20e7bdc8b3 (diff) |
Cleanup: Modernize Smooth modifier code.
Simplify it a bit, hopefully make it clearer, better var names, use
proper types for arrays of vectors, etc.
No behavioral change expected (except for corner-case of vertices being
used by more than 255 edges, which were sort of 'clamped' to those 255
first edges for the smoothed position computation previously, now we use
proper integer, which fixes that bug).
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/modifiers/intern/MOD_smooth.c | 148 |
1 files changed, 59 insertions, 89 deletions
diff --git a/source/blender/modifiers/intern/MOD_smooth.c b/source/blender/modifiers/intern/MOD_smooth.c index 3542df24f49..c8bc3aaa484 100644 --- a/source/blender/modifiers/intern/MOD_smooth.c +++ b/source/blender/modifiers/intern/MOD_smooth.c @@ -54,16 +54,15 @@ static bool isDisabled(const struct Scene *UNUSED(scene), bool UNUSED(useRenderParams)) { SmoothModifierData *smd = (SmoothModifierData *)md; - short flag; - flag = smd->flag & (MOD_SMOOTH_X | MOD_SMOOTH_Y | MOD_SMOOTH_Z); + const short flag = smd->flag & (MOD_SMOOTH_X | MOD_SMOOTH_Y | MOD_SMOOTH_Z); /* disable if modifier is off for X, Y and Z or if factor is 0 */ - if ((smd->fac == 0.0f) || flag == 0) { - return 1; + if (smd->fac == 0.0f || flag == 0) { + return true; } - return 0; + return false; } static void requiredDataMask(Object *UNUSED(ob), @@ -81,134 +80,105 @@ static void requiredDataMask(Object *UNUSED(ob), static void smoothModifier_do( SmoothModifierData *smd, Object *ob, Mesh *mesh, float (*vertexCos)[3], int numVerts) { - MDeformVert *dvert = NULL; - MEdge *medges = NULL; - - int i, j, numDMEdges, defgrp_index; - uchar *uctmp; - float *ftmp, fac, facm; + if (mesh == NULL) { + return; + } - ftmp = (float *)MEM_calloc_arrayN(numVerts, 3 * sizeof(float), "smoothmodifier_f"); - if (!ftmp) { + float(*accumulated_vecs)[3] = MEM_calloc_arrayN( + (size_t)numVerts, sizeof(*accumulated_vecs), __func__); + if (!accumulated_vecs) { return; } - uctmp = (uchar *)MEM_calloc_arrayN(numVerts, sizeof(uchar), "smoothmodifier_uc"); - if (!uctmp) { - if (ftmp) { - MEM_freeN(ftmp); + + uint *num_accumulated_vecs = MEM_calloc_arrayN( + (size_t)numVerts, sizeof(*num_accumulated_vecs), __func__); + if (!num_accumulated_vecs) { + if (accumulated_vecs) { + MEM_freeN(accumulated_vecs); } return; } - fac = smd->fac; - facm = 1 - fac; + const float fac_new = smd->fac; + const float fac_orig = 1.0f - fac_new; - if (mesh != NULL) { - medges = mesh->medge; - numDMEdges = mesh->totedge; - } - else { - medges = NULL; - numDMEdges = 0; - } + MEdge *medges = mesh->medge; + const int num_edges = mesh->totedge; + MDeformVert *dvert; + int defgrp_index; MOD_get_vgroup(ob, mesh, smd->defgrp_name, &dvert, &defgrp_index); - /* NOTICE: this can be optimized a little bit by moving the - * if (dvert) out of the loop, if needed */ - for (j = 0; j < smd->repeat; j++) { - for (i = 0; i < numDMEdges; i++) { - float fvec[3]; - float *v1, *v2; - uint idx1, idx2; - - idx1 = medges[i].v1; - idx2 = medges[i].v2; + for (int j = 0; j < smd->repeat; j++) { + if (j != 0) { + memset(accumulated_vecs, 0, sizeof(*accumulated_vecs) * (size_t)numVerts); + memset(num_accumulated_vecs, 0, sizeof(*num_accumulated_vecs) * (size_t)numVerts); + } - v1 = vertexCos[idx1]; - v2 = vertexCos[idx2]; + for (int i = 0; i < num_edges; i++) { + float fvec[3]; + const uint idx1 = medges[i].v1; + const uint idx2 = medges[i].v2; - mid_v3_v3v3(fvec, v1, v2); + mid_v3_v3v3(fvec, vertexCos[idx1], vertexCos[idx2]); - v1 = &ftmp[idx1 * 3]; - v2 = &ftmp[idx2 * 3]; + num_accumulated_vecs[idx1]++; + add_v3_v3(accumulated_vecs[idx1], fvec); - if (uctmp[idx1] < 255) { - uctmp[idx1]++; - add_v3_v3(v1, fvec); - } - if (uctmp[idx2] < 255) { - uctmp[idx2]++; - add_v3_v3(v2, fvec); - } + num_accumulated_vecs[idx2]++; + add_v3_v3(accumulated_vecs[idx2], fvec); } + const short flag = smd->flag; if (dvert) { MDeformVert *dv = dvert; - for (i = 0; i < numVerts; i++, dv++) { - float f, fm, facw, *fp, *v; - short flag = smd->flag; - - v = vertexCos[i]; - fp = &ftmp[i * 3]; - - f = defvert_find_weight(dv, defgrp_index); - if (f <= 0.0f) { - continue; + for (int i = 0; i < numVerts; i++, dv++) { + float *vco_orig = vertexCos[i]; + if (num_accumulated_vecs[0] > 0) { + mul_v3_fl(accumulated_vecs[i], 1.0f / (float)num_accumulated_vecs[i]); } + float *vco_new = accumulated_vecs[i]; - f *= fac; - fm = 1.0f - f; - - /* fp is the sum of uctmp[i] verts, so must be averaged */ - facw = 0.0f; - if (uctmp[i]) { - facw = f / (float)uctmp[i]; + const float f_new = defvert_find_weight(dv, defgrp_index) * fac_new; + if (f_new <= 0.0f) { + continue; } + const float f_orig = 1.0f - f_new; if (flag & MOD_SMOOTH_X) { - v[0] = fm * v[0] + facw * fp[0]; + vco_orig[0] = f_orig * vco_orig[0] + f_new * vco_new[0]; } if (flag & MOD_SMOOTH_Y) { - v[1] = fm * v[1] + facw * fp[1]; + vco_orig[1] = f_orig * vco_orig[1] + f_new * vco_new[1]; } if (flag & MOD_SMOOTH_Z) { - v[2] = fm * v[2] + facw * fp[2]; + vco_orig[2] = f_orig * vco_orig[2] + f_new * vco_new[2]; } } } else { /* no vertex group */ - for (i = 0; i < numVerts; i++) { - float facw, *fp, *v; - short flag = smd->flag; - - v = vertexCos[i]; - fp = &ftmp[i * 3]; - - /* fp is the sum of uctmp[i] verts, so must be averaged */ - facw = 0.0f; - if (uctmp[i]) { - facw = fac / (float)uctmp[i]; + for (int i = 0; i < numVerts; i++) { + float *vco_orig = vertexCos[i]; + if (num_accumulated_vecs[0] > 0) { + mul_v3_fl(accumulated_vecs[i], 1.0f / (float)num_accumulated_vecs[i]); } + float *vco_new = accumulated_vecs[i]; if (flag & MOD_SMOOTH_X) { - v[0] = facm * v[0] + facw * fp[0]; + vco_orig[0] = fac_orig * vco_orig[0] + fac_new * vco_new[0]; } if (flag & MOD_SMOOTH_Y) { - v[1] = facm * v[1] + facw * fp[1]; + vco_orig[1] = fac_orig * vco_orig[1] + fac_new * vco_new[1]; } if (flag & MOD_SMOOTH_Z) { - v[2] = facm * v[2] + facw * fp[2]; + vco_orig[2] = fac_orig * vco_orig[2] + fac_new * vco_new[2]; } } } - - memset(ftmp, 0, 3 * sizeof(float) * numVerts); - memset(uctmp, 0, sizeof(uchar) * numVerts); } - MEM_freeN(ftmp); - MEM_freeN(uctmp); + MEM_freeN(accumulated_vecs); + MEM_freeN(num_accumulated_vecs); } static void deformVerts(ModifierData *md, |