forked from bartvdbraak/blender
added an 'auto-normalize' option for weight paint mode, that automatically ensures vertex groups that affect bones all add up to 1.0. please test and give feedback.
This commit is contained in:
parent
c0a785a23e
commit
fe68d2672d
@ -519,6 +519,7 @@ class VIEW3D_PT_tools_brush(PaintPanel):
|
|||||||
|
|
||||||
elif context.weight_paint_object and brush:
|
elif context.weight_paint_object and brush:
|
||||||
layout.itemR(context.tool_settings, "vertex_group_weight", text="Weight", slider=True)
|
layout.itemR(context.tool_settings, "vertex_group_weight", text="Weight", slider=True)
|
||||||
|
layout.itemR(context.tool_settings, "auto_normalize", text="Auto Normalize")
|
||||||
|
|
||||||
col = layout.column()
|
col = layout.column()
|
||||||
row = col.row(align=True)
|
row = col.row(align=True)
|
||||||
@ -532,7 +533,7 @@ class VIEW3D_PT_tools_brush(PaintPanel):
|
|||||||
row = col.row(align=True)
|
row = col.row(align=True)
|
||||||
row.itemR(brush, "jitter", slider=True)
|
row.itemR(brush, "jitter", slider=True)
|
||||||
row.itemR(brush, "use_jitter_pressure", toggle=True, text="")
|
row.itemR(brush, "use_jitter_pressure", toggle=True, text="")
|
||||||
|
|
||||||
# Vertex Paint Mode #
|
# Vertex Paint Mode #
|
||||||
|
|
||||||
elif context.vertex_paint_object and brush:
|
elif context.vertex_paint_object and brush:
|
||||||
|
@ -43,8 +43,9 @@
|
|||||||
|
|
||||||
#include "BLI_blenlib.h"
|
#include "BLI_blenlib.h"
|
||||||
#include "BLI_arithb.h"
|
#include "BLI_arithb.h"
|
||||||
|
#include "BLI_ghash.h"
|
||||||
|
|
||||||
|
#include "DNA_anim_types.h"
|
||||||
#include "DNA_action_types.h"
|
#include "DNA_action_types.h"
|
||||||
#include "DNA_armature_types.h"
|
#include "DNA_armature_types.h"
|
||||||
#include "DNA_brush_types.h"
|
#include "DNA_brush_types.h"
|
||||||
@ -986,7 +987,44 @@ void sample_wpaint(Scene *scene, ARegion *ar, View3D *v3d, int mode)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_weight_paint_vertex(VPaint *wp, Object *ob, int index, int alpha, float paintweight, int vgroup_mirror)
|
static void do_weight_paint_auto_normalize(MDeformVert *dvert,
|
||||||
|
int paint_nr, char *map)
|
||||||
|
{
|
||||||
|
MDeformWeight *dw = dvert->dw;
|
||||||
|
float sum=0.0f, fac=0.0f, paintw=0.0f;
|
||||||
|
int i, tot=0;
|
||||||
|
|
||||||
|
if (!map)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i=0; i<dvert->totweight; i++) {
|
||||||
|
if (dvert->dw[i].def_nr == paint_nr)
|
||||||
|
paintw = dvert->dw[i].weight;
|
||||||
|
|
||||||
|
if (map[dvert->dw[i].def_nr]) {
|
||||||
|
tot += 1;
|
||||||
|
if (dvert->dw[i].def_nr != paint_nr)
|
||||||
|
sum += dvert->dw[i].weight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tot || sum <= (1.0f - paintw))
|
||||||
|
return;
|
||||||
|
|
||||||
|
fac = sum / (1.0f - paintw);
|
||||||
|
fac = fac==0.0f ? 1.0f : 1.0f / fac;
|
||||||
|
|
||||||
|
for (i=0; i<dvert->totweight; i++) {
|
||||||
|
if (map[dvert->dw[i].def_nr]) {
|
||||||
|
if (dvert->dw[i].def_nr != paint_nr)
|
||||||
|
dvert->dw[i].weight *= fac;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void do_weight_paint_vertex(VPaint *wp, Object *ob, int index,
|
||||||
|
int alpha, float paintweight,
|
||||||
|
int vgroup_mirror, char *validmap)
|
||||||
{
|
{
|
||||||
Mesh *me= ob->data;
|
Mesh *me= ob->data;
|
||||||
MDeformWeight *dw, *uw;
|
MDeformWeight *dw, *uw;
|
||||||
@ -1004,7 +1042,8 @@ static void do_weight_paint_vertex(VPaint *wp, Object *ob, int index, int alpha,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
wpaint_blend(wp, dw, uw, (float)alpha/255.0, paintweight);
|
wpaint_blend(wp, dw, uw, (float)alpha/255.0, paintweight);
|
||||||
|
do_weight_paint_auto_normalize(me->dvert+index, vgroup, validmap);
|
||||||
|
|
||||||
if(me->editflag & ME_EDIT_MIRROR_X) { /* x mirror painting */
|
if(me->editflag & ME_EDIT_MIRROR_X) { /* x mirror painting */
|
||||||
int j= mesh_get_x_mirror_vert(ob, index);
|
int j= mesh_get_x_mirror_vert(ob, index);
|
||||||
if(j>=0) {
|
if(j>=0) {
|
||||||
@ -1015,6 +1054,8 @@ static void do_weight_paint_vertex(VPaint *wp, Object *ob, int index, int alpha,
|
|||||||
uw= ED_vgroup_weight_verify(me->dvert+j, vgroup);
|
uw= ED_vgroup_weight_verify(me->dvert+j, vgroup);
|
||||||
|
|
||||||
uw->weight= dw->weight;
|
uw->weight= dw->weight;
|
||||||
|
|
||||||
|
do_weight_paint_auto_normalize(me->dvert+j, vgroup, validmap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1208,8 +1249,67 @@ struct WPaintData {
|
|||||||
int vgroup_mirror;
|
int vgroup_mirror;
|
||||||
float *vertexcosnos;
|
float *vertexcosnos;
|
||||||
float wpimat[3][3];
|
float wpimat[3][3];
|
||||||
|
|
||||||
|
/*variables for auto normalize*/
|
||||||
|
int auto_normalize;
|
||||||
|
char *vgroup_validmap; /*stores if vgroups tie to deforming bones or not*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static char *wpaint_make_validmap(Mesh *me, Object *ob)
|
||||||
|
{
|
||||||
|
bDeformGroup *dg;
|
||||||
|
ModifierData *md;
|
||||||
|
char *validmap;
|
||||||
|
bPose *pose;
|
||||||
|
bPoseChannel *chan;
|
||||||
|
ArmatureModifierData *amd;
|
||||||
|
GHash *gh = BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp);
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
/*add all names to a hash table*/
|
||||||
|
for (dg=ob->defbase.first, i=0; dg; dg=dg->next, i++) {
|
||||||
|
BLI_ghash_insert(gh, dg->name, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!i)
|
||||||
|
return;
|
||||||
|
|
||||||
|
validmap = MEM_callocN(i, "wpaint valid map");
|
||||||
|
|
||||||
|
/*now loop through the armature modifiers and identify deform bones*/
|
||||||
|
for (md = ob->modifiers.first; md; md=md->next) {
|
||||||
|
if (!(md->mode & eModifierMode_Realtime))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (md->type == eModifierType_Armature)
|
||||||
|
{
|
||||||
|
amd = (ArmatureModifierData*) md;
|
||||||
|
pose = amd->object->pose;
|
||||||
|
|
||||||
|
for (chan=pose->chanbase.first; chan; chan=chan->next) {
|
||||||
|
if (chan->bone->flag & BONE_NO_DEFORM)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (BLI_ghash_haskey(gh, chan->name)) {
|
||||||
|
BLI_ghash_remove(gh, chan->name, NULL, NULL);
|
||||||
|
BLI_ghash_insert(gh, chan->name, SET_INT_IN_POINTER(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*add all names to a hash table*/
|
||||||
|
for (dg=ob->defbase.first, i=0; dg; dg=dg->next, i++) {
|
||||||
|
if (BLI_ghash_lookup(gh, dg->name) != NULL) {
|
||||||
|
validmap[i] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BLI_ghash_free(gh, NULL, NULL);
|
||||||
|
|
||||||
|
return validmap;
|
||||||
|
}
|
||||||
|
|
||||||
static int wpaint_stroke_test_start(bContext *C, wmOperator *op, wmEvent *event)
|
static int wpaint_stroke_test_start(bContext *C, wmOperator *op, wmEvent *event)
|
||||||
{
|
{
|
||||||
Scene *scene= CTX_data_scene(C);
|
Scene *scene= CTX_data_scene(C);
|
||||||
@ -1236,6 +1336,12 @@ static int wpaint_stroke_test_start(bContext *C, wmOperator *op, wmEvent *event)
|
|||||||
view3d_set_viewcontext(C, &wpd->vc);
|
view3d_set_viewcontext(C, &wpd->vc);
|
||||||
wpd->vgroup_mirror= -1;
|
wpd->vgroup_mirror= -1;
|
||||||
|
|
||||||
|
/*set up auto-normalize, and generate map for detecting which
|
||||||
|
vgroups affect deform bones*/
|
||||||
|
wpd->auto_normalize = ts->auto_normalize;
|
||||||
|
if (wpd->auto_normalize)
|
||||||
|
wpd->vgroup_validmap = wpaint_make_validmap(me, ob);
|
||||||
|
|
||||||
// if(qual & LR_CTRLKEY) {
|
// if(qual & LR_CTRLKEY) {
|
||||||
// sample_wpaint(scene, ar, v3d, 0);
|
// sample_wpaint(scene, ar, v3d, 0);
|
||||||
// return;
|
// return;
|
||||||
@ -1417,7 +1523,9 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
|
|||||||
if((me->dvert+mface->v1)->flag) {
|
if((me->dvert+mface->v1)->flag) {
|
||||||
alpha= calc_vp_alpha_dl(wp, vc, wpd->wpimat, wpd->vertexcosnos+6*mface->v1, mval);
|
alpha= calc_vp_alpha_dl(wp, vc, wpd->wpimat, wpd->vertexcosnos+6*mface->v1, mval);
|
||||||
if(alpha) {
|
if(alpha) {
|
||||||
do_weight_paint_vertex(wp, ob, mface->v1, alpha, paintweight, wpd->vgroup_mirror);
|
do_weight_paint_vertex(wp, ob, mface->v1,
|
||||||
|
alpha, paintweight, wpd->vgroup_mirror,
|
||||||
|
wpd->vgroup_validmap);
|
||||||
}
|
}
|
||||||
(me->dvert+mface->v1)->flag= 0;
|
(me->dvert+mface->v1)->flag= 0;
|
||||||
}
|
}
|
||||||
@ -1425,7 +1533,9 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
|
|||||||
if((me->dvert+mface->v2)->flag) {
|
if((me->dvert+mface->v2)->flag) {
|
||||||
alpha= calc_vp_alpha_dl(wp, vc, wpd->wpimat, wpd->vertexcosnos+6*mface->v2, mval);
|
alpha= calc_vp_alpha_dl(wp, vc, wpd->wpimat, wpd->vertexcosnos+6*mface->v2, mval);
|
||||||
if(alpha) {
|
if(alpha) {
|
||||||
do_weight_paint_vertex(wp, ob, mface->v2, alpha, paintweight, wpd->vgroup_mirror);
|
do_weight_paint_vertex(wp, ob, mface->v2,
|
||||||
|
alpha, paintweight, wpd->vgroup_mirror,
|
||||||
|
wpd->vgroup_validmap);
|
||||||
}
|
}
|
||||||
(me->dvert+mface->v2)->flag= 0;
|
(me->dvert+mface->v2)->flag= 0;
|
||||||
}
|
}
|
||||||
@ -1433,7 +1543,9 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
|
|||||||
if((me->dvert+mface->v3)->flag) {
|
if((me->dvert+mface->v3)->flag) {
|
||||||
alpha= calc_vp_alpha_dl(wp, vc, wpd->wpimat, wpd->vertexcosnos+6*mface->v3, mval);
|
alpha= calc_vp_alpha_dl(wp, vc, wpd->wpimat, wpd->vertexcosnos+6*mface->v3, mval);
|
||||||
if(alpha) {
|
if(alpha) {
|
||||||
do_weight_paint_vertex(wp, ob, mface->v3, alpha, paintweight, wpd->vgroup_mirror);
|
do_weight_paint_vertex(wp, ob, mface->v3,
|
||||||
|
alpha, paintweight, wpd->vgroup_mirror,
|
||||||
|
wpd->vgroup_validmap);
|
||||||
}
|
}
|
||||||
(me->dvert+mface->v3)->flag= 0;
|
(me->dvert+mface->v3)->flag= 0;
|
||||||
}
|
}
|
||||||
@ -1442,7 +1554,9 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
|
|||||||
if(mface->v4) {
|
if(mface->v4) {
|
||||||
alpha= calc_vp_alpha_dl(wp, vc, wpd->wpimat, wpd->vertexcosnos+6*mface->v4, mval);
|
alpha= calc_vp_alpha_dl(wp, vc, wpd->wpimat, wpd->vertexcosnos+6*mface->v4, mval);
|
||||||
if(alpha) {
|
if(alpha) {
|
||||||
do_weight_paint_vertex(wp, ob, mface->v4, alpha, paintweight, wpd->vgroup_mirror);
|
do_weight_paint_vertex(wp, ob, mface->v4,
|
||||||
|
alpha, paintweight, wpd->vgroup_mirror,
|
||||||
|
wpd->vgroup_validmap);
|
||||||
}
|
}
|
||||||
(me->dvert+mface->v4)->flag= 0;
|
(me->dvert+mface->v4)->flag= 0;
|
||||||
}
|
}
|
||||||
@ -1466,6 +1580,9 @@ static void wpaint_stroke_done(bContext *C, struct PaintStroke *stroke)
|
|||||||
MEM_freeN(wpd->vertexcosnos);
|
MEM_freeN(wpd->vertexcosnos);
|
||||||
MEM_freeN(wpd->indexar);
|
MEM_freeN(wpd->indexar);
|
||||||
|
|
||||||
|
if (wpd->vgroup_validmap)
|
||||||
|
MEM_freeN(wpd->vgroup_validmap);
|
||||||
|
|
||||||
/* frees prev buffer */
|
/* frees prev buffer */
|
||||||
copy_wpaint_prev(ts->wpaint, NULL, 0);
|
copy_wpaint_prev(ts->wpaint, NULL, 0);
|
||||||
|
|
||||||
|
@ -669,6 +669,8 @@ typedef struct ToolSettings {
|
|||||||
/* Transform */
|
/* Transform */
|
||||||
short snap_mode, snap_flag, snap_target;
|
short snap_mode, snap_flag, snap_target;
|
||||||
short proportional, prop_mode;
|
short proportional, prop_mode;
|
||||||
|
|
||||||
|
int auto_normalize, intpad; /*auto normalizing mode in wpaint*/
|
||||||
} ToolSettings;
|
} ToolSettings;
|
||||||
|
|
||||||
typedef struct bStats {
|
typedef struct bStats {
|
||||||
|
@ -562,6 +562,12 @@ static void rna_def_tool_settings(BlenderRNA *brna)
|
|||||||
RNA_def_property_struct_type(prop, "Sculpt");
|
RNA_def_property_struct_type(prop, "Sculpt");
|
||||||
RNA_def_property_ui_text(prop, "Sculpt", "");
|
RNA_def_property_ui_text(prop, "Sculpt", "");
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "auto_normalize", PROP_BOOLEAN, PROP_NONE);
|
||||||
|
RNA_def_property_boolean_sdna(prop, NULL, "auto_normalize", 1);
|
||||||
|
RNA_def_property_ui_text(prop, "WPaint Auto-Normalize",
|
||||||
|
"Ensure all bone-deforming vertex groups add up to 1.0 while "
|
||||||
|
"weight painting");
|
||||||
|
|
||||||
prop= RNA_def_property(srna, "vertex_paint", PROP_POINTER, PROP_NONE);
|
prop= RNA_def_property(srna, "vertex_paint", PROP_POINTER, PROP_NONE);
|
||||||
RNA_def_property_pointer_sdna(prop, NULL, "vpaint");
|
RNA_def_property_pointer_sdna(prop, NULL, "vpaint");
|
||||||
RNA_def_property_ui_text(prop, "Vertex Paint", "");
|
RNA_def_property_ui_text(prop, "Vertex Paint", "");
|
||||||
|
Loading…
Reference in New Issue
Block a user