Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIrie Shinsuke <irieshinsuke@yahoo.co.jp>2013-10-10 10:33:23 +0400
committerIrie Shinsuke <irieshinsuke@yahoo.co.jp>2013-10-10 10:33:23 +0400
commit4be74273462bbee7ba14dc660a53d769dee235e4 (patch)
tree0d04a2e6b7b1b76f65ce7f9f4f6c69a3565a1705 /source/blender/blenkernel/intern/deform.c
parentea8b44cc15d358f66ce87056c82a2b6df31589af (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.c115
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);
+ }
}
}
}