diff options
author | Cody Winchester <CodyWinch> | 2020-05-26 21:53:38 +0300 |
---|---|---|
committer | Bastien Montagne <bastien@blender.org> | 2020-05-26 21:56:27 +0300 |
commit | de257b6366455ba6a3604c0830a92245df11f7bc (patch) | |
tree | 239c022c52cbb655ce2116fddb151c3f55549ed6 /source/blender/modifiers/intern | |
parent | 00674c12cc0f08254e5643ad18120b2e9e710a94 (diff) |
Modifiers: Add normalize weights option to vertex weight modifiers
Original patch by Cody Winchester (@CodyWinch), several fixes and
cleanup by Bastien Montagne (@mont29).
Differential revision: https://developer.blender.org/D7656
Diffstat (limited to 'source/blender/modifiers/intern')
5 files changed, 40 insertions, 5 deletions
diff --git a/source/blender/modifiers/intern/MOD_weightvg_util.c b/source/blender/modifiers/intern/MOD_weightvg_util.c index 5dae6bb8505..1a38787777f 100644 --- a/source/blender/modifiers/intern/MOD_weightvg_util.c +++ b/source/blender/modifiers/intern/MOD_weightvg_util.c @@ -272,16 +272,45 @@ void weightvg_update_vg(MDeformVert *dvert, const bool do_add, const float add_thresh, const bool do_rem, - const float rem_thresh) + const float rem_thresh, + const bool do_normalize) { int i; + float min_w = weights[0]; + float norm_fac = 1.0f; + if (do_normalize) { + float max_w = weights[0]; + for (i = 1; i < num; i++) { + const float w = weights[i]; + + /* No need to clamp here, normalization will ensure we stay within [0.0, 1.0] range. */ + if (w < min_w) { + min_w = w; + } + else if (w > max_w) { + max_w = w; + } + } + + const float range = max_w - min_w; + if (fabsf(range) > FLT_EPSILON) { + norm_fac = 1.0f / range; + } + else { + min_w = 0.0f; + } + } + for (i = 0; i < num; i++) { float w = weights[i]; MDeformVert *dv = &dvert[indices ? indices[i] : i]; MDeformWeight *dw = dws ? dws[i] : ((defgrp_idx >= 0) ? BKE_defvert_find_index(dv, defgrp_idx) : NULL); + if (do_normalize) { + w = (w - min_w) * norm_fac; + } /* Never allow weights out of [0.0, 1.0] range. */ CLAMP(w, 0.0f, 1.0f); diff --git a/source/blender/modifiers/intern/MOD_weightvg_util.h b/source/blender/modifiers/intern/MOD_weightvg_util.h index 09a6a1afb3e..50597d43112 100644 --- a/source/blender/modifiers/intern/MOD_weightvg_util.h +++ b/source/blender/modifiers/intern/MOD_weightvg_util.h @@ -86,6 +86,7 @@ void weightvg_update_vg(struct MDeformVert *dvert, const bool do_add, const float add_thresh, const bool do_rem, - const float rem_thresh); + const float rem_thresh, + const bool do_normalize); #endif /* __MOD_WEIGHTVG_UTIL_H__ */ diff --git a/source/blender/modifiers/intern/MOD_weightvgedit.c b/source/blender/modifiers/intern/MOD_weightvgedit.c index 1ff8dfbdcca..8ce1aaee942 100644 --- a/source/blender/modifiers/intern/MOD_weightvgedit.c +++ b/source/blender/modifiers/intern/MOD_weightvgedit.c @@ -239,6 +239,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * /* Do mapping. */ const bool do_invert_mapping = (wmd->edit_flags & MOD_WVG_INVERT_FALLOFF) != 0; + const bool do_normalize = (wmd->edit_flags & MOD_WVG_EDIT_WEIGHTS_NORMALIZE) != 0; if (do_invert_mapping || wmd->falloff_type != MOD_WVG_MAPPING_NONE) { RNG *rng = NULL; @@ -283,7 +284,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * do_add, wmd->add_threshold, do_rem, - wmd->rem_threshold); + wmd->rem_threshold, + do_normalize); /* If weight preview enabled... */ #if 0 /* XXX Currently done in mod stack :/ */ diff --git a/source/blender/modifiers/intern/MOD_weightvgmix.c b/source/blender/modifiers/intern/MOD_weightvgmix.c index f1db8502d74..57156aec5ec 100644 --- a/source/blender/modifiers/intern/MOD_weightvgmix.c +++ b/source/blender/modifiers/intern/MOD_weightvgmix.c @@ -224,6 +224,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * int numIdx = 0; int i; const bool invert_vgroup_mask = (wmd->flag & MOD_WVG_MIX_INVERT_VGROUP_MASK) != 0; + const bool do_normalize = (wmd->flag & MOD_WVG_MIX_WEIGHTS_NORMALIZE) != 0; /* Flags. */ #if 0 const bool do_prev = (wmd->modifier.mode & eModifierMode_DoWeightPreview) != 0; @@ -408,7 +409,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * * XXX Depending on the MOD_WVG_SET_xxx option chosen, we might have to add vertices to vgroup. */ weightvg_update_vg( - dvert, defgrp_index, dw1, numIdx, indices, org_w, true, -FLT_MAX, false, 0.0f); + dvert, defgrp_index, dw1, numIdx, indices, org_w, true, -FLT_MAX, false, 0.0f, do_normalize); /* If weight preview enabled... */ #if 0 /* XXX Currently done in mod stack :/ */ diff --git a/source/blender/modifiers/intern/MOD_weightvgproximity.c b/source/blender/modifiers/intern/MOD_weightvgproximity.c index 3e746403050..e3f833ff81e 100644 --- a/source/blender/modifiers/intern/MOD_weightvgproximity.c +++ b/source/blender/modifiers/intern/MOD_weightvgproximity.c @@ -429,6 +429,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * int i; const bool invert_vgroup_mask = (wmd->proximity_flags & MOD_WVG_PROXIMITY_INVERT_VGROUP_MASK) != 0; + const bool do_normalize = (wmd->proximity_flags & MOD_WVG_PROXIMITY_WEIGHTS_NORMALIZE) != 0; /* Flags. */ #if 0 const bool do_prev = (wmd->modifier.mode & eModifierMode_DoWeightPreview) != 0; @@ -604,7 +605,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * invert_vgroup_mask); /* Update vgroup. Note we never add nor remove vertices from vgroup here. */ - weightvg_update_vg(dvert, defgrp_index, dw, numIdx, indices, org_w, false, 0.0f, false, 0.0f); + weightvg_update_vg( + dvert, defgrp_index, dw, numIdx, indices, org_w, false, 0.0f, false, 0.0f, do_normalize); /* If weight preview enabled... */ #if 0 /* XXX Currently done in mod stack :/ */ |