diff options
Diffstat (limited to 'source/blender/blenkernel/intern/deform.c')
-rw-r--r-- | source/blender/blenkernel/intern/deform.c | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c index 371f64fd468..edeef26ed58 100644 --- a/source/blender/blenkernel/intern/deform.c +++ b/source/blender/blenkernel/intern/deform.c @@ -80,7 +80,21 @@ bDeformGroup *defgroup_duplicate(bDeformGroup *ingroup) return outgroup; } -/* copy & overwrite weights */ +/* overwrite weights filtered by vgroup_subset + * - do nothing if neither are set. + * - add destination weight if needed + */ +void defvert_copy_subset(MDeformVert *dvert_dst, const MDeformVert *dvert_src, + const bool *vgroup_subset, const int vgroup_tot) +{ + int defgroup; + for (defgroup=0; defgroup < vgroup_tot; defgroup++) { + if (vgroup_subset[defgroup]) { + defvert_copy_index(dvert_dst, dvert_src, defgroup); + } + } +} + void defvert_copy(MDeformVert *dvert_dst, const MDeformVert *dvert_src) { if (dvert_dst->totweight == dvert_src->totweight) { @@ -181,6 +195,35 @@ void defvert_remap(MDeformVert *dvert, int *map, const int map_len) } } +/** + * Same as #defvert_normalize but takes a bool array. + */ +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 ((dw->def_nr < vgroup_tot) && vgroup_subset[dw->def_nr]) { + 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); + } + } + } +} + void defvert_normalize(MDeformVert *dvert) { if (dvert->totweight <= 0) { |