diff options
author | Irie Shinsuke <irieshinsuke@yahoo.co.jp> | 2013-10-10 10:33:23 +0400 |
---|---|---|
committer | Irie Shinsuke <irieshinsuke@yahoo.co.jp> | 2013-10-10 10:33:23 +0400 |
commit | 4be74273462bbee7ba14dc660a53d769dee235e4 (patch) | |
tree | 0d04a2e6b7b1b76f65ce7f9f4f6c69a3565a1705 /source/blender/blenkernel/intern/deform.c | |
parent | ea8b44cc15d358f66ce87056c82a2b6df31589af (diff) |
Weight Paint Tools: Add "Subset" option to "Normalize All"
This option is needed when vertex groups are used for both armature
deformation and the other purpose such as influence of mesh modifier.
Thanks to Campbell for code review!
Diffstat (limited to 'source/blender/blenkernel/intern/deform.c')
-rw-r--r-- | source/blender/blenkernel/intern/deform.c | 115 |
1 files changed, 73 insertions, 42 deletions
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c index 882085aa5db..a183872552d 100644 --- a/source/blender/blenkernel/intern/deform.c +++ b/source/blender/blenkernel/intern/deform.c @@ -217,24 +217,35 @@ void defvert_remap(MDeformVert *dvert, int *map, const int map_len) void defvert_normalize_subset(MDeformVert *dvert, const bool *vgroup_subset, const int vgroup_tot) { - MDeformWeight *dw; - unsigned int i; - float tot_weight = 0.0f; - - for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) { + if (dvert->totweight == 0) { + /* nothing */ + } + else if (dvert->totweight == 1) { + MDeformWeight *dw = dvert->dw; if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) { - tot_weight += dw->weight; + dw->weight = 1.0f; } } + else { + MDeformWeight *dw; + unsigned int i; + float tot_weight = 0.0f; - if (tot_weight > 0.0f) { - float scalar = 1.0f / tot_weight; for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) { if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) { - dw->weight *= scalar; - - /* in case of division errors with very low weights */ - CLAMP(dw->weight, 0.0f, 1.0f); + tot_weight += dw->weight; + } + } + + if (tot_weight > 0.0f) { + float scalar = 1.0f / tot_weight; + for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) { + if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) { + dw->weight *= scalar; + + /* in case of division errors with very low weights */ + CLAMP(dw->weight, 0.0f, 1.0f); + } } } } @@ -242,7 +253,7 @@ void defvert_normalize_subset(MDeformVert *dvert, void defvert_normalize(MDeformVert *dvert) { - if (dvert->totweight <= 0) { + if (dvert->totweight == 0) { /* nothing */ } else if (dvert->totweight == 1) { @@ -269,14 +280,20 @@ void defvert_normalize(MDeformVert *dvert) } } -void defvert_normalize_lock_single(MDeformVert *dvert, const int def_nr_lock) +/* Same as defvert_normalize() if the locked vgroup is not a member of the subset */ +void defvert_normalize_lock_single(MDeformVert *dvert, + const bool *vgroup_subset, const int vgroup_tot, + const int def_nr_lock) { - if (dvert->totweight <= 0) { + if (dvert->totweight == 0) { /* nothing */ } else if (dvert->totweight == 1) { - if (def_nr_lock != 0) { - dvert->dw[0].weight = 1.0f; + MDeformWeight *dw = dvert->dw; + if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) { + if (def_nr_lock != 0) { + dw->weight = 1.0f; + } } } else { @@ -287,13 +304,15 @@ void defvert_normalize_lock_single(MDeformVert *dvert, const int def_nr_lock) float lock_iweight = 1.0f; for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) { - if (dw->def_nr != def_nr_lock) { - tot_weight += dw->weight; - } - else { - dw_lock = dw; - lock_iweight = (1.0f - dw_lock->weight); - CLAMP(lock_iweight, 0.0f, 1.0f); + if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) { + if (dw->def_nr != def_nr_lock) { + tot_weight += dw->weight; + } + else { + dw_lock = dw; + lock_iweight = (1.0f - dw_lock->weight); + CLAMP(lock_iweight, 0.0f, 1.0f); + } } } @@ -302,25 +321,33 @@ void defvert_normalize_lock_single(MDeformVert *dvert, const int def_nr_lock) float scalar = (1.0f / tot_weight) * lock_iweight; for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) { - if (dw != dw_lock) { - dw->weight *= scalar; + if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) { + if (dw != dw_lock) { + dw->weight *= scalar; - /* in case of division errors with very low weights */ - CLAMP(dw->weight, 0.0f, 1.0f); + /* in case of division errors with very low weights */ + CLAMP(dw->weight, 0.0f, 1.0f); + } } } } } } -void defvert_normalize_lock_map(MDeformVert *dvert, const bool *lock_flags, const int defbase_tot) +/* Same as defvert_normalize() if no locked vgroup is a member of the subset */ +void defvert_normalize_lock_map(MDeformVert *dvert, + const bool *vgroup_subset, const int vgroup_tot, + const bool *lock_flags, const int defbase_tot) { - if (dvert->totweight <= 0) { + if (dvert->totweight == 0) { /* nothing */ } else if (dvert->totweight == 1) { - if (LIKELY(defbase_tot >= 1) && lock_flags[0]) { - dvert->dw[0].weight = 1.0f; + MDeformWeight *dw = dvert->dw; + if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) { + if (LIKELY(defbase_tot >= 1) && lock_flags[0]) { + dw->weight = 1.0f; + } } } else { @@ -330,12 +357,14 @@ void defvert_normalize_lock_map(MDeformVert *dvert, const bool *lock_flags, cons float lock_iweight = 0.0f; for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) { - if ((dw->def_nr < defbase_tot) && (lock_flags[dw->def_nr] == FALSE)) { - tot_weight += dw->weight; - } - else { - /* invert after */ - lock_iweight += dw->weight; + if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) { + if ((dw->def_nr < defbase_tot) && (lock_flags[dw->def_nr] == FALSE)) { + tot_weight += dw->weight; + } + else { + /* invert after */ + lock_iweight += dw->weight; + } } } @@ -346,11 +375,13 @@ void defvert_normalize_lock_map(MDeformVert *dvert, const bool *lock_flags, cons float scalar = (1.0f / tot_weight) * lock_iweight; for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) { - if ((dw->def_nr < defbase_tot) && (lock_flags[dw->def_nr] == FALSE)) { - dw->weight *= scalar; + if ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) { + if ((dw->def_nr < defbase_tot) && (lock_flags[dw->def_nr] == FALSE)) { + dw->weight *= scalar; - /* in case of division errors with very low weights */ - CLAMP(dw->weight, 0.0f, 1.0f); + /* in case of division errors with very low weights */ + CLAMP(dw->weight, 0.0f, 1.0f); + } } } } |