Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/object/object_vgroup.c')
-rw-r--r--source/blender/editors/object/object_vgroup.c1467
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(&lt->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(&lt->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;
}