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.c1465
1 files changed, 719 insertions, 746 deletions
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c
index 789cfaa840d..e8b683810c6 100644
--- a/source/blender/editors/object/object_vgroup.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -25,8 +25,6 @@
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
- * Creator-specific support for vertex deformation groups
- * Added: apply deform function (ton)
*/
#include <string.h>
@@ -46,7 +44,6 @@
#include "DNA_windowmanager_types.h"
#include "BLI_blenlib.h"
-#include "BLI_editVert.h"
#include "BLI_cellalloc.h"
#include "BKE_context.h"
@@ -60,8 +57,10 @@
#include "BKE_mesh.h"
#include "BKE_paint.h"
#include "BKE_utildefines.h"
+#include "BKE_tessmesh.h"
#include "RNA_access.h"
+#include "RNA_define.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -69,127 +68,55 @@
#include "ED_mesh.h"
#include "ED_view3d.h"
+#include "UI_interface.h"
+
#include "object_intern.h"
-/* XXX */
-static void BIF_undo_push() {}
-static void error() {}
+/************************ Exported Functions **********************/
-static Lattice *def_get_lattice(Object *ob)
+static Lattice *vgroup_edit_lattice(Object *ob)
{
if(ob->type==OB_LATTICE) {
Lattice *lt= ob->data;
- if(lt->editlatt)
- return lt->editlatt;
- return lt;
+ return (lt->editlatt)? lt->editlatt: 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;
- }
+ return NULL;
}
/* check if deform vertex has defgroup index */
-MDeformWeight *get_defweight (MDeformVert *dv, int defgroup)
+MDeformWeight *ED_vgroup_weight_get(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 *verify_defweight (MDeformVert *dv, int defgroup)
+MDeformWeight *ED_vgroup_weight_verify(MDeformVert *dv, int defgroup)
{
MDeformWeight *newdw;
/* do this check always, this function is used to check for it */
- if (!dv || defgroup<0)
+ if(!dv || defgroup<0)
return NULL;
- newdw = get_defweight (dv, defgroup);
- if (newdw)
+ newdw = ED_vgroup_weight_get(dv, defgroup);
+ if(newdw)
return newdw;
newdw = BLI_cellalloc_calloc(sizeof(MDeformWeight)*(dv->totweight+1), "deformWeight");
- if (dv->dw){
- memcpy (newdw, dv->dw, sizeof(MDeformWeight)*dv->totweight);
- BLI_cellalloc_free (dv->dw);
+ if(dv->dw) {
+ memcpy(newdw, dv->dw, sizeof(MDeformWeight)*dv->totweight);
+ BLI_cellalloc_free(dv->dw);
}
dv->dw=newdw;
@@ -202,16 +129,16 @@ MDeformWeight *verify_defweight (MDeformVert *dv, int defgroup)
return dv->dw+(dv->totweight-1);
}
-bDeformGroup *add_defgroup_name (Object *ob, char *name)
+bDeformGroup *ED_vgroup_add_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);
@@ -221,306 +148,20 @@ bDeformGroup *add_defgroup_name (Object *ob, char *name)
return defgroup;
}
-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)
+bDeformGroup *ED_vgroup_add(Object *ob)
{
- /* 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;
+ return ED_vgroup_add_name(ob, "Group");
}
-void create_dverts(ID *id)
+void ED_vgroup_data_create(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");
}
@@ -528,7 +169,7 @@ void create_dverts(ID *id)
/* for mesh in object mode
lattice can be in editmode */
-void remove_vert_def_nr (Object *ob, int def_nr, int vertnum)
+void ED_vgroup_nr_vert_remove(Object *ob, int def_nr, int vertnum)
{
/* This routine removes the vertex from the deform
* group with number def_nr.
@@ -548,11 +189,11 @@ void remove_vert_def_nr (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= def_get_lattice(ob);
+ Lattice *lt= vgroup_edit_lattice(ob);
if(lt->dvert)
dvert = lt->dvert + vertnum;
@@ -564,27 +205,27 @@ void remove_vert_def_nr (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 = BLI_cellalloc_malloc (sizeof(MDeformWeight)*(dvert->totweight),
+ if(dvert->totweight) {
+ newdw = BLI_cellalloc_malloc(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));
- BLI_cellalloc_free (dvert->dw);
+ BLI_cellalloc_free(dvert->dw);
}
dvert->dw=newdw;
}
@@ -592,7 +233,7 @@ void remove_vert_def_nr (Object *ob, int def_nr, int vertnum)
* left then just remove the deform weight
*/
else {
- BLI_cellalloc_free (dvert->dw);
+ MEM_freeN(dvert->dw);
dvert->dw = NULL;
break;
}
@@ -603,8 +244,7 @@ void remove_vert_def_nr (Object *ob, int def_nr, int vertnum)
/* for Mesh in Object mode */
/* allows editmode for Lattice */
-void add_vert_defnr (Object *ob, int def_nr, int vertnum,
- float weight, int assignmode)
+void ED_vgroup_nr_vert_add(Object *ob, int def_nr, int vertnum, float weight, int assignmode)
{
/* add the vert to the deform group with the
* specified number
@@ -619,7 +259,7 @@ void add_vert_defnr (Object *ob, int def_nr, int vertnum,
dv = ((Mesh*)ob->data)->dvert + vertnum;
}
else if(ob->type==OB_LATTICE) {
- Lattice *lt= def_get_lattice(ob);
+ Lattice *lt= vgroup_edit_lattice(ob);
if(lt->dvert)
dv = lt->dvert + vertnum;
@@ -632,21 +272,21 @@ void add_vert_defnr (Object *ob, int def_nr, int vertnum,
* 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:
@@ -654,8 +294,8 @@ void add_vert_defnr (Object *ob, int def_nr, int vertnum,
/* if the weight is zero or less then
* remove the vert from the deform group
*/
- if (dv->dw[i].weight <= 0.0)
- remove_vert_def_nr(ob, def_nr, vertnum);
+ if(dv->dw[i].weight <= 0.0)
+ ED_vgroup_nr_vert_remove(ob, def_nr, vertnum);
break;
}
return;
@@ -666,7 +306,7 @@ void add_vert_defnr (Object *ob, int def_nr, int vertnum,
* 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
@@ -678,11 +318,11 @@ void add_vert_defnr (Object *ob, int def_nr, int vertnum,
/* if we are doing an additive assignment, then
* we need to create the deform weight
*/
- newdw = BLI_cellalloc_calloc (sizeof(MDeformWeight)*(dv->totweight+1),
+ newdw = BLI_cellalloc_calloc(sizeof(MDeformWeight)*(dv->totweight+1),
"deformWeight");
- if (dv->dw){
- memcpy (newdw, dv->dw, sizeof(MDeformWeight)*dv->totweight);
- BLI_cellalloc_free (dv->dw);
+ if(dv->dw){
+ memcpy(newdw, dv->dw, sizeof(MDeformWeight)*dv->totweight);
+ BLI_cellalloc_free(dv->dw);
}
dv->dw=newdw;
@@ -695,8 +335,7 @@ void add_vert_defnr (Object *ob, int def_nr, int vertnum,
}
/* called while not in editmode */
-void add_vert_to_defgroup (Object *ob, bDeformGroup *dg, int vertnum,
- float weight, int assignmode)
+void ED_vgroup_vert_add(Object *ob, bDeformGroup *dg, int vertnum, float weight, int assignmode)
{
/* add the vert to the deform group with the
* specified assign mode
@@ -707,115 +346,27 @@ void add_vert_to_defgroup (Object *ob, bDeformGroup *dg, int vertnum,
* 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)
- create_dverts(ob->data);
+ if(!((Mesh*)ob->data)->dvert)
+ ED_vgroup_data_create(ob->data);
}
else if(ob->type==OB_LATTICE) {
- if (!((Lattice*)ob->data)->dvert)
- create_dverts(ob->data);
+ if(!((Lattice*)ob->data)->dvert)
+ ED_vgroup_data_create(ob->data);
}
/* call another function to do the work
*/
- 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 = BLI_cellalloc_calloc (sizeof(MDeformWeight)*(dvert->totweight+1), "deformWeight");
- if (dvert->dw){
- memcpy (newdw, dvert->dw, sizeof(MDeformWeight)*dvert->totweight);
- BLI_cellalloc_free (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;
- }
-
+ ED_vgroup_nr_vert_add(ob, def_nr, vertnum, weight, assignmode);
}
/* mesh object mode, lattice can be in editmode */
-void remove_vert_defgroup (Object *ob, bDeformGroup *dg, int vertnum)
+void ED_vgroup_vert_remove(Object *ob, bDeformGroup *dg, int vertnum)
{
/* This routine removes the vertex from the specified
* deform group.
@@ -825,7 +376,7 @@ void remove_vert_defgroup (Object *ob, bDeformGroup *dg, int vertnum)
/* if the object is NULL abort
*/
- if (!ob)
+ if(!ob)
return;
/* get the deform number that cooresponds
@@ -833,28 +384,35 @@ void remove_vert_defgroup (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
*/
- remove_vert_def_nr (ob, def_nr, vertnum);
+ ED_vgroup_nr_vert_remove(ob, def_nr, vertnum);
}
-/* for mesh in object mode lattice can be in editmode */
-static float get_vert_def_nr (Object *ob, int def_nr, int vertnum)
+
+static float get_vert_def_nr(Object *ob, int def_nr, int vertnum)
{
MDeformVert *dvert= NULL;
+ BMVert *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) {
- if( ((Mesh*)ob->data)->dvert )
- dvert = ((Mesh*)ob->data)->dvert + vertnum;
+ me= ob->data;
+
+ if(me->edit_btmesh) {
+ eve= BMIter_AtIndex(me->edit_btmesh->bm, BM_VERTS_OF_MESH, NULL, vertnum);
+ if(!eve) return 0.0f;
+ dvert= CustomData_bmesh_get(&me->edit_btmesh->bm->vdata, eve->head.data, CD_MDEFORMVERT);
+ }
+ else
+ dvert = me->dvert + vertnum;
}
else if(ob->type==OB_LATTICE) {
- Lattice *lt= def_get_lattice(ob);
+ Lattice *lt= vgroup_edit_lattice(ob);
if(lt->dvert)
dvert = lt->dvert + vertnum;
@@ -870,61 +428,295 @@ static float get_vert_def_nr (Object *ob, int def_nr, int vertnum)
return 0.0f;
}
-/* mesh object mode, lattice can be in editmode */
-float get_vert_defgroup (Object *ob, bDeformGroup *dg, int vertnum)
+float ED_vgroup_vert_weight(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);
+ 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)
+{
+ BMVert *eve;
+ MDeformVert *dvert;
+ int i;
+
+ if(ob->type == OB_MESH) {
+ Mesh *me= ob->data;
+ BMEditMesh *em = me->edit_btmesh;
+ BMIter iter;
+
+ BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
+ dvert= CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT);
+
+ if(dvert && dvert->totweight){
+ for(i=0; i<dvert->totweight; i++){
+ if(dvert->dw[i].def_nr == (ob->actdef-1)){
+ BM_Select(em->bm, eve, select);
+ break;
+ }
+ }
+ }
+ }
+ /* this has to be called, because this function operates on vertices only */
+ if(select) EDBM_selectmode_flush(em); // vertices to edges/faces
+ else EDBM_deselect_flush(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;
+ }
+ }
}
-/* Only available in editmode */
+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]--;
+ }
+}
+
+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 */
/* removes from active defgroup, if allverts==0 only selected vertices */
-void remove_verts_defgroup (Object *ob, int allverts)
+static void vgroup_active_remove_verts(Object *ob, int allverts)
{
- EditVert *eve;
+ BMVert *eve;
MDeformVert *dvert;
MDeformWeight *newdw;
bDeformGroup *dg, *eg;
int i;
- if (!ob)
- return;
-
dg=BLI_findlink(&ob->defbase, ob->actdef-1);
- if (!dg){
- error ("No vertex group is active");
+ if(!dg)
return;
- }
- switch (ob->type){
- case OB_MESH:
- {
+ if(ob->type == OB_MESH) {
Mesh *me= ob->data;
- EditMesh *em = BKE_mesh_get_editmesh(me);
+ BMEditMesh *em = me->edit_btmesh;
+ BMIter iter;
- for (eve=em->verts.first; eve; eve=eve->next){
- dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
+ BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
+ dvert= CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT);
- if (dvert && dvert->dw && ((eve->f & 1) || allverts)){
- for (i=0; i<dvert->totweight; i++){
+ if(dvert && dvert->dw && (BM_TestHFlag(eve, BM_SELECT) || 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 = BLI_cellalloc_malloc (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;
}
@@ -937,12 +729,9 @@ void remove_verts_defgroup (Object *ob, int allverts)
}
}
}
- BKE_mesh_end_editmesh(me, em);
}
- break;
- case OB_LATTICE:
- {
- Lattice *lt= def_get_lattice(ob);
+ else if(ob->type == OB_LATTICE) {
+ Lattice *lt= vgroup_edit_lattice(ob);
if(lt->dvert) {
BPoint *bp;
@@ -950,170 +739,249 @@ void remove_verts_defgroup (Object *ob, int allverts)
for(a=0, bp= lt->def; a<tot; a++, bp++) {
if(allverts || (bp->f1 & SELECT))
- remove_vert_defgroup (ob, dg, a);
+ ED_vgroup_vert_remove(ob, dg, a);
}
}
}
- break;
-
- default:
- printf ("Removing deformation groups from unknown object type\n");
- break;
- }
}
-/* Only available in editmode */
-/* removes from all defgroup, if allverts==0 only selected vertices */
-void remove_verts_defgroups(Object *ob, int allverts)
+static void vgroup_delete_edit_mode(Object *ob)
{
- int actdef, defCount;
+ bDeformGroup *defgroup;
+ int i;
- if (ob == NULL) return;
-
- actdef= ob->actdef;
- defCount= BLI_countlist(&ob->defbase);
-
- if (defCount == 0) {
- error("Object has no vertex groups");
+ if(!ob->actdef)
+ return;
+
+ defgroup = BLI_findlink(&ob->defbase, ob->actdef-1);
+ if(!defgroup)
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;
+ BMEditMesh *em = me->edit_btmesh;
+ BMIter iter;
+ BMVert *eve;
+ MDeformVert *dvert;
+
+ BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
+ dvert= CustomData_bmesh_get(&em->bm->vdata, eve->head.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--;
+ }
}
-
- /* 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);
+ else if(ob->type==OB_LATTICE) {
+ Lattice *lt= vgroup_edit_lattice(ob);
+ BPoint *bp;
+ MDeformVert *dvert= lt->dvert;
+ int a, tot;
- ob->actdef= actdef;
-}
+ 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--;
+ }
+ }
+ }
+ }
-void vertexgroup_select_by_name(Object *ob, char *name)
-{
- bDeformGroup *curdef;
- int actdef= 1;
+ vgroup_delete_update_users(ob, ob->actdef);
+
+ /* Update the active deform index if necessary */
+ if(ob->actdef==BLI_countlist(&ob->defbase))
+ ob->actdef--;
- if(ob==NULL) return;
+ /* Remove the group */
+ BLI_freelinkN (&ob->defbase, defgroup);
- for (curdef = ob->defbase.first; curdef; curdef=curdef->next, actdef++){
- if (!strcmp(curdef->name, name)) {
- ob->actdef= actdef;
- 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;
+ }
}
}
- ob->actdef=0; // this signals on painting to create a new one, if a bone in posemode is selected */
}
-/* 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)
+static int vgroup_object_in_edit_mode(Object *ob)
{
- VPaint *wp= scene->toolsettings->wpaint;
- int defCount;
- int mode= 0;
+ if(ob->type == OB_MESH)
+ return (((Mesh*)ob->data)->edit_btmesh != NULL);
+ else if(ob->type == OB_LATTICE)
+ return (((Lattice*)ob->data)->editlatt != NULL);
- /* prevent crashes */
- if (wp==NULL || ob==NULL) return;
-
- defCount= BLI_countlist(&ob->defbase);
+ 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;
+ }
+ }
- /* 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");
+ /* Remove all DefGroups */
+ BLI_freelistN(&ob->defbase);
- /* 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;
+ /* Fix counters/indices */
+ ob->actdef= 0;
+}
+
+/* only in editmode */
+static void vgroup_assign_verts(Object *ob, float weight)
+{
+ BMVert *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;
+ BMEditMesh *em = me->edit_btmesh;
+ BMIter iter;
+
+ if(!CustomData_has_layer(&em->bm->vdata, CD_MDEFORMVERT))
+ BM_add_data_layer(em->bm, &em->bm->vdata, CD_MDEFORMVERT);
+
+ /* Go through the list of editverts and assign them */
+ BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
+ dvert= CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT);
+
+ if(dvert && BM_TestHFlag(eve, BM_SELECT)) {
+ 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 = BLI_cellalloc_calloc(sizeof(MDeformWeight)*(dvert->totweight+1), "deformWeight");
+ if(dvert->dw){
+ memcpy(newdw, dvert->dw, sizeof(MDeformWeight)*dvert->totweight);
+ BLI_cellalloc_free(dvert->dw);
+ }
+ dvert->dw=newdw;
+
+ dvert->dw[dvert->totweight].weight= weight;
+ dvert->dw[dvert->totweight].def_nr= ob->actdef-1;
+
+ dvert->totweight++;
+
+ }
+ }
+ }
+ }
+ 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);
+ }
}
}
-/* 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)
+/* only in editmode */
+/* removes from all defgroup, if allverts==0 only selected vertices */
+static void vgroup_remove_verts(Object *ob, int allverts)
{
- int defCount;
- int mode= 0;
-
- /* prevent crashes and useless cases */
- if (ob==NULL) return;
+ int actdef, defCount;
+ actdef= ob->actdef;
defCount= BLI_countlist(&ob->defbase);
- 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");
+ if(defCount == 0)
+ return;
- /* 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;
- }
+ /* 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;
}
/********************** vertex group operators *********************/
-static int vertex_group_add_exec(bContext *C, wmOperator *op)
+static int vertex_group_poll(bContext *C)
{
Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
- Scene *scene= CTX_data_scene(C);
+ ID *data= (ob)? ob->data: NULL;
+ return (ob && !ob->id.lib && ELEM(ob->type, OB_MESH, OB_LATTICE) && data && !data->lib);
+}
- if(!ob)
- return OPERATOR_CANCELLED;
+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;
- add_defgroup(ob);
- DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
- WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
+ 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;
+
+ 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);
return OPERATOR_FINISHED;
}
@@ -1125,6 +993,7 @@ 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 */
@@ -1134,20 +1003,15 @@ 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(!ob)
- return OPERATOR_CANCELLED;
+ if(RNA_boolean_get(op->ptr, "all"))
+ vgroup_delete_all(ob);
+ else
+ vgroup_delete(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);
- }
+ 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);
return OPERATOR_FINISHED;
}
@@ -1159,24 +1023,27 @@ 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(!ob)
- return OPERATOR_CANCELLED;
+ if(RNA_boolean_get(op->ptr, "new"))
+ ED_vgroup_add(ob);
- 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);
+ 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);
return OPERATOR_FINISHED;
}
@@ -1188,24 +1055,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);
- if(!ob)
- return OPERATOR_CANCELLED;
+ 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);
- 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;
}
@@ -1214,23 +1081,27 @@ 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)
+ if(!ob || ob->id.lib)
return OPERATOR_CANCELLED;
- sel_verts_defgroup(ob, 1); /* runs countall() */
- WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, ob);
+ vgroup_select_verts(ob, 1);
+ WM_event_add_notifier(C, NC_GEOM|ND_SELECT, ob->data);
return OPERATOR_FINISHED;
}
@@ -1240,8 +1111,9 @@ 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 */
@@ -1252,11 +1124,8 @@ static int vertex_group_deselect_exec(bContext *C, wmOperator *op)
{
Object *ob= CTX_data_edit_object(C);
- if(!ob)
- return OPERATOR_CANCELLED;
-
- sel_verts_defgroup(ob, 0); /* runs countall() */
- WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, ob);
+ vgroup_select_verts(ob, 0);
+ WM_event_add_notifier(C, NC_GEOM|ND_SELECT, ob->data);
return OPERATOR_FINISHED;
}
@@ -1266,8 +1135,9 @@ 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 */
@@ -1276,16 +1146,13 @@ 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;
- if(!ob)
- return OPERATOR_CANCELLED;
+ 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);
- 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;
}
@@ -1294,8 +1161,9 @@ 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 */
@@ -1306,27 +1174,25 @@ 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;
- if(!ob)
- return retval;
-
- 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;
+ 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;
- DAG_object_flush_update(scene, base->object, OB_RECALC_DATA);
- WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, base->object);
+ 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);
retval = OPERATOR_FINISHED;
- }
- }
- }
-
+ }
+ }
+ }
+
return retval;
}
@@ -1335,11 +1201,118 @@ 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;
+
+ /* 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;
+}