diff options
author | Campbell Barton <ideasman42@gmail.com> | 2016-01-14 07:16:55 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2016-01-14 07:29:37 +0300 |
commit | d67535eea00b2d9f2b75e99d45f7f200bdc642d6 (patch) | |
tree | 9da6654313964b6154288d9f649286a09184e2d1 /source/blender/editors | |
parent | 10ac7c0f15cbf82ee4dca2e10fd2a313f896d8e6 (diff) |
Weight Painting: Respect locks w/ auto-normalize
Diffstat (limited to 'source/blender/editors')
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_vertex.c | 81 |
1 files changed, 79 insertions, 2 deletions
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 76326f42dd4..797366501ad 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -1209,6 +1209,78 @@ static void do_weight_paint_normalize_all(MDeformVert *dvert, const int defbase_ } } +/** + * A version of #do_weight_paint_normalize_all that includes locked weights + * but only changes unlocked weights. + */ +static void do_weight_paint_normalize_all_locked( + MDeformVert *dvert, const int defbase_tot, const bool *vgroup_validmap, + const bool *lock_flags) +{ + float sum = 0.0f, fac; + float sum_unlock = 0.0f; + float lock_weight = 0.0f; + unsigned int i, tot = 0; + MDeformWeight *dw; + + + for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) { + if (dw->def_nr < defbase_tot && vgroup_validmap[dw->def_nr]) { + sum += dw->weight; + + if (lock_flags[dw->def_nr]) { + lock_weight += dw->weight; + } + else { + tot++; + sum_unlock += dw->weight; + } + } + } + + if ((tot == 0) || (sum == 1.0f)) { + return; + } + + if (lock_weight >= 1.0f) { + for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) { + if (dw->def_nr < defbase_tot && vgroup_validmap[dw->def_nr]) { + if (lock_flags[dw->def_nr] == false) { + dw->weight = 0.0f; + } + } + } + + } + else if (sum_unlock != 0.0f) { + fac = (1.0f - lock_weight) / sum; + + for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) { + if (dw->def_nr < defbase_tot && vgroup_validmap[dw->def_nr]) { + if (lock_flags[dw->def_nr] == false) { + dw->weight *= fac; + /* paranoid but possibly with float error */ + CLAMP(dw->weight, 0.0f, 1.0f); + } + } + } + } + else { + /* hrmf, not a factor in this case */ + fac = (1.0f - lock_weight) / tot; + /* paranoid but possibly with float error */ + CLAMP(fac, 0.0f, 1.0f); + + for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) { + if (dw->def_nr < defbase_tot && vgroup_validmap[dw->def_nr]) { + if (lock_flags[dw->def_nr] == false) { + dw->weight = fac; + } + } + } + } +} + /* same as function above except it normalizes against the active vgroup which remains unchanged * * note that the active is just the group which is unchanged, it can be any, @@ -1238,7 +1310,7 @@ static void do_weight_paint_normalize_all_active(MDeformVert *dvert, const int d } if (sum != 0.0f) { - fac = (1.0f / sum) * (1.0f - act_weight); + fac = (1.0f - act_weight) / sum; for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) { if (dw->def_nr < defbase_tot && vgroup_validmap[dw->def_nr]) { @@ -1641,7 +1713,12 @@ static int apply_mp_locks_normalize(Mesh *me, const WeightPaintInfo *wpi, if (wpi->do_auto_normalize) { /* XXX - should we pass the active group? - currently '-1' */ - do_weight_paint_normalize_all(dv, wpi->defbase_tot, wpi->vgroup_validmap); + if (wpi->lock_flags) { + do_weight_paint_normalize_all_locked(dv, wpi->defbase_tot, wpi->vgroup_validmap, wpi->lock_flags); + } + else { + do_weight_paint_normalize_all(dv, wpi->defbase_tot, wpi->vgroup_validmap); + } } if (oldChange && wpi->do_multipaint && wpi->defbase_tot_sel > 1) { |