weight panel editing now supports mirroring

- use mirror when the option is enabled in editmode.
- fliped group names are used when they exist.
- only the setting that is edited will be applied to the mirrored verts group.
- copy value is applied to all mirrored verts of the selection.
- normalize normalizes all vgroups and mirrors.

utility functions defvert_sync and defvert_sync_mapped, similar to defvert_copy but does not remove existing groups and optionally creates groups as needed.
defvert_sync_mapped uses a an int array for mapping the flipped values.
This commit is contained in:
Campbell Barton 2010-01-26 17:07:47 +00:00
parent e308fe9632
commit 246bcf48ad
10 changed files with 231 additions and 119 deletions

@ -42,16 +42,22 @@ struct MDeformVert;
void defgroup_copy_list(struct ListBase *lb1, struct ListBase *lb2);
struct bDeformGroup *defgroup_duplicate(struct bDeformGroup *ingroup);
struct bDeformGroup *defgroup_find_name(Object *ob, char *name);
struct bDeformGroup *defgroup_find_name(struct Object *ob, char *name);
int defgroup_find_index(struct Object *ob, struct bDeformGroup *dg);
int *defgroup_flip_map(struct Object *ob);
int defgroup_name_index(Object *ob, const char *name);
int *defgroup_flip_map(struct Object *ob, int use_default);
int defgroup_flip_index(struct Object *ob, int index, int use_default);
int defgroup_name_index(struct Object *ob, const char *name);
void defgroup_unique_name(struct bDeformGroup *dg, struct Object *ob);
float defvert_find_weight(const struct MDeformVert *dvert, int group_num);
float defvert_find_weight_safe(const struct MDeformVert *dvert, int index, int group_num);
struct MDeformWeight *defvert_find_index(const struct MDeformVert *dv, int defgroup);
struct MDeformWeight *defvert_verify_index(struct MDeformVert *dv, int defgroup);
float defvert_find_weight(const struct MDeformVert *dvert, int group_num);
float defvert_array_find_weight_safe(const struct MDeformVert *dvert, int index, int group_num);
void defvert_copy(struct MDeformVert *dvert_r, const struct MDeformVert *dvert);
void defvert_sync(struct MDeformVert *dvert_r, const struct MDeformVert *dvert, int use_verify);
void defvert_sync_mapped(struct MDeformVert *dvert_r, const struct MDeformVert *dvert, int *flip_map, int use_verify);
void defvert_flip(struct MDeformVert *dvert, int *flip_map);
void defvert_normalize(struct MDeformVert *dvert);

@ -96,6 +96,7 @@ bDeformGroup *defgroup_duplicate (bDeformGroup *ingroup)
return outgroup;
}
/* copy & overwrite weights */
void defvert_copy (MDeformVert *dvert_r, const MDeformVert *dvert)
{
if(dvert_r->totweight == dvert->totweight) {
@ -115,6 +116,44 @@ void defvert_copy (MDeformVert *dvert_r, const MDeformVert *dvert)
}
}
/* only sync over matching weights, don't add or remove groups
* warning, loop within loop.
*/
void defvert_sync (MDeformVert *dvert_r, const MDeformVert *dvert, int use_verify)
{
if(dvert->totweight && dvert_r->totweight) {
int i;
MDeformWeight *dw;
for(i=0, dw=dvert->dw; i < dvert->totweight; i++, dw++) {
MDeformWeight *dw_r;
if(use_verify) dw_r= defvert_find_index(dvert_r, dw->def_nr);
else dw_r= defvert_verify_index(dvert_r, dw->def_nr);
if(dw_r) {
dw_r->weight= dw->weight;
}
}
}
}
/* be sure all flip_map values are valid */
void defvert_sync_mapped (MDeformVert *dvert_r, const MDeformVert *dvert, int *flip_map, int use_verify)
{
if(dvert->totweight && dvert_r->totweight) {
int i;
MDeformWeight *dw;
for(i=0, dw=dvert->dw; i < dvert->totweight; i++, dw++) {
MDeformWeight *dw_r;
if(use_verify) dw_r= defvert_find_index(dvert_r, flip_map[dw->def_nr]);
else dw_r= defvert_verify_index(dvert_r, flip_map[dw->def_nr]);
if(dw_r) {
dw_r->weight= dw->weight;
}
}
}
}
void defvert_normalize (MDeformVert *dvert)
{
if(dvert->totweight<=0) {
@ -225,7 +264,7 @@ int defgroup_find_index (Object *ob, bDeformGroup *dg)
}
/* note, must be freed */
int *defgroup_flip_map(Object *ob)
int *defgroup_flip_map(Object *ob, int use_default)
{
bDeformGroup *dg;
int totdg= BLI_countlist(&ob->defbase);
@ -236,14 +275,20 @@ int *defgroup_flip_map(Object *ob)
else {
char name[sizeof(dg->name)];
int i, flip_num, *map= MEM_mallocN(totdg * sizeof(int), "get_defgroup_flip_map");
memset(map, -1, totdg * sizeof(int));
for (dg=ob->defbase.first, i=0; dg; dg=dg->next, i++) {
if(map[i] == -1) { /* may be calculated previously */
/* incase no valid value is found, use this */
if(use_default)
map[i]= i;
flip_side_name(name, dg->name, 0);
if(strcmp(name, dg->name)) {
flip_num= defgroup_name_index(ob, name);
if(flip_num > -1) {
if(flip_num >= 0) {
map[i]= flip_num;
map[flip_num]= i; /* save an extra lookup */
}
@ -254,6 +299,22 @@ int *defgroup_flip_map(Object *ob)
}
}
int defgroup_flip_index(Object *ob, int index, int use_default)
{
bDeformGroup *dg= BLI_findlink(&ob->defbase, index);
int flip_index = -1;
if(dg) {
char name[sizeof(dg->name)];
flip_side_name(name, dg->name, 0);
if(strcmp(name, dg->name))
flip_index= defgroup_name_index(ob, name);
}
return (flip_index==-1 && use_default) ? index : flip_index;
}
void defgroup_unique_name (bDeformGroup *dg, Object *ob)
{
bDeformGroup *curdef;
@ -423,29 +484,61 @@ void flip_side_name (char *name, const char *from_name, int strip_number)
sprintf (name, "%s%s%s%s", prefix, replace, suffix, number);
}
float defvert_find_weight(const struct MDeformVert *dvert, int group_num)
{
if(dvert)
{
const MDeformWeight *dw = dvert->dw;
int i;
for(i=dvert->totweight; i>0; i--, dw++)
if(dw->def_nr == group_num)
return dw->weight;
}
/* Not found */
return 0.0;
MDeformWeight *dw= defvert_find_index(dvert, group_num);
return dw ? dw->weight : 1.0f;
}
float defvert_find_weight_safe(const struct MDeformVert *dvert, int index, int group_num)
float defvert_array_find_weight_safe(const struct MDeformVert *dvert, int index, int group_num)
{
if(group_num == -1 || dvert == NULL)
return 1.0;
return 1.0f;
return defvert_find_weight(dvert+index, group_num);
}
MDeformWeight *defvert_find_index(const MDeformVert *dvert, int defgroup)
{
if(dvert && defgroup >= 0) {
MDeformWeight *dw = dvert->dw;
int i;
for(i=dvert->totweight; i>0; i--, dw++)
if(dw->def_nr == defgroup)
return dw;
}
return NULL;
}
/* Ensures that mv has a deform weight entry for the specified defweight group */
/* Note this function is mirrored in editmesh_tools.c, for use for editvertices */
MDeformWeight *defvert_verify_index(MDeformVert *dv, int defgroup)
{
MDeformWeight *newdw;
/* do this check always, this function is used to check for it */
if(!dv || defgroup<0)
return NULL;
newdw = defvert_find_index(dv, defgroup);
if(newdw)
return newdw;
newdw = MEM_callocN(sizeof(MDeformWeight)*(dv->totweight+1), "deformWeight");
if(dv->dw) {
memcpy(newdw, dv->dw, sizeof(MDeformWeight)*dv->totweight);
MEM_freeN(dv->dw);
}
dv->dw=newdw;
dv->dw[dv->totweight].weight=0.0f;
dv->dw[dv->totweight].def_nr=defgroup;
/* Group index */
dv->totweight++;
return dv->dw+(dv->totweight-1);
}

@ -1812,7 +1812,7 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
if (do_vgroup_mirr) {
flip_map= defgroup_flip_map(ob);
flip_map= defgroup_flip_map(ob, 0);
if(flip_map == NULL)
do_vgroup_mirr= 0;
}

@ -184,7 +184,7 @@ static void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc)
{
float *co = calc->vertexCos[i];
float tmp_co[3];
float weight = defvert_find_weight_safe(calc->dvert, i, calc->vgroup);
float weight = defvert_array_find_weight_safe(calc->dvert, i, calc->vgroup);
if(weight == 0.0f) continue;
@ -356,7 +356,7 @@ static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc, struct S
{
float *co = calc->vertexCos[i];
float tmp_co[3], tmp_no[3];
float weight = defvert_find_weight_safe(calc->dvert, i, calc->vgroup);
float weight = defvert_array_find_weight_safe(calc->dvert, i, calc->vgroup);
if(weight == 0.0f) continue;
@ -447,7 +447,7 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc)
{
float *co = calc->vertexCos[i];
float tmp_co[3];
float weight = defvert_find_weight_safe(calc->dvert, i, calc->vgroup);
float weight = defvert_array_find_weight_safe(calc->dvert, i, calc->vgroup);
if(weight == 0.0f) continue;
//Convert the vertex to tree coordinates

@ -227,7 +227,7 @@ void SimpleDeformModifier_do(SimpleDeformModifierData *smd, struct Object *ob, s
for(i=0; i<numVerts; i++)
{
float weight = defvert_find_weight_safe(dvert, i, vgroup);
float weight = defvert_array_find_weight_safe(dvert, i, vgroup);
if(weight != 0.0f)
{

@ -195,9 +195,6 @@ void ED_vgroup_vert_add(struct Object *ob, struct bDeformGroup *dg, int vertnum
void ED_vgroup_vert_remove(struct Object *ob, struct bDeformGroup *dg, int vertnum);
float ED_vgroup_vert_weight(struct Object *ob, struct bDeformGroup *dg, int vertnum);
struct MDeformWeight *ED_vgroup_weight_verify(struct MDeformVert *dv, int defgroup);
struct MDeformWeight *ED_vgroup_weight_get(struct MDeformVert *dv, int defgroup);
/*needed by edge slide*/
struct EditVert *editedge_getOtherVert(struct EditEdge *eed, struct EditVert *eve);
struct EditVert *editedge_getSharedVert(struct EditEdge *eed, struct EditEdge *eed2);

@ -85,51 +85,6 @@ static Lattice *vgroup_edit_lattice(Object *ob)
return NULL;
}
/* check if deform vertex has defgroup index */
MDeformWeight *ED_vgroup_weight_get(MDeformVert *dv, int defgroup)
{
int i;
if(!dv || defgroup<0)
return NULL;
for(i=0; i<dv->totweight; i++)
if(dv->dw[i].def_nr == defgroup)
return dv->dw+i;
return NULL;
}
/* Ensures that mv has a deform weight entry for the specified defweight group */
/* Note this function is mirrored in editmesh_tools.c, for use for editvertices */
MDeformWeight *ED_vgroup_weight_verify(MDeformVert *dv, int defgroup)
{
MDeformWeight *newdw;
/* do this check always, this function is used to check for it */
if(!dv || defgroup<0)
return NULL;
newdw = ED_vgroup_weight_get(dv, defgroup);
if(newdw)
return newdw;
newdw = MEM_callocN(sizeof(MDeformWeight)*(dv->totweight+1), "deformWeight");
if(dv->dw) {
memcpy(newdw, dv->dw, sizeof(MDeformWeight)*dv->totweight);
MEM_freeN(dv->dw);
}
dv->dw=newdw;
dv->dw[dv->totweight].weight=0.0f;
dv->dw[dv->totweight].def_nr=defgroup;
/* Group index */
dv->totweight++;
return dv->dw+(dv->totweight-1);
}
bDeformGroup *ED_vgroup_add_name(Object *ob, char *name)
{
bDeformGroup *defgroup;
@ -569,11 +524,11 @@ static void vgroup_duplicate(Object *ob)
for(i = 0; i < dvert_tot; i++) {
dvert = dvert_array+i;
org = ED_vgroup_weight_get(dvert, idg);
org = defvert_find_index(dvert, idg);
if(org) {
float weight = org->weight;
/* ED_vgroup_weight_verify re-allocs org so need to store the weight first */
cpy = ED_vgroup_weight_verify(dvert, icdg);
/* defvert_verify_index re-allocs org so need to store the weight first */
cpy = defvert_verify_index(dvert, icdg);
cpy->weight = weight;
}
}
@ -597,7 +552,7 @@ static void vgroup_normalize(Object *ob)
for(i = 0; i < dvert_tot; i++) {
dvert = dvert_array+i;
dw = ED_vgroup_weight_get(dvert, def_nr);
dw = defvert_find_index(dvert, def_nr);
if(dw) {
weight_max = MAX2(dw->weight, weight_max);
}
@ -606,7 +561,7 @@ static void vgroup_normalize(Object *ob)
if(weight_max > 0.0f) {
for(i = 0; i < dvert_tot; i++) {
dvert = dvert_array+i;
dw = ED_vgroup_weight_get(dvert, def_nr);
dw = defvert_find_index(dvert, def_nr);
if(dw) {
dw->weight /= weight_max;
@ -634,7 +589,7 @@ static void vgroup_levels(Object *ob, float offset, float gain)
for(i = 0; i < dvert_tot; i++) {
dvert = dvert_array+i;
dw = ED_vgroup_weight_get(dvert, def_nr);
dw = defvert_find_index(dvert, def_nr);
if(dw) {
dw->weight = gain * (dw->weight + offset);
@ -745,9 +700,9 @@ static void vgroup_invert(Object *ob, int auto_assign, int auto_remove)
dvert = dvert_array+i;
if(auto_assign) {
dw= ED_vgroup_weight_verify(dvert, def_nr);
dw= defvert_verify_index(dvert, def_nr);
} else {
dw= ED_vgroup_weight_get(dvert, def_nr);
dw= defvert_find_index(dvert, def_nr);
}
if(dw) {
@ -820,7 +775,7 @@ static void vgroup_blend(Object *ob)
if(em) dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
else dvert= dvert_array+i2;
dw= ED_vgroup_weight_get(dvert, def_nr);
dw= defvert_find_index(dvert, def_nr);
if(dw) {
vg_weights[i1] += dw->weight;
@ -835,7 +790,7 @@ static void vgroup_blend(Object *ob)
if(em) dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
else dvert= dvert_array+i;
dw= ED_vgroup_weight_verify(dvert, def_nr);
dw= defvert_verify_index(dvert, def_nr);
dw->weight= vg_weights[i] / (float)vg_users[i];
}
@ -863,7 +818,7 @@ static void vgroup_clean(Object *ob, float eul, int keep_single)
for(i = 0; i < dvert_tot; i++) {
dvert = dvert_array+i;
dw= ED_vgroup_weight_get(dvert, def_nr);
dw= defvert_find_index(dvert, def_nr);
if(dw) {
if(dw->weight <= eul)
@ -923,7 +878,7 @@ void ED_vgroup_mirror(Object *ob, int mirror_weights, int flip_vgroups)
if(!CustomData_has_layer(&em->vdata, CD_MDEFORMVERT))
return;
flip_map= defgroup_flip_map(ob);
flip_map= defgroup_flip_map(ob, 0);
/* Go through the list of editverts and assign them */
for(eve=em->verts.first; eve; eve=eve->next){
@ -1042,7 +997,7 @@ static void vgroup_delete_object_mode(Object *ob)
for(i = 0; i < dvert_tot; i++) {
dvert = dvert_array + i;
if(dvert) {
if(ED_vgroup_weight_get(dvert, (ob->actdef-1)))
if(defvert_find_index(dvert, (ob->actdef-1)))
ED_vgroup_vert_remove(ob, dg, i);
}
}

@ -435,9 +435,9 @@ void wpaint_fill(VPaint *wp, Object *ob, float paintweight)
faceverts[3]= mface->v4;
for (i=0; i<3 || faceverts[i]; i++) {
if(!((me->dvert+faceverts[i])->flag)) {
dw= ED_vgroup_weight_verify(me->dvert+faceverts[i], vgroup);
dw= defvert_verify_index(me->dvert+faceverts[i], vgroup);
if(dw) {
uw= ED_vgroup_weight_verify(wp->wpaint_prev+faceverts[i], vgroup);
uw= defvert_verify_index(wp->wpaint_prev+faceverts[i], vgroup);
uw->weight= dw->weight; /* set the undo weight */
dw->weight= paintweight;
@ -446,11 +446,11 @@ void wpaint_fill(VPaint *wp, Object *ob, float paintweight)
if(j>=0) {
/* copy, not paint again */
if(vgroup_mirror != -1) {
dw= ED_vgroup_weight_verify(me->dvert+j, vgroup_mirror);
uw= ED_vgroup_weight_verify(wp->wpaint_prev+j, vgroup_mirror);
dw= defvert_verify_index(me->dvert+j, vgroup_mirror);
uw= defvert_verify_index(wp->wpaint_prev+j, vgroup_mirror);
} else {
dw= ED_vgroup_weight_verify(me->dvert+j, vgroup);
uw= ED_vgroup_weight_verify(wp->wpaint_prev+j, vgroup);
dw= defvert_verify_index(me->dvert+j, vgroup);
uw= defvert_verify_index(wp->wpaint_prev+j, vgroup);
}
uw->weight= dw->weight; /* set the undo weight */
dw->weight= paintweight;
@ -989,20 +989,20 @@ void sample_wpaint(Scene *scene, ARegion *ar, View3D *v3d, int mode)
fac= MIN4(w1, w2, w3, w4);
if(w1==fac) {
dw= ED_vgroup_weight_get(me->dvert+mface->v1, ob->actdef-1);
dw= defvert_find_index(me->dvert+mface->v1, ob->actdef-1);
if(dw) ts->vgroup_weight= dw->weight; else ts->vgroup_weight= 0.0f;
}
else if(w2==fac) {
dw= ED_vgroup_weight_get(me->dvert+mface->v2, ob->actdef-1);
dw= defvert_find_index(me->dvert+mface->v2, ob->actdef-1);
if(dw) ts->vgroup_weight= dw->weight; else ts->vgroup_weight= 0.0f;
}
else if(w3==fac) {
dw= ED_vgroup_weight_get(me->dvert+mface->v3, ob->actdef-1);
dw= defvert_find_index(me->dvert+mface->v3, ob->actdef-1);
if(dw) ts->vgroup_weight= dw->weight; else ts->vgroup_weight= 0.0f;
}
else if(w4==fac) {
if(mface->v4) {
dw= ED_vgroup_weight_get(me->dvert+mface->v4, ob->actdef-1);
dw= defvert_find_index(me->dvert+mface->v4, ob->actdef-1);
if(dw) ts->vgroup_weight= dw->weight; else ts->vgroup_weight= 0.0f;
}
}
@ -1058,12 +1058,12 @@ static void do_weight_paint_vertex(VPaint *wp, Object *ob, int index,
int vgroup= ob->actdef-1;
if(wp->flag & VP_ONLYVGROUP) {
dw= ED_vgroup_weight_get(me->dvert+index, vgroup);
uw= ED_vgroup_weight_get(wp->wpaint_prev+index, vgroup);
dw= defvert_find_index(me->dvert+index, vgroup);
uw= defvert_find_index(wp->wpaint_prev+index, vgroup);
}
else {
dw= ED_vgroup_weight_verify(me->dvert+index, vgroup);
uw= ED_vgroup_weight_verify(wp->wpaint_prev+index, vgroup);
dw= defvert_verify_index(me->dvert+index, vgroup);
uw= defvert_verify_index(wp->wpaint_prev+index, vgroup);
}
if(dw==NULL || uw==NULL)
return;
@ -1076,9 +1076,9 @@ static void do_weight_paint_vertex(VPaint *wp, Object *ob, int index,
if(j>=0) {
/* copy, not paint again */
if(vgroup_mirror != -1)
uw= ED_vgroup_weight_verify(me->dvert+j, vgroup_mirror);
uw= defvert_verify_index(me->dvert+j, vgroup_mirror);
else
uw= ED_vgroup_weight_verify(me->dvert+j, vgroup);
uw= defvert_verify_index(me->dvert+j, vgroup);
uw->weight= dw->weight;
@ -1538,10 +1538,10 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
if(mface->v4) (me->dvert+mface->v4)->flag= 1;
if(brush->vertexpaint_tool==VP_BLUR) {
MDeformWeight *dw, *(*dw_func)(MDeformVert *, int) = ED_vgroup_weight_verify;
MDeformWeight *dw, *(*dw_func)(MDeformVert *, int) = defvert_verify_index;
if(wp->flag & VP_ONLYVGROUP)
dw_func= ED_vgroup_weight_get;
dw_func= defvert_find_index;
dw= dw_func(me->dvert+mface->v1, ob->actdef-1);
if(dw) {paintweight+= dw->weight; totw++;}

@ -1297,7 +1297,7 @@ static void drawlattice__point(Lattice *lt, DispList *dl, int u, int v, int w, i
if(use_wcol) {
float col[3];
MDeformWeight *mdw= ED_vgroup_weight_get (lt->dvert+index, use_wcol-1);
MDeformWeight *mdw= defvert_find_index (lt->dvert+index, use_wcol-1);
weight_to_rgb(mdw?mdw->weight:0.0f, col, col+1, col+2);
glColor3fv(col);

@ -477,11 +477,10 @@ static void v3d_editvertex_buts(const bContext *C, uiLayout *layout, View3D *v3d
// ED_undo_push(C, "Transform properties");
}
}
#define B_VGRP_PNL_EDIT 1
#define B_VGRP_PNL_COPY 2
#define B_VGRP_PNL_NORMALIZE 3
#define B_VGRP_PNL_COPY_SINGLE 100 /* or greater */
#define B_VGRP_PNL_COPY 1
#define B_VGRP_PNL_NORMALIZE 2
#define B_VGRP_PNL_EDIT_SINGLE 8 /* or greater */
#define B_VGRP_PNL_COPY_SINGLE 16384 /* or greater */
static void act_vert_def(Object *ob, EditVert **eve, MDeformVert **dvert)
{
@ -503,6 +502,49 @@ static void act_vert_def(Object *ob, EditVert **eve, MDeformVert **dvert)
*dvert= NULL;
}
static void editvert_mirror_update(Object *ob, EditVert *eve, int def_nr)
{
Mesh *me= ob->data;
EditMesh *em = BKE_mesh_get_editmesh(me);
EditVert *eve_mirr;
eve_mirr= editmesh_get_x_mirror_vert(ob, em, eve->co);
if(eve_mirr && eve_mirr != eve) {
MDeformVert *dvert_src= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
MDeformVert *dvert_dst= CustomData_em_get(&em->vdata, eve_mirr->data, CD_MDEFORMVERT);
if(dvert_dst) {
if(def_nr == -1) {
/* all vgroups, add groups where neded */
int *flip_map= defgroup_flip_map(ob, 1);
defvert_sync_mapped(dvert_dst, dvert_src, flip_map, 1);
MEM_freeN(flip_map);
}
else {
/* single vgroup */
MDeformWeight *dw= defvert_verify_index(dvert_dst, defgroup_flip_index(ob, def_nr, 1));
if(dw) {
dw->weight= defvert_find_weight(dvert_src, def_nr);
}
}
}
}
}
static void vgroup_adjust_active(Object *ob, int def_nr)
{
EditVert *eve_act;
MDeformVert *dvert_act;
act_vert_def(ob, &eve_act, &dvert_act);
if(dvert_act) {
if(((Mesh *)ob->data)->editflag & ME_EDIT_MIRROR_X)
editvert_mirror_update(ob, eve_act, def_nr);
}
}
static void vgroup_copy_active_to_sel(Object *ob)
{
EditVert *eve_act;
@ -522,8 +564,13 @@ static void vgroup_copy_active_to_sel(Object *ob)
for(eve= em->verts.first; eve; eve= eve->next) {
if(eve->f & SELECT && eve != eve_act) {
dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
if(dvert)
if(dvert) {
defvert_copy(dvert, dvert_act);
if(me->editflag & ME_EDIT_MIRROR_X)
editvert_mirror_update(ob, eve, -1);
}
}
}
}
@ -565,12 +612,20 @@ static void vgroup_copy_active_to_sel_single(Object *ob, int def_nr)
for(i=0, dw=dvert->dw; i < dvert->totweight; i++, dw++) {
if(def_nr == dw->def_nr) {
dw->weight= act_weight;
if(me->editflag & ME_EDIT_MIRROR_X)
editvert_mirror_update(ob, eve, -1);
break;
}
}
}
}
}
if(me->editflag & ME_EDIT_MIRROR_X)
editvert_mirror_update(ob, eve_act, -1);
}
}
@ -585,6 +640,12 @@ static void vgroup_normalize_active(Object *ob)
return;
defvert_normalize(dvert_act);
if(((Mesh *)ob->data)->editflag & ME_EDIT_MIRROR_X)
editvert_mirror_update(ob, eve_act, -1);
}
static void do_view3d_vgroup_buttons(bContext *C, void *arg, int event)
@ -592,10 +653,7 @@ static void do_view3d_vgroup_buttons(bContext *C, void *arg, int event)
Scene *scene= CTX_data_scene(C);
Object *ob= OBACT;
if(event==B_VGRP_PNL_EDIT) {
/* nothing */
}
else if(event==B_VGRP_PNL_NORMALIZE) {
if(event==B_VGRP_PNL_NORMALIZE) {
vgroup_normalize_active(ob);
}
else if(event == B_VGRP_PNL_COPY) {
@ -604,6 +662,9 @@ static void do_view3d_vgroup_buttons(bContext *C, void *arg, int event)
else if(event >= B_VGRP_PNL_COPY_SINGLE) {
vgroup_copy_active_to_sel_single(ob, event - B_VGRP_PNL_COPY_SINGLE);
}
else if(event >= B_VGRP_PNL_EDIT_SINGLE) {
vgroup_adjust_active(ob, event - B_VGRP_PNL_EDIT_SINGLE);
}
// todo
// if(((Mesh *)ob->data)->editflag & ME_EDIT_MIRROR_X)
@ -654,7 +715,7 @@ static void view3d_panel_vgroup(const bContext *C, Panel *pa)
for (i=0; i<dvert->totweight; i++){
dg = BLI_findlink (&ob->defbase, dvert->dw[i].def_nr);
if(dg) {
uiDefButF(block, NUM, B_VGRP_PNL_EDIT, dg->name, 0, yco, 180, 20, &dvert->dw[i].weight, 0.0, 1.0, 1, 3, "");
uiDefButF(block, NUM, B_VGRP_PNL_EDIT_SINGLE + dvert->dw[i].def_nr, dg->name, 0, yco, 180, 20, &dvert->dw[i].weight, 0.0, 1.0, 1, 3, "");
uiDefBut(block, BUT, B_VGRP_PNL_COPY_SINGLE + dvert->dw[i].def_nr, "C", 180,yco,20,20, 0, 0, 0, 0, 0, "Copy this groups weight to other selected verts");
yco -= 20;
}