diff options
Diffstat (limited to 'source/blender/editors/object/object_vgroup.c')
-rw-r--r-- | source/blender/editors/object/object_vgroup.c | 1467 |
1 files changed, 745 insertions, 722 deletions
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 2b17a6cbe54..154ab14df60 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -25,6 +25,8 @@ * Contributor(s): none yet. * * ***** END GPL LICENSE BLOCK ***** + * Creator-specific support for vertex deformation groups + * Added: apply deform function (ton) */ #include <string.h> @@ -59,7 +61,6 @@ #include "BKE_utildefines.h" #include "RNA_access.h" -#include "RNA_define.h" #include "WM_api.h" #include "WM_types.h" @@ -67,55 +68,127 @@ #include "ED_mesh.h" #include "ED_view3d.h" -#include "UI_interface.h" - #include "object_intern.h" -/************************ Exported Functions **********************/ +/* XXX */ +static void BIF_undo_push() {} +static void error() {} -static Lattice *vgroup_edit_lattice(Object *ob) +static Lattice *def_get_lattice(Object *ob) { if(ob->type==OB_LATTICE) { Lattice *lt= ob->data; - return (lt->editlatt)? lt->editlatt: lt; + if(lt->editlatt) + return lt->editlatt; + return lt; } - return NULL; } +/* only in editmode */ +void sel_verts_defgroup (Object *obedit, int select) +{ + EditVert *eve; + Object *ob; + int i; + MDeformVert *dvert; + + ob= obedit; + + if (!ob) + return; + + switch (ob->type){ + case OB_MESH: + { + Mesh *me= ob->data; + EditMesh *em = BKE_mesh_get_editmesh(me); + + for (eve=em->verts.first; eve; eve=eve->next){ + dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); + + if (dvert && dvert->totweight){ + for (i=0; i<dvert->totweight; i++){ + if (dvert->dw[i].def_nr == (ob->actdef-1)){ + if (select) eve->f |= SELECT; + else eve->f &= ~SELECT; + + break; + } + } + } + } + /* this has to be called, because this function operates on vertices only */ + if(select) EM_select_flush(em); // vertices to edges/faces + else EM_deselect_flush(em); + + BKE_mesh_end_editmesh(me, em); + } + break; + case OB_LATTICE: + { + Lattice *lt= def_get_lattice(ob); + + if(lt->dvert) { + BPoint *bp; + int a, tot; + + dvert= lt->dvert; + + tot= lt->pntsu*lt->pntsv*lt->pntsw; + for(a=0, bp= lt->def; a<tot; a++, bp++, dvert++) { + for (i=0; i<dvert->totweight; i++){ + if (dvert->dw[i].def_nr == (ob->actdef-1)) { + if(select) bp->f1 |= SELECT; + else bp->f1 &= ~SELECT; + + break; + } + } + } + } + } + break; + + default: + break; + } +} + /* check if deform vertex has defgroup index */ -MDeformWeight *ED_vgroup_weight_get(MDeformVert *dv, int defgroup) +MDeformWeight *get_defweight (MDeformVert *dv, int defgroup) { int i; - if(!dv || defgroup<0) + if (!dv || defgroup<0) return NULL; - for(i=0; i<dv->totweight; i++) - if(dv->dw[i].def_nr == defgroup) + 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 */ +/* 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 *verify_defweight (MDeformVert *dv, int defgroup) { MDeformWeight *newdw; /* do this check always, this function is used to check for it */ - if(!dv || defgroup<0) + if (!dv || defgroup<0) return NULL; - newdw = ED_vgroup_weight_get(dv, defgroup); - if(newdw) + newdw = get_defweight (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); + 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; @@ -128,16 +201,16 @@ MDeformWeight *ED_vgroup_weight_verify(MDeformVert *dv, int defgroup) return dv->dw+(dv->totweight-1); } -bDeformGroup *ED_vgroup_add_name(Object *ob, char *name) +bDeformGroup *add_defgroup_name (Object *ob, char *name) { - bDeformGroup *defgroup; + bDeformGroup *defgroup; - if(!ob) + if (!ob) return NULL; - defgroup = MEM_callocN(sizeof(bDeformGroup), "add deformGroup"); + defgroup = MEM_callocN (sizeof(bDeformGroup), "add deformGroup"); - BLI_strncpy(defgroup->name, name, 32); + BLI_strncpy (defgroup->name, name, 32); BLI_addtail(&ob->defbase, defgroup); unique_vertexgroup_name(defgroup, ob); @@ -147,20 +220,306 @@ bDeformGroup *ED_vgroup_add_name(Object *ob, char *name) return defgroup; } -bDeformGroup *ED_vgroup_add(Object *ob) +void add_defgroup (Object *ob) +{ + add_defgroup_name (ob, "Group"); +} + + +void duplicate_defgroup ( Object *ob ) +{ + bDeformGroup *dg, *cdg; + char name[32], s[32]; + MDeformWeight *org, *cpy; + MDeformVert *dvert, *dvert_array=NULL; + int i, idg, icdg, dvert_tot=0; + + if (ob->type != OB_MESH && ob->type != OB_LATTICE) + return; + + dg = BLI_findlink (&ob->defbase, (ob->actdef-1)); + if (!dg) + return; + + if (strstr(dg->name, "_copy")) { + BLI_strncpy (name, dg->name, 32); /* will be renamed _copy.001... etc */ + } else { + BLI_snprintf (name, 32, "%s_copy", dg->name); + while (get_named_vertexgroup (ob, name)) { + if ((strlen (name) + 6) > 32) { + error ("Error: the name for the new group is > 32 characters"); + return; + } + strcpy (s, name); + BLI_snprintf (name, 32, "%s_copy", s); + } + } + + cdg = copy_defgroup (dg); + strcpy (cdg->name, name); + unique_vertexgroup_name(cdg, ob); + + BLI_addtail (&ob->defbase, cdg); + + idg = (ob->actdef-1); + ob->actdef = BLI_countlist (&ob->defbase); + icdg = (ob->actdef-1); + + if(ob->type == OB_MESH) { + Mesh *me = get_mesh (ob); + dvert_array= me->dvert; + dvert_tot= me->totvert; + } + else if (ob->type == OB_LATTICE) { + Lattice *lt= (Lattice *)ob->data; + dvert_array= lt->dvert; + dvert_tot= lt->pntsu*lt->pntsv*lt->pntsw; + } + + if (!dvert_array) + return; + + for (i = 0; i < dvert_tot; i++) { + dvert = dvert_array+i; + org = get_defweight (dvert, idg); + if (org) { + float weight = org->weight; + /* verify_defweight re-allocs org so need to store the weight first */ + cpy = verify_defweight (dvert, icdg); + cpy->weight = weight; + } + } +} + +static void del_defgroup_update_users(Object *ob, int id) +{ + ExplodeModifierData *emd; + ModifierData *md; + ParticleSystem *psys; + ClothModifierData *clmd; + ClothSimSettings *clsim; + int a; + + /* these cases don't use names to refer to vertex groups, so when + * they get deleted the numbers get out of sync, this corrects that */ + + if(ob->soft) { + if(ob->soft->vertgroup == id) + ob->soft->vertgroup= 0; + else if(ob->soft->vertgroup > id) + ob->soft->vertgroup--; + } + + for(md=ob->modifiers.first; md; md=md->next) { + if(md->type == eModifierType_Explode) { + emd= (ExplodeModifierData*)md; + + if(emd->vgroup == id) + emd->vgroup= 0; + else if(emd->vgroup > id) + emd->vgroup--; + } + else if(md->type == eModifierType_Cloth) { + clmd= (ClothModifierData*)md; + clsim= clmd->sim_parms; + + if(clsim) { + if(clsim->vgroup_mass == id) + clsim->vgroup_mass= 0; + else if(clsim->vgroup_mass > id) + clsim->vgroup_mass--; + + if(clsim->vgroup_bend == id) + clsim->vgroup_bend= 0; + else if(clsim->vgroup_bend > id) + clsim->vgroup_bend--; + + if(clsim->vgroup_struct == id) + clsim->vgroup_struct= 0; + else if(clsim->vgroup_struct > id) + clsim->vgroup_struct--; + } + } + } + + for(psys=ob->particlesystem.first; psys; psys=psys->next) { + for(a=0; a<PSYS_TOT_VG; a++) + if(psys->vgroup[a] == id) + psys->vgroup[a]= 0; + else if(psys->vgroup[a] > id) + psys->vgroup[a]--; + } +} + +void del_defgroup_in_object_mode ( Object *ob ) +{ + bDeformGroup *dg; + MDeformVert *dvert, *dvert_array=NULL; + int i, e, dvert_tot=0; + + if ((!ob) || (ob->type != OB_MESH && ob->type != OB_LATTICE)) + return; + + if(ob->type == OB_MESH) { + Mesh *me = get_mesh (ob); + dvert_array= me->dvert; + dvert_tot= me->totvert; + } + else if (ob->type == OB_LATTICE) { + Lattice *lt= (Lattice *)ob->data; + dvert_array= lt->dvert; + dvert_tot= lt->pntsu*lt->pntsv*lt->pntsw; + } + + dg = BLI_findlink (&ob->defbase, (ob->actdef-1)); + if (!dg) + return; + + if (dvert_array) { + for (i = 0; i < dvert_tot; i++) { + dvert = dvert_array + i; + if (dvert) { + if (get_defweight (dvert, (ob->actdef-1))) + remove_vert_defgroup (ob, dg, i); + } + } + + for (i = 0; i < dvert_tot; i++) { + dvert = dvert_array+i; + if (dvert) { + for (e = 0; e < dvert->totweight; e++) { + if (dvert->dw[e].def_nr > (ob->actdef-1)) + dvert->dw[e].def_nr--; + } + } + } + } + + del_defgroup_update_users(ob, ob->actdef); + + /* Update the active deform index if necessary */ + if (ob->actdef == BLI_countlist(&ob->defbase)) + ob->actdef--; + + /* Remove the group */ + BLI_freelinkN (&ob->defbase, dg); +} + +void del_defgroup (Object *ob) +{ + bDeformGroup *defgroup; + int i; + + if (!ob) + return; + + if (!ob->actdef) + return; + + defgroup = BLI_findlink(&ob->defbase, ob->actdef-1); + if (!defgroup) + return; + + /* Make sure that no verts are using this group */ + remove_verts_defgroup(ob, 1); + + /* Make sure that any verts with higher indices are adjusted accordingly */ + if(ob->type==OB_MESH) { + Mesh *me= ob->data; + EditMesh *em = BKE_mesh_get_editmesh(me); + EditVert *eve; + MDeformVert *dvert; + + for (eve=em->verts.first; eve; eve=eve->next){ + dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); + + if (dvert) + for (i=0; i<dvert->totweight; i++) + if (dvert->dw[i].def_nr > (ob->actdef-1)) + dvert->dw[i].def_nr--; + } + BKE_mesh_end_editmesh(me, em); + } + else if(ob->type==OB_LATTICE) { + Lattice *lt= def_get_lattice(ob); + BPoint *bp; + MDeformVert *dvert= lt->dvert; + int a, tot; + + if (dvert) { + tot= lt->pntsu*lt->pntsv*lt->pntsw; + for(a=0, bp= lt->def; a<tot; a++, bp++, dvert++) { + for (i=0; i<dvert->totweight; i++){ + if (dvert->dw[i].def_nr > (ob->actdef-1)) + dvert->dw[i].def_nr--; + } + } + } + } + + del_defgroup_update_users(ob, ob->actdef); + + /* Update the active deform index if necessary */ + if (ob->actdef==BLI_countlist(&ob->defbase)) + ob->actdef--; + + /* Remove the group */ + BLI_freelinkN (&ob->defbase, defgroup); + + /* remove all dverts */ + if(ob->actdef==0) { + if(ob->type==OB_MESH) { + Mesh *me= ob->data; + CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert); + me->dvert= NULL; + } + else if(ob->type==OB_LATTICE) { + Lattice *lt= def_get_lattice(ob); + if (lt->dvert) { + MEM_freeN(lt->dvert); + lt->dvert= NULL; + } + } + } +} + +void del_all_defgroups (Object *ob) { - return ED_vgroup_add_name(ob, "Group"); + /* Sanity check */ + if (ob == NULL) + return; + + /* Remove all DVerts */ + if (ob->type==OB_MESH) { + Mesh *me= ob->data; + CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert); + me->dvert= NULL; + } + else if(ob->type==OB_LATTICE) { + Lattice *lt= def_get_lattice(ob); + if (lt->dvert) { + MEM_freeN(lt->dvert); + lt->dvert= NULL; + } + } + + /* Remove all DefGroups */ + BLI_freelistN(&ob->defbase); + + /* Fix counters/indices */ + ob->actdef= 0; } -void ED_vgroup_data_create(ID *id) +void create_dverts(ID *id) { - /* create deform verts */ + /* create deform verts + */ - if(GS(id->name)==ID_ME) { + if( GS(id->name)==ID_ME) { Mesh *me= (Mesh *)id; me->dvert= CustomData_add_layer(&me->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, me->totvert); } - else if(GS(id->name)==ID_LT) { + else if( GS(id->name)==ID_LT) { Lattice *lt= (Lattice *)id; lt->dvert= MEM_callocN(sizeof(MDeformVert)*lt->pntsu*lt->pntsv*lt->pntsw, "lattice deformVert"); } @@ -168,7 +527,7 @@ void ED_vgroup_data_create(ID *id) /* for mesh in object mode lattice can be in editmode */ -void ED_vgroup_nr_vert_remove(Object *ob, int def_nr, int vertnum) +void remove_vert_def_nr (Object *ob, int def_nr, int vertnum) { /* This routine removes the vertex from the deform * group with number def_nr. @@ -188,11 +547,11 @@ void ED_vgroup_nr_vert_remove(Object *ob, int def_nr, int vertnum) * vertnum */ if(ob->type==OB_MESH) { - if(((Mesh*)ob->data)->dvert) + if( ((Mesh*)ob->data)->dvert ) dvert = ((Mesh*)ob->data)->dvert + vertnum; } else if(ob->type==OB_LATTICE) { - Lattice *lt= vgroup_edit_lattice(ob); + Lattice *lt= def_get_lattice(ob); if(lt->dvert) dvert = lt->dvert + vertnum; @@ -204,27 +563,27 @@ void ED_vgroup_nr_vert_remove(Object *ob, int def_nr, int vertnum) /* for all of the deform weights in the * deform vert */ - for(i=dvert->totweight - 1 ; i>=0 ; i--){ + for (i=dvert->totweight - 1 ; i>=0 ; i--){ /* if the def_nr is the same as the one * for our weight group then remove it * from this deform vert. */ - if(dvert->dw[i].def_nr == def_nr) { + if (dvert->dw[i].def_nr == def_nr) { dvert->totweight--; /* if there are still other deform weights * attached to this vert then remove this * deform weight, and reshuffle the others */ - if(dvert->totweight) { - newdw = MEM_mallocN(sizeof(MDeformWeight)*(dvert->totweight), + if (dvert->totweight) { + newdw = MEM_mallocN (sizeof(MDeformWeight)*(dvert->totweight), "deformWeight"); - if(dvert->dw){ - memcpy(newdw, dvert->dw, sizeof(MDeformWeight)*i); - memcpy(newdw+i, dvert->dw+i+1, + if (dvert->dw){ + memcpy (newdw, dvert->dw, sizeof(MDeformWeight)*i); + memcpy (newdw+i, dvert->dw+i+1, sizeof(MDeformWeight)*(dvert->totweight-i)); - MEM_freeN(dvert->dw); + MEM_freeN (dvert->dw); } dvert->dw=newdw; } @@ -232,7 +591,7 @@ void ED_vgroup_nr_vert_remove(Object *ob, int def_nr, int vertnum) * left then just remove the deform weight */ else { - MEM_freeN(dvert->dw); + MEM_freeN (dvert->dw); dvert->dw = NULL; break; } @@ -243,7 +602,8 @@ void ED_vgroup_nr_vert_remove(Object *ob, int def_nr, int vertnum) /* for Mesh in Object mode */ /* allows editmode for Lattice */ -void ED_vgroup_nr_vert_add(Object *ob, int def_nr, int vertnum, float weight, int assignmode) +void add_vert_defnr (Object *ob, int def_nr, int vertnum, + float weight, int assignmode) { /* add the vert to the deform group with the * specified number @@ -258,7 +618,7 @@ void ED_vgroup_nr_vert_add(Object *ob, int def_nr, int vertnum, float weight, in dv = ((Mesh*)ob->data)->dvert + vertnum; } else if(ob->type==OB_LATTICE) { - Lattice *lt= vgroup_edit_lattice(ob); + Lattice *lt= def_get_lattice(ob); if(lt->dvert) dv = lt->dvert + vertnum; @@ -271,21 +631,21 @@ void ED_vgroup_nr_vert_add(Object *ob, int def_nr, int vertnum, float weight, in * already in the weight group -- if so * lets update it */ - for(i=0; i<dv->totweight; i++){ + for (i=0; i<dv->totweight; i++){ /* if this weight cooresponds to the * deform group, then add it using * the assign mode provided */ - if(dv->dw[i].def_nr == def_nr){ + if (dv->dw[i].def_nr == def_nr){ - switch(assignmode) { + switch (assignmode) { case WEIGHT_REPLACE: dv->dw[i].weight=weight; break; case WEIGHT_ADD: dv->dw[i].weight+=weight; - if(dv->dw[i].weight >= 1.0) + if (dv->dw[i].weight >= 1.0) dv->dw[i].weight = 1.0; break; case WEIGHT_SUBTRACT: @@ -293,8 +653,8 @@ void ED_vgroup_nr_vert_add(Object *ob, int def_nr, int vertnum, float weight, in /* if the weight is zero or less then * remove the vert from the deform group */ - if(dv->dw[i].weight <= 0.0) - ED_vgroup_nr_vert_remove(ob, def_nr, vertnum); + if (dv->dw[i].weight <= 0.0) + remove_vert_def_nr(ob, def_nr, vertnum); break; } return; @@ -305,7 +665,7 @@ void ED_vgroup_nr_vert_add(Object *ob, int def_nr, int vertnum, float weight, in * we must take a different form of action ... */ - switch(assignmode) { + switch (assignmode) { case WEIGHT_SUBTRACT: /* if we are subtracting then we don't * need to do anything @@ -317,11 +677,11 @@ void ED_vgroup_nr_vert_add(Object *ob, int def_nr, int vertnum, float weight, in /* if we are doing an additive assignment, then * we need to create the deform weight */ - newdw = MEM_callocN(sizeof(MDeformWeight)*(dv->totweight+1), + newdw = MEM_callocN (sizeof(MDeformWeight)*(dv->totweight+1), "deformWeight"); - if(dv->dw){ - memcpy(newdw, dv->dw, sizeof(MDeformWeight)*dv->totweight); - MEM_freeN(dv->dw); + if (dv->dw){ + memcpy (newdw, dv->dw, sizeof(MDeformWeight)*dv->totweight); + MEM_freeN (dv->dw); } dv->dw=newdw; @@ -334,7 +694,8 @@ void ED_vgroup_nr_vert_add(Object *ob, int def_nr, int vertnum, float weight, in } /* called while not in editmode */ -void ED_vgroup_vert_add(Object *ob, bDeformGroup *dg, int vertnum, float weight, int assignmode) +void add_vert_to_defgroup (Object *ob, bDeformGroup *dg, int vertnum, + float weight, int assignmode) { /* add the vert to the deform group with the * specified assign mode @@ -345,27 +706,115 @@ void ED_vgroup_vert_add(Object *ob, bDeformGroup *dg, int vertnum, float weight, * it can't be found */ def_nr = get_defgroup_num(ob, dg); - if(def_nr < 0) return; + if (def_nr < 0) return; /* if there's no deform verts then * create some */ if(ob->type==OB_MESH) { - if(!((Mesh*)ob->data)->dvert) - ED_vgroup_data_create(ob->data); + if (!((Mesh*)ob->data)->dvert) + create_dverts(ob->data); } else if(ob->type==OB_LATTICE) { - if(!((Lattice*)ob->data)->dvert) - ED_vgroup_data_create(ob->data); + if (!((Lattice*)ob->data)->dvert) + create_dverts(ob->data); } /* call another function to do the work */ - ED_vgroup_nr_vert_add(ob, def_nr, vertnum, weight, assignmode); + add_vert_defnr (ob, def_nr, vertnum, weight, assignmode); +} + +/* Only available in editmode */ +void assign_verts_defgroup (Object *ob, float weight) +{ + EditVert *eve; + bDeformGroup *dg, *eg; + MDeformWeight *newdw; + MDeformVert *dvert; + int i, done; + + if (!ob) + return; + + dg=BLI_findlink(&ob->defbase, ob->actdef-1); + if (!dg){ + error ("No vertex group is active"); + return; + } + + switch (ob->type){ + case OB_MESH: + { + Mesh *me= ob->data; + EditMesh *em = BKE_mesh_get_editmesh(me); + + if (!CustomData_has_layer(&em->vdata, CD_MDEFORMVERT)) + EM_add_data_layer(em, &em->vdata, CD_MDEFORMVERT); + + /* Go through the list of editverts and assign them */ + for (eve=em->verts.first; eve; eve=eve->next){ + dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); + + if (dvert && (eve->f & 1)){ + done=0; + /* See if this vert already has a reference to this group */ + /* If so: Change its weight */ + done=0; + for (i=0; i<dvert->totweight; i++){ + eg = BLI_findlink (&ob->defbase, dvert->dw[i].def_nr); + /* Find the actual group */ + if (eg==dg){ + dvert->dw[i].weight= weight; + done=1; + break; + } + } + /* If not: Add the group and set its weight */ + if (!done){ + newdw = MEM_callocN (sizeof(MDeformWeight)*(dvert->totweight+1), "deformWeight"); + if (dvert->dw){ + memcpy (newdw, dvert->dw, sizeof(MDeformWeight)*dvert->totweight); + MEM_freeN (dvert->dw); + } + dvert->dw=newdw; + + dvert->dw[dvert->totweight].weight= weight; + dvert->dw[dvert->totweight].def_nr= ob->actdef-1; + + dvert->totweight++; + + } + } + } + BKE_mesh_end_editmesh(me, em); + } + break; + case OB_LATTICE: + { + Lattice *lt= def_get_lattice(ob); + BPoint *bp; + int a, tot; + + if(lt->dvert==NULL) + create_dverts(<->id); + + tot= lt->pntsu*lt->pntsv*lt->pntsw; + for(a=0, bp= lt->def; a<tot; a++, bp++) { + if(bp->f1 & SELECT) + add_vert_defnr (ob, ob->actdef-1, a, weight, WEIGHT_REPLACE); + } + } + break; + default: + printf ("Assigning deformation groups to unknown object type\n"); + break; + } + } /* mesh object mode, lattice can be in editmode */ -void ED_vgroup_vert_remove(Object *ob, bDeformGroup *dg, int vertnum) +void remove_vert_defgroup (Object *ob, bDeformGroup *dg, int vertnum) { /* This routine removes the vertex from the specified * deform group. @@ -375,7 +824,7 @@ void ED_vgroup_vert_remove(Object *ob, bDeformGroup *dg, int vertnum) /* if the object is NULL abort */ - if(!ob) + if (!ob) return; /* get the deform number that cooresponds @@ -383,34 +832,28 @@ void ED_vgroup_vert_remove(Object *ob, bDeformGroup *dg, int vertnum) * can not be found. */ def_nr = get_defgroup_num(ob, dg); - if(def_nr < 0) return; + if (def_nr < 0) return; /* call another routine to do the work */ - ED_vgroup_nr_vert_remove(ob, def_nr, vertnum); + remove_vert_def_nr (ob, def_nr, vertnum); } -static float get_vert_def_nr(Object *ob, int def_nr, int vertnum) +/* for mesh in object mode lattice can be in editmode */ +static float get_vert_def_nr (Object *ob, int def_nr, int vertnum) { MDeformVert *dvert= NULL; - EditVert *eve; - Mesh *me; int i; - /* get the deform vertices corresponding to the vertnum */ + /* get the deform vertices corresponding to the + * vertnum + */ if(ob->type==OB_MESH) { - me= ob->data; - - if(me->edit_mesh) { - eve= BLI_findlink(&me->edit_mesh->verts, vertnum); - if(!eve) return 0.0f; - dvert= CustomData_em_get(&me->edit_mesh->vdata, eve->data, CD_MDEFORMVERT); - } - else - dvert = me->dvert + vertnum; + if( ((Mesh*)ob->data)->dvert ) + dvert = ((Mesh*)ob->data)->dvert + vertnum; } else if(ob->type==OB_LATTICE) { - Lattice *lt= vgroup_edit_lattice(ob); + Lattice *lt= def_get_lattice(ob); if(lt->dvert) dvert = lt->dvert + vertnum; @@ -426,267 +869,23 @@ static float get_vert_def_nr(Object *ob, int def_nr, int vertnum) return 0.0f; } -float ED_vgroup_vert_weight(Object *ob, bDeformGroup *dg, int vertnum) +/* mesh object mode, lattice can be in editmode */ +float get_vert_defgroup (Object *ob, bDeformGroup *dg, int vertnum) { int def_nr; - if(!ob) return 0.0f; + if(!ob) + return 0.0f; def_nr = get_defgroup_num(ob, dg); if(def_nr < 0) return 0.0f; - return get_vert_def_nr(ob, def_nr, vertnum); -} - -void ED_vgroup_select_by_name(Object *ob, char *name) -{ - bDeformGroup *curdef; - int actdef= 1; - - for(curdef = ob->defbase.first; curdef; curdef=curdef->next, actdef++){ - if(!strcmp(curdef->name, name)) { - ob->actdef= actdef; - return; - } - } - - ob->actdef=0; // this signals on painting to create a new one, if a bone in posemode is selected */ -} - -/********************** Operator Implementations *********************/ - -/* only in editmode */ -static void vgroup_select_verts(Object *ob, int select) -{ - EditVert *eve; - MDeformVert *dvert; - int i; - - if(ob->type == OB_MESH) { - Mesh *me= ob->data; - EditMesh *em = BKE_mesh_get_editmesh(me); - - for(eve=em->verts.first; eve; eve=eve->next){ - dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); - - if(dvert && dvert->totweight){ - for(i=0; i<dvert->totweight; i++){ - if(dvert->dw[i].def_nr == (ob->actdef-1)){ - if(select) eve->f |= SELECT; - else eve->f &= ~SELECT; - - break; - } - } - } - } - /* this has to be called, because this function operates on vertices only */ - if(select) EM_select_flush(em); // vertices to edges/faces - else EM_deselect_flush(em); - - BKE_mesh_end_editmesh(me, em); - } - else if(ob->type == OB_LATTICE) { - Lattice *lt= vgroup_edit_lattice(ob); - - if(lt->dvert) { - BPoint *bp; - int a, tot; - - dvert= lt->dvert; - - tot= lt->pntsu*lt->pntsv*lt->pntsw; - for(a=0, bp= lt->def; a<tot; a++, bp++, dvert++) { - for(i=0; i<dvert->totweight; i++){ - if(dvert->dw[i].def_nr == (ob->actdef-1)) { - if(select) bp->f1 |= SELECT; - else bp->f1 &= ~SELECT; - - break; - } - } - } - } - } -} - -static void vgroup_duplicate(Object *ob) -{ - bDeformGroup *dg, *cdg; - char name[32], s[32]; - MDeformWeight *org, *cpy; - MDeformVert *dvert, *dvert_array=NULL; - int i, idg, icdg, dvert_tot=0; - - dg = BLI_findlink(&ob->defbase, (ob->actdef-1)); - if(!dg) - return; - - if(strstr(dg->name, "_copy")) { - BLI_strncpy(name, dg->name, 32); /* will be renamed _copy.001... etc */ - } - else { - BLI_snprintf(name, 32, "%s_copy", dg->name); - while(get_named_vertexgroup(ob, name)) { - if((strlen(name) + 6) > 32) { - printf("Internal error: the name for the new vertex group is > 32 characters"); - return; - } - strcpy(s, name); - BLI_snprintf(name, 32, "%s_copy", s); - } - } - - cdg = copy_defgroup(dg); - strcpy(cdg->name, name); - unique_vertexgroup_name(cdg, ob); - - BLI_addtail(&ob->defbase, cdg); - - idg = (ob->actdef-1); - ob->actdef = BLI_countlist(&ob->defbase); - icdg = (ob->actdef-1); - - if(ob->type == OB_MESH) { - Mesh *me = get_mesh(ob); - dvert_array= me->dvert; - dvert_tot= me->totvert; - } - else if(ob->type == OB_LATTICE) { - Lattice *lt= (Lattice *)ob->data; - dvert_array= lt->dvert; - dvert_tot= lt->pntsu*lt->pntsv*lt->pntsw; - } - - if(!dvert_array) - return; - - for(i = 0; i < dvert_tot; i++) { - dvert = dvert_array+i; - org = ED_vgroup_weight_get(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); - cpy->weight = weight; - } - } -} - -static void vgroup_delete_update_users(Object *ob, int id) -{ - ExplodeModifierData *emd; - ModifierData *md; - ParticleSystem *psys; - ClothModifierData *clmd; - ClothSimSettings *clsim; - int a; - - /* these cases don't use names to refer to vertex groups, so when - * they get deleted the numbers get out of sync, this corrects that */ - - if(ob->soft) { - if(ob->soft->vertgroup == id) - ob->soft->vertgroup= 0; - else if(ob->soft->vertgroup > id) - ob->soft->vertgroup--; - } - - for(md=ob->modifiers.first; md; md=md->next) { - if(md->type == eModifierType_Explode) { - emd= (ExplodeModifierData*)md; - - if(emd->vgroup == id) - emd->vgroup= 0; - else if(emd->vgroup > id) - emd->vgroup--; - } - else if(md->type == eModifierType_Cloth) { - clmd= (ClothModifierData*)md; - clsim= clmd->sim_parms; - - if(clsim) { - if(clsim->vgroup_mass == id) - clsim->vgroup_mass= 0; - else if(clsim->vgroup_mass > id) - clsim->vgroup_mass--; - - if(clsim->vgroup_bend == id) - clsim->vgroup_bend= 0; - else if(clsim->vgroup_bend > id) - clsim->vgroup_bend--; - - if(clsim->vgroup_struct == id) - clsim->vgroup_struct= 0; - else if(clsim->vgroup_struct > id) - clsim->vgroup_struct--; - } - } - } - - for(psys=ob->particlesystem.first; psys; psys=psys->next) { - for(a=0; a<PSYS_TOT_VG; a++) - if(psys->vgroup[a] == id) - psys->vgroup[a]= 0; - else if(psys->vgroup[a] > id) - psys->vgroup[a]--; - } + return get_vert_def_nr (ob, def_nr, vertnum); } -static void vgroup_delete_object_mode(Object *ob) -{ - bDeformGroup *dg; - MDeformVert *dvert, *dvert_array=NULL; - int i, e, dvert_tot=0; - - if(ob->type == OB_MESH) { - Mesh *me = get_mesh(ob); - dvert_array= me->dvert; - dvert_tot= me->totvert; - } - else if(ob->type == OB_LATTICE) { - Lattice *lt= (Lattice *)ob->data; - dvert_array= lt->dvert; - dvert_tot= lt->pntsu*lt->pntsv*lt->pntsw; - } - - dg = BLI_findlink(&ob->defbase, (ob->actdef-1)); - if(!dg) - return; - - if(dvert_array) { - for(i = 0; i < dvert_tot; i++) { - dvert = dvert_array + i; - if(dvert) { - if(ED_vgroup_weight_get(dvert, (ob->actdef-1))) - ED_vgroup_vert_remove(ob, dg, i); - } - } - - for(i = 0; i < dvert_tot; i++) { - dvert = dvert_array+i; - if(dvert) { - for(e = 0; e < dvert->totweight; e++) { - if(dvert->dw[e].def_nr > (ob->actdef-1)) - dvert->dw[e].def_nr--; - } - } - } - } - - vgroup_delete_update_users(ob, ob->actdef); - - /* Update the active deform index if necessary */ - if(ob->actdef == BLI_countlist(&ob->defbase)) - ob->actdef--; - - /* Remove the group */ - BLI_freelinkN(&ob->defbase, dg); -} - -/* only in editmode */ +/* Only available in editmode */ /* removes from active defgroup, if allverts==0 only selected vertices */ -static void vgroup_active_remove_verts(Object *ob, int allverts) +void remove_verts_defgroup (Object *ob, int allverts) { EditVert *eve; MDeformVert *dvert; @@ -694,35 +893,42 @@ static void vgroup_active_remove_verts(Object *ob, int allverts) bDeformGroup *dg, *eg; int i; + if (!ob) + return; + dg=BLI_findlink(&ob->defbase, ob->actdef-1); - if(!dg) + if (!dg){ + error ("No vertex group is active"); return; + } - if(ob->type == OB_MESH) { + switch (ob->type){ + case OB_MESH: + { Mesh *me= ob->data; EditMesh *em = BKE_mesh_get_editmesh(me); - for(eve=em->verts.first; eve; eve=eve->next){ + for (eve=em->verts.first; eve; eve=eve->next){ dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); - if(dvert && dvert->dw && ((eve->f & 1) || allverts)){ - for(i=0; i<dvert->totweight; i++){ + if (dvert && dvert->dw && ((eve->f & 1) || allverts)){ + for (i=0; i<dvert->totweight; i++){ /* Find group */ - eg = BLI_findlink(&ob->defbase, dvert->dw[i].def_nr); - if(eg == dg){ + eg = BLI_findlink (&ob->defbase, dvert->dw[i].def_nr); + if (eg == dg){ dvert->totweight--; - if(dvert->totweight){ - newdw = MEM_mallocN(sizeof(MDeformWeight)*(dvert->totweight), "deformWeight"); + if (dvert->totweight){ + newdw = MEM_mallocN (sizeof(MDeformWeight)*(dvert->totweight), "deformWeight"); - if(dvert->dw){ - memcpy(newdw, dvert->dw, sizeof(MDeformWeight)*i); - memcpy(newdw+i, dvert->dw+i+1, sizeof(MDeformWeight)*(dvert->totweight-i)); - MEM_freeN(dvert->dw); + if (dvert->dw){ + memcpy (newdw, dvert->dw, sizeof(MDeformWeight)*i); + memcpy (newdw+i, dvert->dw+i+1, sizeof(MDeformWeight)*(dvert->totweight-i)); + MEM_freeN (dvert->dw); } dvert->dw=newdw; } else{ - MEM_freeN(dvert->dw); + MEM_freeN (dvert->dw); dvert->dw=NULL; break; } @@ -732,8 +938,10 @@ static void vgroup_active_remove_verts(Object *ob, int allverts) } BKE_mesh_end_editmesh(me, em); } - else if(ob->type == OB_LATTICE) { - Lattice *lt= vgroup_edit_lattice(ob); + break; + case OB_LATTICE: + { + Lattice *lt= def_get_lattice(ob); if(lt->dvert) { BPoint *bp; @@ -741,249 +949,170 @@ static void vgroup_active_remove_verts(Object *ob, int allverts) for(a=0, bp= lt->def; a<tot; a++, bp++) { if(allverts || (bp->f1 & SELECT)) - ED_vgroup_vert_remove(ob, dg, a); + remove_vert_defgroup (ob, dg, a); } } } + break; + + default: + printf ("Removing deformation groups from unknown object type\n"); + break; + } } -static void vgroup_delete_edit_mode(Object *ob) +/* Only available in editmode */ +/* removes from all defgroup, if allverts==0 only selected vertices */ +void remove_verts_defgroups(Object *ob, int allverts) { - bDeformGroup *defgroup; - int i; - - if(!ob->actdef) - return; + int actdef, defCount; - defgroup = BLI_findlink(&ob->defbase, ob->actdef-1); - if(!defgroup) + if (ob == NULL) return; + + actdef= ob->actdef; + defCount= BLI_countlist(&ob->defbase); + + if (defCount == 0) { + error("Object has no vertex groups"); return; - - /* Make sure that no verts are using this group */ - vgroup_active_remove_verts(ob, 1); - - /* Make sure that any verts with higher indices are adjusted accordingly */ - if(ob->type==OB_MESH) { - Mesh *me= ob->data; - EditMesh *em = BKE_mesh_get_editmesh(me); - EditVert *eve; - MDeformVert *dvert; - - for(eve=em->verts.first; eve; eve=eve->next){ - dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); - - if(dvert) - for(i=0; i<dvert->totweight; i++) - if(dvert->dw[i].def_nr > (ob->actdef-1)) - dvert->dw[i].def_nr--; - } - BKE_mesh_end_editmesh(me, em); } - else if(ob->type==OB_LATTICE) { - Lattice *lt= vgroup_edit_lattice(ob); - BPoint *bp; - MDeformVert *dvert= lt->dvert; - int a, tot; + + /* To prevent code redundancy, we just use remove_verts_defgroup, but that + * only operates on the active vgroup. So we iterate through all groups, by changing + * active group index + */ + for (ob->actdef= 1; ob->actdef <= defCount; ob->actdef++) + remove_verts_defgroup(ob, allverts); - if(dvert) { - tot= lt->pntsu*lt->pntsv*lt->pntsw; - for(a=0, bp= lt->def; a<tot; a++, bp++, dvert++) { - for(i=0; i<dvert->totweight; i++){ - if(dvert->dw[i].def_nr > (ob->actdef-1)) - dvert->dw[i].def_nr--; - } - } - } - } - - vgroup_delete_update_users(ob, ob->actdef); + ob->actdef= actdef; +} - /* Update the active deform index if necessary */ - if(ob->actdef==BLI_countlist(&ob->defbase)) - ob->actdef--; +void vertexgroup_select_by_name(Object *ob, char *name) +{ + bDeformGroup *curdef; + int actdef= 1; - /* Remove the group */ - BLI_freelinkN (&ob->defbase, defgroup); + if(ob==NULL) return; - /* remove all dverts */ - if(ob->actdef==0) { - if(ob->type==OB_MESH) { - Mesh *me= ob->data; - CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert); - me->dvert= NULL; - } - else if(ob->type==OB_LATTICE) { - Lattice *lt= vgroup_edit_lattice(ob); - if(lt->dvert) { - MEM_freeN(lt->dvert); - lt->dvert= NULL; - } + for (curdef = ob->defbase.first; curdef; curdef=curdef->next, actdef++){ + if (!strcmp(curdef->name, name)) { + ob->actdef= actdef; + return; } } + ob->actdef=0; // this signals on painting to create a new one, if a bone in posemode is selected */ } -static int vgroup_object_in_edit_mode(Object *ob) +/* This function provides a shortcut for adding/removing verts from + * vertex groups. It is called by the Ctrl-G hotkey in EditMode for Meshes + * and Lattices. (currently only restricted to those two) + * It is only responsible for + */ +void vgroup_assign_with_menu(Scene *scene, Object *ob) { - if(ob->type == OB_MESH) - return (((Mesh*)ob->data)->edit_mesh != NULL); - else if(ob->type == OB_LATTICE) - return (((Lattice*)ob->data)->editlatt != NULL); + VPaint *wp= scene->toolsettings->wpaint; + int defCount; + int mode= 0; - return 0; -} - -static void vgroup_delete(Object *ob) -{ - if(vgroup_object_in_edit_mode(ob)) - vgroup_delete_edit_mode(ob); - else - vgroup_delete_object_mode(ob); -} - -static void vgroup_delete_all(Object *ob) -{ - /* Remove all DVerts */ - if(ob->type==OB_MESH) { - Mesh *me= ob->data; - CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert); - me->dvert= NULL; - } - else if(ob->type==OB_LATTICE) { - Lattice *lt= vgroup_edit_lattice(ob); - if(lt->dvert) { - MEM_freeN(lt->dvert); - lt->dvert= NULL; - } - } + /* prevent crashes */ + if (wp==NULL || ob==NULL) return; - /* Remove all DefGroups */ - BLI_freelistN(&ob->defbase); + defCount= BLI_countlist(&ob->defbase); - /* Fix counters/indices */ - ob->actdef= 0; -} - -/* only in editmode */ -static void vgroup_assign_verts(Object *ob, float weight) -{ - EditVert *eve; - bDeformGroup *dg, *eg; - MDeformWeight *newdw; - MDeformVert *dvert; - int i, done; - - dg=BLI_findlink(&ob->defbase, ob->actdef-1); - - if(ob->type == OB_MESH) { - Mesh *me= ob->data; - EditMesh *em = BKE_mesh_get_editmesh(me); - - if(!CustomData_has_layer(&em->vdata, CD_MDEFORMVERT)) - EM_add_data_layer(em, &em->vdata, CD_MDEFORMVERT); - - /* Go through the list of editverts and assign them */ - for(eve=em->verts.first; eve; eve=eve->next){ - dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); - - if(dvert && (eve->f & 1)){ - done=0; - /* See if this vert already has a reference to this group */ - /* If so: Change its weight */ - done=0; - for(i=0; i<dvert->totweight; i++){ - eg = BLI_findlink(&ob->defbase, dvert->dw[i].def_nr); - /* Find the actual group */ - if(eg==dg){ - dvert->dw[i].weight= weight; - done=1; - break; - } - } - /* If not: Add the group and set its weight */ - if(!done){ - newdw = MEM_callocN(sizeof(MDeformWeight)*(dvert->totweight+1), "deformWeight"); - if(dvert->dw){ - memcpy(newdw, dvert->dw, sizeof(MDeformWeight)*dvert->totweight); - MEM_freeN(dvert->dw); - } - dvert->dw=newdw; - - dvert->dw[dvert->totweight].weight= weight; - dvert->dw[dvert->totweight].def_nr= ob->actdef-1; - - dvert->totweight++; - - } - } - } - BKE_mesh_end_editmesh(me, em); - } - else if(ob->type == OB_LATTICE) { - Lattice *lt= vgroup_edit_lattice(ob); - BPoint *bp; - int a, tot; - - if(lt->dvert==NULL) - ED_vgroup_data_create(<->id); - - tot= lt->pntsu*lt->pntsv*lt->pntsw; - for(a=0, bp= lt->def; a<tot; a++, bp++) { - if(bp->f1 & SELECT) - ED_vgroup_nr_vert_add(ob, ob->actdef-1, a, weight, WEIGHT_REPLACE); - } + /* give user choices of adding to current/new or removing from current */ +// XXX if (defCount && ob->actdef) +// mode = pupmenu("Vertex Groups %t|Add Selected to New Group %x1|Add Selected to Active Group %x2|Remove Selected from Active Group %x3|Remove Selected from All Groups %x4"); +// else +// mode= pupmenu("Vertex Groups %t|Add Selected to New Group %x1"); + + /* handle choices */ + switch (mode) { + case 1: /* add to new group */ + add_defgroup(ob); + assign_verts_defgroup(ob, paint_brush(&wp->paint)->alpha); + BIF_undo_push("Assign to vertex group"); + break; + case 2: /* add to current group */ + assign_verts_defgroup(ob, paint_brush(&wp->paint)->alpha); + BIF_undo_push("Assign to vertex group"); + break; + case 3: /* remove from current group */ + remove_verts_defgroup(ob, 0); + BIF_undo_push("Remove from vertex group"); + break; + case 4: /* remove from all groups */ + remove_verts_defgroups(ob, 0); + BIF_undo_push("Remove from all vertex groups"); + break; } } -/* only in editmode */ -/* removes from all defgroup, if allverts==0 only selected vertices */ -static void vgroup_remove_verts(Object *ob, int allverts) +/* This function provides a shortcut for commonly used vertex group + * functions - change weight (not implemented), change active group, delete active group, + * when Ctrl-Shift-G is used in EditMode, for Meshes and Lattices (only for now). + */ +void vgroup_operation_with_menu(Object *ob) { - int actdef, defCount; + int defCount; + int mode= 0; + + /* prevent crashes and useless cases */ + if (ob==NULL) return; - actdef= ob->actdef; defCount= BLI_countlist(&ob->defbase); + if (defCount == 0) return; - if(defCount == 0) - return; + /* give user choices of adding to current/new or removing from current */ +// XXX if (ob->actdef) +// mode = pupmenu("Vertex Groups %t|Change Active Group%x1|Delete Active Group%x2|Delete All Groups%x3"); +// else +// mode= pupmenu("Vertex Groups %t|Change Active Group%x1|Delete All Groups%x3"); - /* To prevent code redundancy, we just use vgroup_active_remove_verts, but that - * only operates on the active vgroup. So we iterate through all groups, by changing - * active group index - */ - for(ob->actdef= 1; ob->actdef <= defCount; ob->actdef++) - vgroup_active_remove_verts(ob, allverts); - - ob->actdef= actdef; + /* handle choices */ + switch (mode) { + case 1: /* change active group*/ + { + char *menustr= NULL; // XXX get_vertexgroup_menustr(ob); + short nr; + + if (menustr) { +// XXX nr= pupmenu(menustr); + + if ((nr >= 1) && (nr <= defCount)) + ob->actdef= nr; + + MEM_freeN(menustr); + } + } + break; + case 2: /* delete active group */ + { + del_defgroup(ob); + BIF_undo_push("Delete vertex group"); + } + break; + case 3: /* delete all groups */ + { + del_all_defgroups(ob); + BIF_undo_push("Delete all vertex groups"); + } + break; + } } /********************** vertex group operators *********************/ -static int vertex_group_poll(bContext *C) -{ - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; - ID *data= (ob)? ob->data: NULL; - return (ob && !ob->id.lib && ELEM(ob->type, OB_MESH, OB_LATTICE) && data && !data->lib); -} - -static int vertex_group_poll_edit(bContext *C) -{ - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; - ID *data= (ob)? ob->data: NULL; - - if(!(ob && !ob->id.lib && data && !data->lib)) - return 0; - - return vgroup_object_in_edit_mode(ob); -} - static int vertex_group_add_exec(bContext *C, wmOperator *op) { Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Scene *scene= CTX_data_scene(C); - ED_vgroup_add(ob); - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data); - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); + if(!ob) + return OPERATOR_CANCELLED; + + add_defgroup(ob); + DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob); return OPERATOR_FINISHED; } @@ -995,7 +1124,6 @@ void OBJECT_OT_vertex_group_add(wmOperatorType *ot) ot->idname= "OBJECT_OT_vertex_group_add"; /* api callbacks */ - ot->poll= vertex_group_poll; ot->exec= vertex_group_add_exec; /* flags */ @@ -1005,15 +1133,20 @@ void OBJECT_OT_vertex_group_add(wmOperatorType *ot) static int vertex_group_remove_exec(bContext *C, wmOperator *op) { Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + Scene *scene= CTX_data_scene(C); - if(RNA_boolean_get(op->ptr, "all")) - vgroup_delete_all(ob); - else - vgroup_delete(ob); + if(!ob) + return OPERATOR_CANCELLED; - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data); - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); + if(scene->obedit == ob) { + del_defgroup(ob); + WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob); + } + else { + del_defgroup_in_object_mode(ob); + DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob); + } return OPERATOR_FINISHED; } @@ -1025,27 +1158,24 @@ void OBJECT_OT_vertex_group_remove(wmOperatorType *ot) ot->idname= "OBJECT_OT_vertex_group_remove"; /* api callbacks */ - ot->poll= vertex_group_poll; ot->exec= vertex_group_remove_exec; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - /* properties */ - RNA_def_boolean(ot->srna, "all", 0, "All", "Remove from all vertex groups."); } static int vertex_group_assign_exec(bContext *C, wmOperator *op) { + Scene *scene= CTX_data_scene(C); ToolSettings *ts= CTX_data_tool_settings(C); Object *ob= CTX_data_edit_object(C); - if(RNA_boolean_get(op->ptr, "new")) - ED_vgroup_add(ob); + if(!ob) + return OPERATOR_CANCELLED; - vgroup_assign_verts(ob, ts->vgroup_weight); - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data); + assign_verts_defgroup(ob, ts->vgroup_weight); + DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob); return OPERATOR_FINISHED; } @@ -1057,24 +1187,24 @@ void OBJECT_OT_vertex_group_assign(wmOperatorType *ot) ot->idname= "OBJECT_OT_vertex_group_assign"; /* api callbacks */ - ot->poll= vertex_group_poll_edit; ot->exec= vertex_group_assign_exec; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - /* properties */ - RNA_def_boolean(ot->srna, "new", 0, "New", "Assign vertex to new vertex group."); } static int vertex_group_remove_from_exec(bContext *C, wmOperator *op) { + Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_edit_object(C); - vgroup_remove_verts(ob, 0); - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data); + if(!ob) + return OPERATOR_CANCELLED; + remove_verts_defgroup(ob, 0); + DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob); + return OPERATOR_FINISHED; } @@ -1083,27 +1213,23 @@ void OBJECT_OT_vertex_group_remove_from(wmOperatorType *ot) /* identifiers */ ot->name= "Remove from Vertex Group"; ot->idname= "OBJECT_OT_vertex_group_remove_from"; - + /* api callbacks */ - ot->poll= vertex_group_poll_edit; ot->exec= vertex_group_remove_from_exec; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - /* properties */ - RNA_def_boolean(ot->srna, "all", 0, "All", "Remove from all vertex groups."); } static int vertex_group_select_exec(bContext *C, wmOperator *op) { Object *ob= CTX_data_edit_object(C); - if(!ob || ob->id.lib) + if(!ob) return OPERATOR_CANCELLED; - vgroup_select_verts(ob, 1); - WM_event_add_notifier(C, NC_GEOM|ND_SELECT, ob->data); + sel_verts_defgroup(ob, 1); /* runs countall() */ + WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, ob); return OPERATOR_FINISHED; } @@ -1113,9 +1239,8 @@ void OBJECT_OT_vertex_group_select(wmOperatorType *ot) /* identifiers */ ot->name= "Select Vertex Group"; ot->idname= "OBJECT_OT_vertex_group_select"; - + /* api callbacks */ - ot->poll= vertex_group_poll_edit; ot->exec= vertex_group_select_exec; /* flags */ @@ -1126,8 +1251,11 @@ static int vertex_group_deselect_exec(bContext *C, wmOperator *op) { Object *ob= CTX_data_edit_object(C); - vgroup_select_verts(ob, 0); - WM_event_add_notifier(C, NC_GEOM|ND_SELECT, ob->data); + if(!ob) + return OPERATOR_CANCELLED; + + sel_verts_defgroup(ob, 0); /* runs countall() */ + WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, ob); return OPERATOR_FINISHED; } @@ -1137,9 +1265,8 @@ void OBJECT_OT_vertex_group_deselect(wmOperatorType *ot) /* identifiers */ ot->name= "Deselect Vertex Group"; ot->idname= "OBJECT_OT_vertex_group_deselect"; - + /* api callbacks */ - ot->poll= vertex_group_poll_edit; ot->exec= vertex_group_deselect_exec; /* flags */ @@ -1148,13 +1275,16 @@ void OBJECT_OT_vertex_group_deselect(wmOperatorType *ot) static int vertex_group_copy_exec(bContext *C, wmOperator *op) { + Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; - vgroup_duplicate(ob); - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data); + if(!ob) + return OPERATOR_CANCELLED; + duplicate_defgroup(ob); + DAG_object_flush_update(scene, ob, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob); + return OPERATOR_FINISHED; } @@ -1163,9 +1293,8 @@ void OBJECT_OT_vertex_group_copy(wmOperatorType *ot) /* identifiers */ ot->name= "Copy Vertex Group"; ot->idname= "OBJECT_OT_vertex_group_copy"; - + /* api callbacks */ - ot->poll= vertex_group_poll; ot->exec= vertex_group_copy_exec; /* flags */ @@ -1176,25 +1305,27 @@ static int vertex_group_copy_to_linked_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; - Base *base; + Base *base; int retval= OPERATOR_CANCELLED; - for(base=scene->base.first; base; base= base->next) { - if(base->object->type==ob->type) { - if(base->object!=ob && base->object->data==ob->data) { - BLI_freelistN(&base->object->defbase); - BLI_duplicatelist(&base->object->defbase, &ob->defbase); - base->object->actdef= ob->actdef; + if(!ob) + return retval; - DAG_id_flush_update(&base->object->id, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, base->object); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, base->object->data); + for(base=scene->base.first; base; base= base->next) { + if(base->object->type==ob->type) { + if(base->object!=ob && base->object->data==ob->data) { + BLI_freelistN(&base->object->defbase); + BLI_duplicatelist(&base->object->defbase, &ob->defbase); + base->object->actdef= ob->actdef; - retval = OPERATOR_FINISHED; - } - } - } + DAG_object_flush_update(scene, base->object, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, base->object); + retval = OPERATOR_FINISHED; + } + } + } + return retval; } @@ -1203,119 +1334,11 @@ void OBJECT_OT_vertex_group_copy_to_linked(wmOperatorType *ot) /* identifiers */ ot->name= "Copy Vertex Group to Linked"; ot->idname= "OBJECT_OT_vertex_group_copy_to_linked"; - - /* api callbacks */ - ot->poll= vertex_group_poll; - ot->exec= vertex_group_copy_to_linked_exec; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - -static EnumPropertyItem vgroup_items[]= { - {0, NULL, 0, NULL, NULL}}; - -static int set_active_group_exec(bContext *C, wmOperator *op) -{ - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; - int nr= RNA_enum_get(op->ptr, "group"); - - ob->actdef= nr+1; - - DAG_id_flush_update(&ob->id, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); - - return OPERATOR_FINISHED; -} - -static EnumPropertyItem *vgroup_itemf(bContext *C, PointerRNA *ptr, int *free) -{ - Object *ob; - EnumPropertyItem tmp = {0, "", 0, "", ""}; - EnumPropertyItem *item= NULL; - bDeformGroup *def; - int a, totitem= 0; - if(!C || !(ob = CTX_data_pointer_get_type(C, "object", &RNA_Object).data)) /* needed for docs */ - return vgroup_items; - - for(a=0, def=ob->defbase.first; def; def=def->next, a++) { - tmp.value= a; - tmp.identifier= def->name; - tmp.name= def->name; - RNA_enum_item_add(&item, &totitem, &tmp); - } - - RNA_enum_item_end(&item, &totitem); - - *free= 1; - - return item; -} - -void OBJECT_OT_vertex_group_set_active(wmOperatorType *ot) -{ - PropertyRNA *prop; - - /* identifiers */ - ot->name= "Set Active Vertex Group"; - ot->idname= "OBJECT_OT_vertex_group_set_active"; - /* api callbacks */ - ot->poll= vertex_group_poll; - ot->exec= set_active_group_exec; - ot->invoke= WM_menu_invoke; + ot->exec= vertex_group_copy_to_linked_exec; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - /* properties */ - prop= RNA_def_enum(ot->srna, "group", vgroup_items, 0, "Group", "Vertex group to set as active."); - RNA_def_enum_funcs(prop, vgroup_itemf); -} - -static int vertex_group_menu_exec(bContext *C, wmOperator *op) -{ - Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; - uiPopupMenu *pup; - uiLayout *layout; - - pup= uiPupMenuBegin(C, "Vertex Groups", 0); - layout= uiPupMenuLayout(pup); - uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_REGION_WIN); - - if(vgroup_object_in_edit_mode(ob)) { - uiItemBooleanO(layout, "Assign to New Group", 0, "OBJECT_OT_vertex_group_assign", "new", 1); - - if(BLI_countlist(&ob->defbase) && ob->actdef) { - uiItemO(layout, "Assign to Group", 0, "OBJECT_OT_vertex_group_assign"); - uiItemO(layout, "Remove from Group", 0, "OBJECT_OT_vertex_group_remove_from"); - uiItemBooleanO(layout, "Remove from All", 0, "OBJECT_OT_vertex_group_remove_from", "all", 1); - } - } - - if(BLI_countlist(&ob->defbase) && ob->actdef) { - if(vgroup_object_in_edit_mode(ob)) - uiItemS(layout); - - uiItemO(layout, "Set Active Group", 0, "OBJECT_OT_vertex_group_set_active"); - uiItemO(layout, "Remove Group", 0, "OBJECT_OT_vertex_group_remove"); - uiItemBooleanO(layout, "Remove All Groups", 0, "OBJECT_OT_vertex_group_remove", "all", 1); - } - - uiPupMenuEnd(C, pup); - - return OPERATOR_FINISHED; -} - -void OBJECT_OT_vertex_group_menu(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Vertex Group Menu"; - ot->idname= "OBJECT_OT_vertex_group_menu"; - - /* api callbacks */ - ot->poll= vertex_group_poll; - ot->exec= vertex_group_menu_exec; } |