svn merge -r 22371:22571 https://svn.blender.org/svnroot/bf-blender/branches/blender2...
[blender.git] / source / blender / editors / object / object_vgroup.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  * Creator-specific support for vertex deformation groups
29  * Added: apply deform function (ton)
30  */
31
32 #include <string.h>
33
34 #include "MEM_guardedalloc.h"
35
36 #include "DNA_cloth_types.h"
37 #include "DNA_curve_types.h"
38 #include "DNA_lattice_types.h"
39 #include "DNA_mesh_types.h"
40 #include "DNA_meshdata_types.h"
41 #include "DNA_modifier_types.h"
42 #include "DNA_object_types.h"
43 #include "DNA_object_force.h"
44 #include "DNA_scene_types.h"
45 #include "DNA_particle_types.h"
46 #include "DNA_windowmanager_types.h"
47
48 #include "BLI_blenlib.h"
49 #include "BLI_editVert.h"
50
51 #include "BKE_context.h"
52 #include "BKE_customdata.h"
53 #include "BKE_deform.h"
54 #include "BKE_depsgraph.h"
55 #include "BKE_DerivedMesh.h"
56 #include "BKE_displist.h"
57 #include "BKE_global.h"
58 #include "BKE_lattice.h"
59 #include "BKE_mesh.h"
60 #include "BKE_paint.h"
61 #include "BKE_utildefines.h"
62
63 #include "RNA_access.h"
64
65 #include "WM_api.h"
66 #include "WM_types.h"
67
68 #include "ED_mesh.h"
69 #include "ED_view3d.h"
70
71 #include "object_intern.h"
72
73 /* XXX */
74 static void BIF_undo_push() {}
75 static void error() {}
76
77 static Lattice *def_get_lattice(Object *ob)
78 {
79         if(ob->type==OB_LATTICE) {
80                 Lattice *lt= ob->data;
81                 if(lt->editlatt)
82                         return lt->editlatt;
83                 return lt;
84         }
85         return NULL;
86 }
87
88 /* only in editmode */
89 void sel_verts_defgroup (Object *obedit, int select)
90 {
91         EditVert *eve;
92         Object *ob;
93         int i;
94         MDeformVert *dvert;
95
96         ob= obedit;
97
98         if (!ob)
99                 return;
100
101         switch (ob->type){
102         case OB_MESH:
103         {
104                 Mesh *me= ob->data;
105                 EditMesh *em = BKE_mesh_get_editmesh(me);
106
107                 for (eve=em->verts.first; eve; eve=eve->next){
108                         dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
109
110                         if (dvert && dvert->totweight){
111                                 for (i=0; i<dvert->totweight; i++){
112                                         if (dvert->dw[i].def_nr == (ob->actdef-1)){
113                                                 if (select) eve->f |= SELECT;
114                                                 else eve->f &= ~SELECT;
115                                                 
116                                                 break;
117                                         }
118                                 }
119                         }
120                 }
121                 /* this has to be called, because this function operates on vertices only */
122                 if(select) EM_select_flush(em); // vertices to edges/faces
123                 else EM_deselect_flush(em);
124
125                 BKE_mesh_end_editmesh(me, em);
126         }
127                 break;
128         case OB_LATTICE:
129         {
130                 Lattice *lt= def_get_lattice(ob);
131                 
132                 if(lt->dvert) {
133                         BPoint *bp;
134                         int a, tot;
135                         
136                         dvert= lt->dvert;
137
138                         tot= lt->pntsu*lt->pntsv*lt->pntsw;
139                         for(a=0, bp= lt->def; a<tot; a++, bp++, dvert++) {
140                                 for (i=0; i<dvert->totweight; i++){
141                                         if (dvert->dw[i].def_nr == (ob->actdef-1)) {
142                                                 if(select) bp->f1 |= SELECT;
143                                                 else bp->f1 &= ~SELECT;
144                                                 
145                                                 break;
146                                         }
147                                 }
148                         }
149                 }
150         }
151                 break;
152                 
153         default:
154                 break;
155         }
156 }
157
158 /* check if deform vertex has defgroup index */
159 MDeformWeight *get_defweight (MDeformVert *dv, int defgroup)
160 {
161         int i;
162         
163         if (!dv || defgroup<0)
164                 return NULL;
165         
166         for (i=0; i<dv->totweight; i++){
167                 if (dv->dw[i].def_nr == defgroup)
168                         return dv->dw+i;
169         }
170         return NULL;
171 }
172
173 /* Ensures that mv has a deform weight entry for
174    the specified defweight group */
175 /* Note this function is mirrored in editmesh_tools.c, for use for editvertices */
176 MDeformWeight *verify_defweight (MDeformVert *dv, int defgroup)
177 {
178         MDeformWeight *newdw;
179
180         /* do this check always, this function is used to check for it */
181         if (!dv || defgroup<0)
182                 return NULL;
183         
184         newdw = get_defweight (dv, defgroup);
185         if (newdw)
186                 return newdw;
187         
188         newdw = MEM_callocN (sizeof(MDeformWeight)*(dv->totweight+1), "deformWeight");
189         if (dv->dw){
190                 memcpy (newdw, dv->dw, sizeof(MDeformWeight)*dv->totweight);
191                 MEM_freeN (dv->dw);
192         }
193         dv->dw=newdw;
194         
195         dv->dw[dv->totweight].weight=0.0f;
196         dv->dw[dv->totweight].def_nr=defgroup;
197         /* Group index */
198         
199         dv->totweight++;
200
201         return dv->dw+(dv->totweight-1);
202 }
203
204 bDeformGroup *add_defgroup_name (Object *ob, char *name)
205 {
206         bDeformGroup    *defgroup;
207         
208         if (!ob)
209                 return NULL;
210         
211         defgroup = MEM_callocN (sizeof(bDeformGroup), "add deformGroup");
212
213         BLI_strncpy (defgroup->name, name, 32);
214
215         BLI_addtail(&ob->defbase, defgroup);
216         unique_vertexgroup_name(defgroup, ob);
217
218         ob->actdef = BLI_countlist(&ob->defbase);
219
220         return defgroup;
221 }
222
223 void add_defgroup (Object *ob) 
224 {
225         add_defgroup_name (ob, "Group");
226 }
227
228
229 void duplicate_defgroup ( Object *ob )
230 {
231         bDeformGroup *dg, *cdg;
232         char name[32], s[32];
233         MDeformWeight *org, *cpy;
234         MDeformVert *dvert, *dvert_array=NULL;
235         int i, idg, icdg, dvert_tot=0;
236
237         if (ob->type != OB_MESH && ob->type != OB_LATTICE)
238                 return;
239
240         dg = BLI_findlink (&ob->defbase, (ob->actdef-1));
241         if (!dg)
242                 return;
243         
244         if (strstr(dg->name, "_copy")) {
245                 BLI_strncpy (name, dg->name, 32); /* will be renamed _copy.001... etc */
246         } else {
247                 BLI_snprintf (name, 32, "%s_copy", dg->name);
248                 while (get_named_vertexgroup (ob, name)) {
249                         if ((strlen (name) + 6) > 32) {
250                                 error ("Error: the name for the new group is > 32 characters");
251                                 return;
252                         }
253                         strcpy (s, name);
254                         BLI_snprintf (name, 32, "%s_copy", s);
255                 }
256         }               
257
258         cdg = copy_defgroup (dg);
259         strcpy (cdg->name, name);
260         unique_vertexgroup_name(cdg, ob);
261         
262         BLI_addtail (&ob->defbase, cdg);
263
264         idg = (ob->actdef-1);
265         ob->actdef = BLI_countlist (&ob->defbase);
266         icdg = (ob->actdef-1);
267
268         if(ob->type == OB_MESH) {
269                 Mesh *me = get_mesh (ob);
270                 dvert_array= me->dvert;
271                 dvert_tot= me->totvert;
272         }
273         else if (ob->type == OB_LATTICE) {
274                 Lattice *lt= (Lattice *)ob->data;
275                 dvert_array= lt->dvert;
276                 dvert_tot= lt->pntsu*lt->pntsv*lt->pntsw;
277         }
278         
279         if (!dvert_array)
280                 return;
281
282         for (i = 0; i < dvert_tot; i++) {
283                 dvert = dvert_array+i;
284                 org = get_defweight (dvert, idg);
285                 if (org) {
286                         float weight = org->weight;
287                         /* verify_defweight re-allocs org so need to store the weight first */
288                         cpy = verify_defweight (dvert, icdg);
289                         cpy->weight = weight;
290                 }
291         }
292 }
293
294 static void del_defgroup_update_users(Object *ob, int id)
295 {
296         ExplodeModifierData *emd;
297         ModifierData *md;
298         ParticleSystem *psys;
299         ClothModifierData *clmd;
300         ClothSimSettings *clsim;
301         int a;
302
303         /* these cases don't use names to refer to vertex groups, so when
304          * they get deleted the numbers get out of sync, this corrects that */
305
306         if(ob->soft) {
307                 if(ob->soft->vertgroup == id)
308                         ob->soft->vertgroup= 0;
309                 else if(ob->soft->vertgroup > id)
310                         ob->soft->vertgroup--;
311         }
312
313         for(md=ob->modifiers.first; md; md=md->next) {
314                 if(md->type == eModifierType_Explode) {
315                         emd= (ExplodeModifierData*)md;
316
317                         if(emd->vgroup == id)
318                                 emd->vgroup= 0;
319                         else if(emd->vgroup > id)
320                                 emd->vgroup--;
321                 }
322                 else if(md->type == eModifierType_Cloth) {
323                         clmd= (ClothModifierData*)md;
324                         clsim= clmd->sim_parms;
325
326                         if(clsim) {
327                                 if(clsim->vgroup_mass == id)
328                                         clsim->vgroup_mass= 0;
329                                 else if(clsim->vgroup_mass > id)
330                                         clsim->vgroup_mass--;
331
332                                 if(clsim->vgroup_bend == id)
333                                         clsim->vgroup_bend= 0;
334                                 else if(clsim->vgroup_bend > id)
335                                         clsim->vgroup_bend--;
336
337                                 if(clsim->vgroup_struct == id)
338                                         clsim->vgroup_struct= 0;
339                                 else if(clsim->vgroup_struct > id)
340                                         clsim->vgroup_struct--;
341                         }
342                 }
343         }
344
345         for(psys=ob->particlesystem.first; psys; psys=psys->next) {
346                 for(a=0; a<PSYS_TOT_VG; a++)
347                         if(psys->vgroup[a] == id)
348                                 psys->vgroup[a]= 0;
349                         else if(psys->vgroup[a] > id)
350                                 psys->vgroup[a]--;
351         }
352 }
353
354 void del_defgroup_in_object_mode ( Object *ob )
355 {
356         bDeformGroup *dg;
357         MDeformVert *dvert, *dvert_array=NULL;
358         int i, e, dvert_tot=0;
359
360         if ((!ob) || (ob->type != OB_MESH && ob->type != OB_LATTICE))
361                 return;
362
363         if(ob->type == OB_MESH) {
364                 Mesh *me = get_mesh (ob);
365                 dvert_array= me->dvert;
366                 dvert_tot= me->totvert;
367         }
368         else if (ob->type == OB_LATTICE) {
369                 Lattice *lt= (Lattice *)ob->data;
370                 dvert_array= lt->dvert;
371                 dvert_tot= lt->pntsu*lt->pntsv*lt->pntsw;
372         }
373         
374         dg = BLI_findlink (&ob->defbase, (ob->actdef-1));
375         if (!dg)
376                 return;
377         
378         if (dvert_array) {
379                 for (i = 0; i < dvert_tot; i++) {
380                         dvert = dvert_array + i;
381                         if (dvert) {
382                                 if (get_defweight (dvert, (ob->actdef-1)))
383                                         remove_vert_defgroup (ob, dg, i);
384                         }
385                 }
386
387                 for (i = 0; i < dvert_tot; i++) {
388                         dvert = dvert_array+i;
389                         if (dvert) {
390                                 for (e = 0; e < dvert->totweight; e++) {
391                                         if (dvert->dw[e].def_nr > (ob->actdef-1))
392                                                 dvert->dw[e].def_nr--;
393                                 }
394                         }
395                 }
396         }
397
398         del_defgroup_update_users(ob, ob->actdef);
399
400         /* Update the active deform index if necessary */
401         if (ob->actdef == BLI_countlist(&ob->defbase))
402                 ob->actdef--;
403   
404         /* Remove the group */
405         BLI_freelinkN (&ob->defbase, dg);
406 }
407
408 void del_defgroup (Object *ob)
409 {
410         bDeformGroup    *defgroup;
411         int                             i;
412
413         if (!ob)
414                 return;
415
416         if (!ob->actdef)
417                 return;
418
419         defgroup = BLI_findlink(&ob->defbase, ob->actdef-1);
420         if (!defgroup)
421                 return;
422
423         /* Make sure that no verts are using this group */
424         remove_verts_defgroup(ob, 1);
425
426         /* Make sure that any verts with higher indices are adjusted accordingly */
427         if(ob->type==OB_MESH) {
428                 Mesh *me= ob->data;
429                 EditMesh *em = BKE_mesh_get_editmesh(me);
430                 EditVert *eve;
431                 MDeformVert *dvert;
432                 
433                 for (eve=em->verts.first; eve; eve=eve->next){
434                         dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
435
436                         if (dvert)
437                                 for (i=0; i<dvert->totweight; i++)
438                                         if (dvert->dw[i].def_nr > (ob->actdef-1))
439                                                 dvert->dw[i].def_nr--;
440                 }
441                 BKE_mesh_end_editmesh(me, em);
442         }
443         else if(ob->type==OB_LATTICE) {
444                 Lattice *lt= def_get_lattice(ob);
445                 BPoint *bp;
446                 MDeformVert *dvert= lt->dvert;
447                 int a, tot;
448                 
449                 if (dvert) {
450                         tot= lt->pntsu*lt->pntsv*lt->pntsw;
451                         for(a=0, bp= lt->def; a<tot; a++, bp++, dvert++) {
452                                 for (i=0; i<dvert->totweight; i++){
453                                         if (dvert->dw[i].def_nr > (ob->actdef-1))
454                                                 dvert->dw[i].def_nr--;
455                                 }
456                         }
457                 }
458         }
459
460         del_defgroup_update_users(ob, ob->actdef);
461
462         /* Update the active deform index if necessary */
463         if (ob->actdef==BLI_countlist(&ob->defbase))
464                 ob->actdef--;
465         
466         /* Remove the group */
467         BLI_freelinkN (&ob->defbase, defgroup);
468         
469         /* remove all dverts */
470         if(ob->actdef==0) {
471                 if(ob->type==OB_MESH) {
472                         Mesh *me= ob->data;
473                         CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert);
474                         me->dvert= NULL;
475                 }
476                 else if(ob->type==OB_LATTICE) {
477                         Lattice *lt= def_get_lattice(ob);
478                         if (lt->dvert) {
479                                 MEM_freeN(lt->dvert);
480                                 lt->dvert= NULL;
481                         }
482                 }
483         }
484 }
485
486 void del_all_defgroups (Object *ob)
487 {
488         /* Sanity check */
489         if (ob == NULL)
490                 return;
491         
492         /* Remove all DVerts */
493         if (ob->type==OB_MESH) {
494                 Mesh *me= ob->data;
495                 CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert);
496                 me->dvert= NULL;
497         }
498         else if(ob->type==OB_LATTICE) {
499                 Lattice *lt= def_get_lattice(ob);
500                 if (lt->dvert) {
501                         MEM_freeN(lt->dvert);
502                         lt->dvert= NULL;
503                 }
504         }
505         
506         /* Remove all DefGroups */
507         BLI_freelistN(&ob->defbase);
508         
509         /* Fix counters/indices */
510         ob->actdef= 0;
511 }
512
513 void create_dverts(ID *id)
514 {
515         /* create deform verts
516          */
517
518         if( GS(id->name)==ID_ME) {
519                 Mesh *me= (Mesh *)id;
520                 me->dvert= CustomData_add_layer(&me->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, me->totvert);
521         }
522         else if( GS(id->name)==ID_LT) {
523                 Lattice *lt= (Lattice *)id;
524                 lt->dvert= MEM_callocN(sizeof(MDeformVert)*lt->pntsu*lt->pntsv*lt->pntsw, "lattice deformVert");
525         }
526 }
527
528 /* for mesh in object mode
529    lattice can be in editmode */
530 void remove_vert_def_nr (Object *ob, int def_nr, int vertnum)
531 {
532         /* This routine removes the vertex from the deform
533          * group with number def_nr.
534          *
535          * This routine is meant to be fast, so it is the
536          * responsibility of the calling routine to:
537          *   a) test whether ob is non-NULL
538          *   b) test whether ob is a mesh
539          *   c) calculate def_nr
540          */
541
542         MDeformWeight *newdw;
543         MDeformVert *dvert= NULL;
544         int i;
545
546         /* get the deform vertices corresponding to the
547          * vertnum
548          */
549         if(ob->type==OB_MESH) {
550                 if( ((Mesh*)ob->data)->dvert )
551                         dvert = ((Mesh*)ob->data)->dvert + vertnum;
552         }
553         else if(ob->type==OB_LATTICE) {
554                 Lattice *lt= def_get_lattice(ob);
555                 
556                 if(lt->dvert)
557                         dvert = lt->dvert + vertnum;
558         }
559         
560         if(dvert==NULL)
561                 return;
562         
563         /* for all of the deform weights in the
564          * deform vert
565          */
566         for (i=dvert->totweight - 1 ; i>=0 ; i--){
567
568                 /* if the def_nr is the same as the one
569                  * for our weight group then remove it
570                  * from this deform vert.
571                  */
572                 if (dvert->dw[i].def_nr == def_nr) {
573                         dvert->totweight--;
574         
575                         /* if there are still other deform weights
576                          * attached to this vert then remove this
577                          * deform weight, and reshuffle the others
578                          */
579                         if (dvert->totweight) {
580                                 newdw = MEM_mallocN (sizeof(MDeformWeight)*(dvert->totweight), 
581                                                                          "deformWeight");
582                                 if (dvert->dw){
583                                         memcpy (newdw, dvert->dw, sizeof(MDeformWeight)*i);
584                                         memcpy (newdw+i, dvert->dw+i+1, 
585                                                         sizeof(MDeformWeight)*(dvert->totweight-i));
586                                         MEM_freeN (dvert->dw);
587                                 }
588                                 dvert->dw=newdw;
589                         }
590                         /* if there are no other deform weights
591                          * left then just remove the deform weight
592                          */
593                         else {
594                                 MEM_freeN (dvert->dw);
595                                 dvert->dw = NULL;
596                                 break;
597                         }
598                 }
599         }
600
601 }
602
603 /* for Mesh in Object mode */
604 /* allows editmode for Lattice */
605 void add_vert_defnr (Object *ob, int def_nr, int vertnum, 
606                            float weight, int assignmode)
607 {
608         /* add the vert to the deform group with the
609          * specified number
610          */
611         MDeformVert *dv= NULL;
612         MDeformWeight *newdw;
613         int     i;
614
615         /* get the vert */
616         if(ob->type==OB_MESH) {
617                 if(((Mesh*)ob->data)->dvert)
618                         dv = ((Mesh*)ob->data)->dvert + vertnum;
619         }
620         else if(ob->type==OB_LATTICE) {
621                 Lattice *lt= def_get_lattice(ob);
622                 
623                 if(lt->dvert)
624                         dv = lt->dvert + vertnum;
625         }
626         
627         if(dv==NULL)
628                 return;
629         
630         /* Lets first check to see if this vert is
631          * already in the weight group -- if so
632          * lets update it
633          */
634         for (i=0; i<dv->totweight; i++){
635                 
636                 /* if this weight cooresponds to the
637                  * deform group, then add it using
638                  * the assign mode provided
639                  */
640                 if (dv->dw[i].def_nr == def_nr){
641                         
642                         switch (assignmode) {
643                         case WEIGHT_REPLACE:
644                                 dv->dw[i].weight=weight;
645                                 break;
646                         case WEIGHT_ADD:
647                                 dv->dw[i].weight+=weight;
648                                 if (dv->dw[i].weight >= 1.0)
649                                         dv->dw[i].weight = 1.0;
650                                 break;
651                         case WEIGHT_SUBTRACT:
652                                 dv->dw[i].weight-=weight;
653                                 /* if the weight is zero or less then
654                                  * remove the vert from the deform group
655                                  */
656                                 if (dv->dw[i].weight <= 0.0)
657                                         remove_vert_def_nr(ob, def_nr, vertnum);
658                                 break;
659                         }
660                         return;
661                 }
662         }
663
664         /* if the vert wasn't in the deform group then
665          * we must take a different form of action ...
666          */
667
668         switch (assignmode) {
669         case WEIGHT_SUBTRACT:
670                 /* if we are subtracting then we don't
671                  * need to do anything
672                  */
673                 return;
674
675         case WEIGHT_REPLACE:
676         case WEIGHT_ADD:
677                 /* if we are doing an additive assignment, then
678                  * we need to create the deform weight
679                  */
680                 newdw = MEM_callocN (sizeof(MDeformWeight)*(dv->totweight+1), 
681                                                          "deformWeight");
682                 if (dv->dw){
683                         memcpy (newdw, dv->dw, sizeof(MDeformWeight)*dv->totweight);
684                         MEM_freeN (dv->dw);
685                 }
686                 dv->dw=newdw;
687     
688                 dv->dw[dv->totweight].weight=weight;
689                 dv->dw[dv->totweight].def_nr=def_nr;
690     
691                 dv->totweight++;
692                 break;
693         }
694 }
695
696 /* called while not in editmode */
697 void add_vert_to_defgroup (Object *ob, bDeformGroup *dg, int vertnum, 
698                            float weight, int assignmode)
699 {
700         /* add the vert to the deform group with the
701          * specified assign mode
702          */
703         int     def_nr;
704
705         /* get the deform group number, exit if
706          * it can't be found
707          */
708         def_nr = get_defgroup_num(ob, dg);
709         if (def_nr < 0) return;
710
711         /* if there's no deform verts then
712          * create some
713          */
714         if(ob->type==OB_MESH) {
715                 if (!((Mesh*)ob->data)->dvert)
716                         create_dverts(ob->data);
717         }
718         else if(ob->type==OB_LATTICE) {
719                 if (!((Lattice*)ob->data)->dvert)
720                         create_dverts(ob->data);
721         }
722
723         /* call another function to do the work
724          */
725         add_vert_defnr (ob, def_nr, vertnum, weight, assignmode);
726 }
727
728 /* Only available in editmode */
729 void assign_verts_defgroup (Object *ob, float weight)
730 {
731         EditVert *eve;
732         bDeformGroup *dg, *eg;
733         MDeformWeight *newdw;
734         MDeformVert *dvert;
735         int     i, done;
736
737         if (!ob)
738                 return;
739
740         dg=BLI_findlink(&ob->defbase, ob->actdef-1);
741         if (!dg){
742                 error ("No vertex group is active");
743                 return;
744         }
745
746         switch (ob->type){
747         case OB_MESH:
748         {
749                 Mesh *me= ob->data;
750                 EditMesh *em = BKE_mesh_get_editmesh(me);
751
752                 if (!CustomData_has_layer(&em->vdata, CD_MDEFORMVERT))
753                         EM_add_data_layer(em, &em->vdata, CD_MDEFORMVERT);
754
755                 /* Go through the list of editverts and assign them */
756                 for (eve=em->verts.first; eve; eve=eve->next){
757                         dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
758
759                         if (dvert && (eve->f & 1)){
760                                 done=0;
761                                 /* See if this vert already has a reference to this group */
762                                 /*              If so: Change its weight */
763                                 done=0;
764                                 for (i=0; i<dvert->totweight; i++){
765                                         eg = BLI_findlink (&ob->defbase, dvert->dw[i].def_nr);
766                                         /* Find the actual group */
767                                         if (eg==dg){
768                                                 dvert->dw[i].weight= weight;
769                                                 done=1;
770                                                 break;
771                                         }
772                                 }
773                                 /*              If not: Add the group and set its weight */
774                                 if (!done){
775                                         newdw = MEM_callocN (sizeof(MDeformWeight)*(dvert->totweight+1), "deformWeight");
776                                         if (dvert->dw){
777                                                 memcpy (newdw, dvert->dw, sizeof(MDeformWeight)*dvert->totweight);
778                                                 MEM_freeN (dvert->dw);
779                                         }
780                                         dvert->dw=newdw;
781
782                                         dvert->dw[dvert->totweight].weight= weight;
783                                         dvert->dw[dvert->totweight].def_nr= ob->actdef-1;
784
785                                         dvert->totweight++;
786
787                                 }
788                         }
789                 }
790                 BKE_mesh_end_editmesh(me, em);
791         }
792                 break;
793         case OB_LATTICE:
794                 {
795                         Lattice *lt= def_get_lattice(ob);
796                         BPoint *bp;
797                         int a, tot;
798                         
799                         if(lt->dvert==NULL)
800                                 create_dverts(&lt->id);
801                         
802                         tot= lt->pntsu*lt->pntsv*lt->pntsw;
803                         for(a=0, bp= lt->def; a<tot; a++, bp++) {
804                                 if(bp->f1 & SELECT)
805                                         add_vert_defnr (ob, ob->actdef-1, a, weight, WEIGHT_REPLACE);
806                         }
807                 }
808                 break;
809         default:
810                 printf ("Assigning deformation groups to unknown object type\n");
811                 break;
812         }
813
814 }
815
816 /* mesh object mode, lattice can be in editmode */
817 void remove_vert_defgroup (Object *ob, bDeformGroup     *dg, int vertnum)
818 {
819         /* This routine removes the vertex from the specified
820          * deform group.
821          */
822
823         int def_nr;
824
825         /* if the object is NULL abort
826          */
827         if (!ob)
828                 return;
829
830         /* get the deform number that cooresponds
831          * to this deform group, and abort if it
832          * can not be found.
833          */
834         def_nr = get_defgroup_num(ob, dg);
835         if (def_nr < 0) return;
836
837         /* call another routine to do the work
838          */
839         remove_vert_def_nr (ob, def_nr, vertnum);
840 }
841
842 /* for mesh in object mode lattice can be in editmode */
843 static float get_vert_def_nr (Object *ob, int def_nr, int vertnum)
844 {
845         MDeformVert *dvert= NULL;
846         int i;
847
848         /* get the deform vertices corresponding to the
849          * vertnum
850          */
851         if(ob->type==OB_MESH) {
852                 if( ((Mesh*)ob->data)->dvert )
853                         dvert = ((Mesh*)ob->data)->dvert + vertnum;
854         }
855         else if(ob->type==OB_LATTICE) {
856                 Lattice *lt= def_get_lattice(ob);
857                 
858                 if(lt->dvert)
859                         dvert = lt->dvert + vertnum;
860         }
861         
862         if(dvert==NULL)
863                 return 0.0f;
864         
865         for(i=dvert->totweight-1 ; i>=0 ; i--)
866                 if(dvert->dw[i].def_nr == def_nr)
867                         return dvert->dw[i].weight;
868
869         return 0.0f;
870 }
871
872 /* mesh object mode, lattice can be in editmode */
873 float get_vert_defgroup (Object *ob, bDeformGroup *dg, int vertnum)
874 {
875         int def_nr;
876
877         if(!ob)
878                 return 0.0f;
879
880         def_nr = get_defgroup_num(ob, dg);
881         if(def_nr < 0) return 0.0f;
882
883         return get_vert_def_nr (ob, def_nr, vertnum);
884 }
885
886 /* Only available in editmode */
887 /* removes from active defgroup, if allverts==0 only selected vertices */
888 void remove_verts_defgroup (Object *ob, int allverts)
889 {
890         EditVert *eve;
891         MDeformVert *dvert;
892         MDeformWeight *newdw;
893         bDeformGroup *dg, *eg;
894         int     i;
895
896         if (!ob)
897                 return;
898
899         dg=BLI_findlink(&ob->defbase, ob->actdef-1);
900         if (!dg){
901                 error ("No vertex group is active");
902                 return;
903         }
904
905         switch (ob->type){
906         case OB_MESH:
907         {
908                 Mesh *me= ob->data;
909                 EditMesh *em = BKE_mesh_get_editmesh(me);
910
911                 for (eve=em->verts.first; eve; eve=eve->next){
912                         dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
913                 
914                         if (dvert && dvert->dw && ((eve->f & 1) || allverts)){
915                                 for (i=0; i<dvert->totweight; i++){
916                                         /* Find group */
917                                         eg = BLI_findlink (&ob->defbase, dvert->dw[i].def_nr);
918                                         if (eg == dg){
919                                                 dvert->totweight--;
920                                                 if (dvert->totweight){
921                                                         newdw = MEM_mallocN (sizeof(MDeformWeight)*(dvert->totweight), "deformWeight");
922                                                         
923                                                         if (dvert->dw){
924                                                                 memcpy (newdw, dvert->dw, sizeof(MDeformWeight)*i);
925                                                                 memcpy (newdw+i, dvert->dw+i+1, sizeof(MDeformWeight)*(dvert->totweight-i));
926                                                                 MEM_freeN (dvert->dw);
927                                                         }
928                                                         dvert->dw=newdw;
929                                                 }
930                                                 else{
931                                                         MEM_freeN (dvert->dw);
932                                                         dvert->dw=NULL;
933                                                         break;
934                                                 }
935                                         }
936                                 }
937                         }
938                 }
939                 BKE_mesh_end_editmesh(me, em);
940         }
941                 break;
942         case OB_LATTICE:
943         {
944                 Lattice *lt= def_get_lattice(ob);
945                 
946                 if(lt->dvert) {
947                         BPoint *bp;
948                         int a, tot= lt->pntsu*lt->pntsv*lt->pntsw;
949                                 
950                         for(a=0, bp= lt->def; a<tot; a++, bp++) {
951                                 if(allverts || (bp->f1 & SELECT))
952                                         remove_vert_defgroup (ob, dg, a);
953                         }
954                 }
955         }
956                 break;
957                 
958         default:
959                 printf ("Removing deformation groups from unknown object type\n");
960                 break;
961         }
962 }
963
964 /* Only available in editmode */
965 /* removes from all defgroup, if allverts==0 only selected vertices */
966 void remove_verts_defgroups(Object *ob, int allverts)
967 {
968         int actdef, defCount;
969
970         if (ob == NULL) return;
971         
972         actdef= ob->actdef;
973         defCount= BLI_countlist(&ob->defbase);
974         
975         if (defCount == 0) {
976                 error("Object has no vertex groups");
977                 return;
978         }
979         
980         /* To prevent code redundancy, we just use remove_verts_defgroup, but that
981          * only operates on the active vgroup. So we iterate through all groups, by changing
982          * active group index
983          */
984         for (ob->actdef= 1; ob->actdef <= defCount; ob->actdef++)
985                 remove_verts_defgroup(ob, allverts);
986                 
987         ob->actdef= actdef;
988 }
989
990 void vertexgroup_select_by_name(Object *ob, char *name)
991 {
992         bDeformGroup *curdef;
993         int actdef= 1;
994         
995         if(ob==NULL) return;
996         
997         for (curdef = ob->defbase.first; curdef; curdef=curdef->next, actdef++){
998                 if (!strcmp(curdef->name, name)) {
999                         ob->actdef= actdef;
1000                         return;
1001                 }
1002         }
1003         ob->actdef=0;   // this signals on painting to create a new one, if a bone in posemode is selected */
1004 }
1005
1006 /* This function provides a shortcut for adding/removing verts from 
1007  * vertex groups. It is called by the Ctrl-G hotkey in EditMode for Meshes
1008  * and Lattices. (currently only restricted to those two)
1009  * It is only responsible for 
1010  */
1011 void vgroup_assign_with_menu(Scene *scene, Object *ob)
1012 {
1013         VPaint *wp= scene->toolsettings->wpaint;
1014         int defCount;
1015         int mode= 0;
1016         
1017         /* prevent crashes */
1018         if (wp==NULL || ob==NULL) return;
1019         
1020         defCount= BLI_countlist(&ob->defbase);
1021         
1022         /* give user choices of adding to current/new or removing from current */
1023 // XXX  if (defCount && ob->actdef)
1024 //              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");
1025 //      else
1026 //              mode= pupmenu("Vertex Groups %t|Add Selected to New Group %x1");
1027         
1028         /* handle choices */
1029         switch (mode) {
1030                 case 1: /* add to new group */
1031                         add_defgroup(ob);
1032                         assign_verts_defgroup(ob, paint_brush(&wp->paint)->alpha);
1033                         BIF_undo_push("Assign to vertex group");
1034                         break;
1035                 case 2: /* add to current group */
1036                         assign_verts_defgroup(ob, paint_brush(&wp->paint)->alpha);
1037                         BIF_undo_push("Assign to vertex group");
1038                         break;
1039                 case 3: /* remove from current group */
1040                         remove_verts_defgroup(ob, 0);
1041                         BIF_undo_push("Remove from vertex group");
1042                         break;
1043                 case 4: /* remove from all groups */
1044                         remove_verts_defgroups(ob, 0);
1045                         BIF_undo_push("Remove from all vertex groups");
1046                         break;
1047         }
1048 }
1049
1050 /* This function provides a shortcut for commonly used vertex group 
1051  * functions - change weight (not implemented), change active group, delete active group,
1052  * when Ctrl-Shift-G is used in EditMode, for Meshes and Lattices (only for now).
1053  */
1054 void vgroup_operation_with_menu(Object *ob)
1055 {
1056         int defCount;
1057         int mode= 0;
1058         
1059         /* prevent crashes and useless cases */
1060         if (ob==NULL) return;
1061         
1062         defCount= BLI_countlist(&ob->defbase);
1063         if (defCount == 0) return;
1064         
1065         /* give user choices of adding to current/new or removing from current */
1066 // XXX  if (ob->actdef)
1067 //              mode = pupmenu("Vertex Groups %t|Change Active Group%x1|Delete Active Group%x2|Delete All Groups%x3");
1068 //      else
1069 //              mode= pupmenu("Vertex Groups %t|Change Active Group%x1|Delete All Groups%x3");
1070         
1071         /* handle choices */
1072         switch (mode) {
1073                 case 1: /* change active group*/
1074                         {
1075                                 char *menustr= NULL; // XXX get_vertexgroup_menustr(ob);
1076                                 short nr;
1077                                 
1078                                 if (menustr) {
1079 // XXX                                  nr= pupmenu(menustr);
1080                                         
1081                                         if ((nr >= 1) && (nr <= defCount)) 
1082                                                 ob->actdef= nr;
1083                                                 
1084                                         MEM_freeN(menustr);
1085                                 }
1086                         }
1087                         break;
1088                 case 2: /* delete active group  */
1089                         {
1090                                 del_defgroup(ob);
1091                                 BIF_undo_push("Delete vertex group");
1092                         }
1093                         break;
1094                 case 3: /* delete all groups */
1095                         {
1096                                 del_all_defgroups(ob);
1097                                 BIF_undo_push("Delete all vertex groups");
1098                         }
1099                         break;
1100         }
1101 }
1102
1103 /********************** vertex group operators *********************/
1104
1105 static int vertex_group_add_exec(bContext *C, wmOperator *op)
1106 {
1107         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
1108         Scene *scene= CTX_data_scene(C);
1109
1110         if(!ob)
1111                 return OPERATOR_CANCELLED;
1112
1113         add_defgroup(ob);
1114         DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
1115         WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
1116         
1117         return OPERATOR_FINISHED;
1118 }
1119
1120 void OBJECT_OT_vertex_group_add(wmOperatorType *ot)
1121 {
1122         /* identifiers */
1123         ot->name= "Add Vertex Group";
1124         ot->idname= "OBJECT_OT_vertex_group_add";
1125         
1126         /* api callbacks */
1127         ot->exec= vertex_group_add_exec;
1128
1129         /* flags */
1130         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1131 }
1132
1133 static int vertex_group_remove_exec(bContext *C, wmOperator *op)
1134 {
1135         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
1136         Scene *scene= CTX_data_scene(C);
1137
1138         if(!ob)
1139                 return OPERATOR_CANCELLED;
1140
1141         if(scene->obedit == ob) {
1142                 del_defgroup(ob);
1143                 WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
1144         }
1145         else {
1146                 del_defgroup_in_object_mode(ob);
1147                 DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
1148                 WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
1149         }
1150         
1151         return OPERATOR_FINISHED;
1152 }
1153
1154 void OBJECT_OT_vertex_group_remove(wmOperatorType *ot)
1155 {
1156         /* identifiers */
1157         ot->name= "Remove Vertex Group";
1158         ot->idname= "OBJECT_OT_vertex_group_remove";
1159         
1160         /* api callbacks */
1161         ot->exec= vertex_group_remove_exec;
1162
1163         /* flags */
1164         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1165 }
1166
1167 static int vertex_group_assign_exec(bContext *C, wmOperator *op)
1168 {
1169         Scene *scene= CTX_data_scene(C);
1170         ToolSettings *ts= CTX_data_tool_settings(C);
1171         Object *ob= CTX_data_edit_object(C);
1172
1173         if(!ob)
1174                 return OPERATOR_CANCELLED;
1175
1176         assign_verts_defgroup(ob, ts->vgroup_weight);
1177         DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
1178         WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
1179         
1180         return OPERATOR_FINISHED;
1181 }
1182
1183 void OBJECT_OT_vertex_group_assign(wmOperatorType *ot)
1184 {
1185         /* identifiers */
1186         ot->name= "Assign Vertex Group";
1187         ot->idname= "OBJECT_OT_vertex_group_assign";
1188         
1189         /* api callbacks */
1190         ot->exec= vertex_group_assign_exec;
1191
1192         /* flags */
1193         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1194 }
1195
1196 static int vertex_group_remove_from_exec(bContext *C, wmOperator *op)
1197 {
1198         Scene *scene= CTX_data_scene(C);
1199         Object *ob= CTX_data_edit_object(C);
1200
1201         if(!ob)
1202                 return OPERATOR_CANCELLED;
1203
1204         remove_verts_defgroup(ob, 0);
1205         DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
1206         WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
1207         
1208         return OPERATOR_FINISHED;
1209 }
1210
1211 void OBJECT_OT_vertex_group_remove_from(wmOperatorType *ot)
1212 {
1213         /* identifiers */
1214         ot->name= "Remove from Vertex Group";
1215         ot->idname= "OBJECT_OT_vertex_group_remove_from";
1216         
1217         /* api callbacks */
1218         ot->exec= vertex_group_remove_from_exec;
1219
1220         /* flags */
1221         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1222 }
1223
1224 static int vertex_group_select_exec(bContext *C, wmOperator *op)
1225 {
1226         Object *ob= CTX_data_edit_object(C);
1227
1228         if(!ob)
1229                 return OPERATOR_CANCELLED;
1230
1231         sel_verts_defgroup(ob, 1); /* runs countall() */
1232         WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, ob);
1233
1234         return OPERATOR_FINISHED;
1235 }
1236
1237 void OBJECT_OT_vertex_group_select(wmOperatorType *ot)
1238 {
1239         /* identifiers */
1240         ot->name= "Select Vertex Group";
1241         ot->idname= "OBJECT_OT_vertex_group_select";
1242         
1243         /* api callbacks */
1244         ot->exec= vertex_group_select_exec;
1245
1246         /* flags */
1247         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1248 }
1249
1250 static int vertex_group_deselect_exec(bContext *C, wmOperator *op)
1251 {
1252         Object *ob= CTX_data_edit_object(C);
1253
1254         if(!ob)
1255                 return OPERATOR_CANCELLED;
1256
1257         sel_verts_defgroup(ob, 0); /* runs countall() */
1258         WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, ob);
1259
1260         return OPERATOR_FINISHED;
1261 }
1262
1263 void OBJECT_OT_vertex_group_deselect(wmOperatorType *ot)
1264 {
1265         /* identifiers */
1266         ot->name= "Deselect Vertex Group";
1267         ot->idname= "OBJECT_OT_vertex_group_deselect";
1268         
1269         /* api callbacks */
1270         ot->exec= vertex_group_deselect_exec;
1271
1272         /* flags */
1273         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1274 }
1275
1276 static int vertex_group_copy_exec(bContext *C, wmOperator *op)
1277 {
1278         Scene *scene= CTX_data_scene(C);
1279         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
1280
1281         if(!ob)
1282                 return OPERATOR_CANCELLED;
1283
1284         duplicate_defgroup(ob);
1285         DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
1286         WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
1287         
1288         return OPERATOR_FINISHED;
1289 }
1290
1291 void OBJECT_OT_vertex_group_copy(wmOperatorType *ot)
1292 {
1293         /* identifiers */
1294         ot->name= "Copy Vertex Group";
1295         ot->idname= "OBJECT_OT_vertex_group_copy";
1296         
1297         /* api callbacks */
1298         ot->exec= vertex_group_copy_exec;
1299
1300         /* flags */
1301         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1302 }
1303
1304 static int vertex_group_copy_to_linked_exec(bContext *C, wmOperator *op)
1305 {
1306         Scene *scene= CTX_data_scene(C);
1307         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
1308     Base *base;
1309         int retval= OPERATOR_CANCELLED;
1310
1311         if(!ob)
1312                 return retval;
1313
1314     for(base=scene->base.first; base; base= base->next) {
1315         if(base->object->type==ob->type) {
1316             if(base->object!=ob && base->object->data==ob->data) {
1317                 BLI_freelistN(&base->object->defbase);
1318                 BLI_duplicatelist(&base->object->defbase, &ob->defbase);
1319                 base->object->actdef= ob->actdef;
1320
1321                 DAG_object_flush_update(scene, base->object, OB_RECALC_DATA);
1322                                 WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, base->object);
1323
1324                                 retval = OPERATOR_FINISHED;
1325             }
1326         }
1327     }
1328         
1329         return retval;
1330 }
1331
1332 void OBJECT_OT_vertex_group_copy_to_linked(wmOperatorType *ot)
1333 {
1334         /* identifiers */
1335         ot->name= "Copy Vertex Group to Linked";
1336         ot->idname= "OBJECT_OT_vertex_group_copy_to_linked";
1337         
1338         /* api callbacks */
1339         ot->exec= vertex_group_copy_to_linked_exec;
1340
1341         /* flags */
1342         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1343 }
1344