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; - - ftmp = (float *)MEM_calloc_arrayN(numVerts, 3 * sizeof(float), "smoothmodifier_f"); - if (!ftmp) { + if (mesh == NULL) { return; } - uctmp = (uchar *)MEM_calloc_arrayN(numVerts, sizeof(uchar), "smoothmodifier_uc"); - if (!uctmp) { - if (ftmp) { - MEM_freeN(ftmp); + + float(*accumulated_vecs)[3] = MEM_calloc_arrayN( + (size_t)numVerts, sizeof(*accumulated_vecs), __func__); + if (!accumulated_vecs) { + return; + } + + 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; - - v1 = vertexCos[idx1]; - v2 = vertexCos[idx2]; - - mid_v3_v3v3(fvec, v1, v2); - - v1 = &ftmp[idx1 * 3]; - v2 = &ftmp[idx2 * 3]; - - if (uctmp[idx1] < 255) { - uctmp[idx1]++; - add_v3_v3(v1, fvec); - } - if (uctmp[idx2] < 255) { - uctmp[idx2]++; - add_v3_v3(v2, fvec); - } + 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); } + 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, vertexCos[idx1], vertexCos[idx2]); + + num_accumulated_vecs[idx1]++; + add_v3_v3(accumulated_vecs[idx1], 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; + 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]; - v = vertexCos[i]; - fp = &ftmp[i * 3]; - - f = defvert_find_weight(dv, defgrp_index); - if (f <= 0.0f) { + const float f_new = defvert_find_weight(dv, defgrp_index) * fac_new; + if (f_new <= 0.0f) { continue; } - - 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_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,