forked from bartvdbraak/blender
fix [#29431] "Normalize All" from Weight Tools don't work correctly
This commit is contained in:
parent
a512cac545
commit
99fcec3334
@ -67,7 +67,8 @@ void defvert_remap(struct MDeformVert *dvert, int *map, const int map_len);
|
||||
void defvert_flip(struct MDeformVert *dvert, const int *flip_map, const int flip_map_len);
|
||||
void defvert_flip_merged(struct MDeformVert *dvert, const int *flip_map, const int flip_map_len);
|
||||
void defvert_normalize(struct MDeformVert *dvert);
|
||||
void defvert_normalize_lock(struct MDeformVert *dvert, const int def_nr_lock);
|
||||
void defvert_normalize_lock_single(struct MDeformVert *dvert, const int def_nr_lock);
|
||||
void defvert_normalize_lock_map(struct MDeformVert *dvert, const char *lock_flags, const int defbase_tot);
|
||||
|
||||
/* utility function, note that MAX_VGROUP_NAME chars is the maximum string length since its only
|
||||
* used with defgroups currently */
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
@ -41,7 +42,10 @@
|
||||
|
||||
#include "BKE_deform.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_path_util.h"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
|
||||
@ -204,7 +208,7 @@ void defvert_normalize(MDeformVert *dvert)
|
||||
}
|
||||
}
|
||||
|
||||
void defvert_normalize_lock(MDeformVert *dvert, const int def_nr_lock)
|
||||
void defvert_normalize_lock_single(MDeformVert *dvert, const int def_nr_lock)
|
||||
{
|
||||
if (dvert->totweight <= 0) {
|
||||
/* nothing */
|
||||
@ -248,6 +252,50 @@ void defvert_normalize_lock(MDeformVert *dvert, const int def_nr_lock)
|
||||
}
|
||||
}
|
||||
|
||||
void defvert_normalize_lock_map(MDeformVert *dvert, const char *lock_flags, const int defbase_tot)
|
||||
{
|
||||
if (dvert->totweight <= 0) {
|
||||
/* nothing */
|
||||
}
|
||||
else if (dvert->totweight == 1) {
|
||||
if (LIKELY(defbase_tot >= 1) && lock_flags[0]) {
|
||||
dvert->dw[0].weight = 1.0f;
|
||||
}
|
||||
}
|
||||
else {
|
||||
MDeformWeight *dw;
|
||||
unsigned int i;
|
||||
float tot_weight = 0.0f;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
lock_iweight = maxf(0.0f, 1.0f - lock_iweight);
|
||||
|
||||
if (tot_weight > 0.0f) {
|
||||
/* paranoid, should be 1.0 but in case of float error clamp anyway */
|
||||
|
||||
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;
|
||||
|
||||
/* in case of division errors with very low weights */
|
||||
CLAMP(dw->weight, 0.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void defvert_flip(MDeformVert *dvert, const int *flip_map, const int flip_map_len)
|
||||
{
|
||||
MDeformWeight *dw;
|
||||
|
@ -62,6 +62,7 @@
|
||||
#include "BKE_tessmesh.h"
|
||||
#include "BKE_report.h"
|
||||
#include "BKE_DerivedMesh.h"
|
||||
#include "BKE_object_deform.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
#include "RNA_define.h"
|
||||
@ -1136,7 +1137,6 @@ static void vgroup_levels(Object *ob, float offset, float gain)
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO - select between groups */
|
||||
static void vgroup_normalize_all(Object *ob, int lock_active)
|
||||
{
|
||||
MDeformVert *dv, **dvert_array = NULL;
|
||||
@ -1152,27 +1152,33 @@ static void vgroup_normalize_all(Object *ob, int lock_active)
|
||||
ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot, use_vert_sel);
|
||||
|
||||
if (dvert_array) {
|
||||
if (lock_active) {
|
||||
const int defbase_tot = BLI_countlist(&ob->defbase);
|
||||
char *lock_flags = BKE_objdef_lock_flags_get(ob, defbase_tot);
|
||||
|
||||
for (i = 0; i < dvert_tot; i++) {
|
||||
/* in case its not selected */
|
||||
if (!(dv = dvert_array[i])) {
|
||||
continue;
|
||||
if ((lock_active == TRUE) &&
|
||||
(lock_flags != NULL) &&
|
||||
(def_nr < defbase_tot))
|
||||
{
|
||||
lock_flags[def_nr] = TRUE;
|
||||
}
|
||||
|
||||
for (i = 0; i < dvert_tot; i++) {
|
||||
/* in case its not selected */
|
||||
if ((dv = dvert_array[i])) {
|
||||
if (lock_flags) {
|
||||
defvert_normalize_lock_map(dv, lock_flags, defbase_tot);
|
||||
}
|
||||
else if (lock_active) {
|
||||
defvert_normalize_lock_single(dv, def_nr);
|
||||
}
|
||||
else {
|
||||
defvert_normalize(dv);
|
||||
}
|
||||
|
||||
defvert_normalize_lock(dv, def_nr);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < dvert_tot; i++) {
|
||||
|
||||
/* in case its not selected */
|
||||
if (!(dv = dvert_array[i])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
defvert_normalize(dv);
|
||||
}
|
||||
if (lock_flags) {
|
||||
MEM_freeN(lock_flags);
|
||||
}
|
||||
|
||||
MEM_freeN(dvert_array);
|
||||
|
Loading…
Reference in New Issue
Block a user