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(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_flip_merged(struct MDeformVert *dvert, const int *flip_map, const int flip_map_len);
|
||||||
void defvert_normalize(struct MDeformVert *dvert);
|
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
|
/* utility function, note that MAX_VGROUP_NAME chars is the maximum string length since its only
|
||||||
* used with defgroups currently */
|
* used with defgroups currently */
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "MEM_guardedalloc.h"
|
#include "MEM_guardedalloc.h"
|
||||||
|
|
||||||
@ -41,7 +42,10 @@
|
|||||||
|
|
||||||
#include "BKE_deform.h"
|
#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"
|
#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) {
|
if (dvert->totweight <= 0) {
|
||||||
/* nothing */
|
/* 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)
|
void defvert_flip(MDeformVert *dvert, const int *flip_map, const int flip_map_len)
|
||||||
{
|
{
|
||||||
MDeformWeight *dw;
|
MDeformWeight *dw;
|
||||||
|
@ -62,6 +62,7 @@
|
|||||||
#include "BKE_tessmesh.h"
|
#include "BKE_tessmesh.h"
|
||||||
#include "BKE_report.h"
|
#include "BKE_report.h"
|
||||||
#include "BKE_DerivedMesh.h"
|
#include "BKE_DerivedMesh.h"
|
||||||
|
#include "BKE_object_deform.h"
|
||||||
|
|
||||||
#include "RNA_access.h"
|
#include "RNA_access.h"
|
||||||
#include "RNA_define.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)
|
static void vgroup_normalize_all(Object *ob, int lock_active)
|
||||||
{
|
{
|
||||||
MDeformVert *dv, **dvert_array = NULL;
|
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);
|
ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot, use_vert_sel);
|
||||||
|
|
||||||
if (dvert_array) {
|
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++) {
|
if ((lock_active == TRUE) &&
|
||||||
/* in case its not selected */
|
(lock_flags != NULL) &&
|
||||||
if (!(dv = dvert_array[i])) {
|
(def_nr < defbase_tot))
|
||||||
continue;
|
{
|
||||||
|
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 (lock_flags) {
|
||||||
if (!(dv = dvert_array[i])) {
|
MEM_freeN(lock_flags);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
defvert_normalize(dv);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MEM_freeN(dvert_array);
|
MEM_freeN(dvert_array);
|
||||||
|
Loading…
Reference in New Issue
Block a user