3ccd4d56ece7b5daec9b1e515b466308dc8b2885
[blender-staging.git] / source / blender / editors / mesh / editdeform.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_customdata.h"
52 #include "BKE_DerivedMesh.h"
53 #include "BKE_depsgraph.h"
54 #include "BKE_deform.h"
55 #include "BKE_displist.h"
56 #include "BKE_global.h"
57 #include "BKE_lattice.h"
58 #include "BKE_mesh.h"
59 #include "BKE_utildefines.h"
60
61 #include "ED_mesh.h"
62 #include "ED_view3d.h"
63 #include "mesh_intern.h"
64
65 /* XXX */
66 static void BIF_undo_push() {}
67 static void error() {}
68
69 static Lattice *def_get_lattice(Object *ob)
70 {
71         if(ob->type==OB_LATTICE) {
72                 Lattice *lt= ob->data;
73                 if(lt->editlatt)
74                         return lt->editlatt;
75                 return lt;
76         }
77         return NULL;
78 }
79
80 /* only in editmode */
81 void sel_verts_defgroup (Object *obedit, int select)
82 {
83         EditVert *eve;
84         Object *ob;
85         int i;
86         MDeformVert *dvert;
87
88         ob= obedit;
89
90         if (!ob)
91                 return;
92
93         switch (ob->type){
94         case OB_MESH:
95         {
96                 Mesh *me= ob->data;
97                 EditMesh *em = BKE_mesh_get_editmesh(me);
98
99                 for (eve=em->verts.first; eve; eve=eve->next){
100                         dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
101
102                         if (dvert && dvert->totweight){
103                                 for (i=0; i<dvert->totweight; i++){
104                                         if (dvert->dw[i].def_nr == (ob->actdef-1)){
105                                                 if (select) eve->f |= SELECT;
106                                                 else eve->f &= ~SELECT;
107                                                 
108                                                 break;
109                                         }
110                                 }
111                         }
112                 }
113                 /* this has to be called, because this function operates on vertices only */
114                 if(select) EM_select_flush(em); // vertices to edges/faces
115                 else EM_deselect_flush(em);
116
117                 BKE_mesh_end_editmesh(me, em);
118         }
119                 break;
120         case OB_LATTICE:
121         {
122                 Lattice *lt= def_get_lattice(ob);
123                 
124                 if(lt->dvert) {
125                         BPoint *bp;
126                         int a, tot;
127                         
128                         dvert= lt->dvert;
129
130                         tot= lt->pntsu*lt->pntsv*lt->pntsw;
131                         for(a=0, bp= lt->def; a<tot; a++, bp++, dvert++) {
132                                 for (i=0; i<dvert->totweight; i++){
133                                         if (dvert->dw[i].def_nr == (ob->actdef-1)) {
134                                                 if(select) bp->f1 |= SELECT;
135                                                 else bp->f1 &= ~SELECT;
136                                                 
137                                                 break;
138                                         }
139                                 }
140                         }
141                 }
142         }
143                 break;
144                 
145         default:
146                 break;
147         }
148 }
149
150 /* check if deform vertex has defgroup index */
151 MDeformWeight *get_defweight (MDeformVert *dv, int defgroup)
152 {
153         int i;
154         
155         if (!dv || defgroup<0)
156                 return NULL;
157         
158         for (i=0; i<dv->totweight; i++){
159                 if (dv->dw[i].def_nr == defgroup)
160                         return dv->dw+i;
161         }
162         return NULL;
163 }
164
165 /* Ensures that mv has a deform weight entry for
166    the specified defweight group */
167 /* Note this function is mirrored in editmesh_tools.c, for use for editvertices */
168 MDeformWeight *verify_defweight (MDeformVert *dv, int defgroup)
169 {
170         MDeformWeight *newdw;
171
172         /* do this check always, this function is used to check for it */
173         if (!dv || defgroup<0)
174                 return NULL;
175         
176         newdw = get_defweight (dv, defgroup);
177         if (newdw)
178                 return newdw;
179         
180         newdw = MEM_callocN (sizeof(MDeformWeight)*(dv->totweight+1), "deformWeight");
181         if (dv->dw){
182                 memcpy (newdw, dv->dw, sizeof(MDeformWeight)*dv->totweight);
183                 MEM_freeN (dv->dw);
184         }
185         dv->dw=newdw;
186         
187         dv->dw[dv->totweight].weight=0.0f;
188         dv->dw[dv->totweight].def_nr=defgroup;
189         /* Group index */
190         
191         dv->totweight++;
192
193         return dv->dw+(dv->totweight-1);
194 }
195
196 bDeformGroup *add_defgroup_name (Object *ob, char *name)
197 {
198         bDeformGroup    *defgroup;
199         
200         if (!ob)
201                 return NULL;
202         
203         defgroup = MEM_callocN (sizeof(bDeformGroup), "add deformGroup");
204
205         BLI_strncpy (defgroup->name, name, 32);
206
207         BLI_addtail(&ob->defbase, defgroup);
208         unique_vertexgroup_name(defgroup, ob);
209
210         ob->actdef = BLI_countlist(&ob->defbase);
211
212         return defgroup;
213 }
214
215 void add_defgroup (Object *ob) 
216 {
217         add_defgroup_name (ob, "Group");
218 }
219
220
221 void duplicate_defgroup ( Object *ob )
222 {
223         bDeformGroup *dg, *cdg;
224         char name[32], s[32];
225         MDeformWeight *org, *cpy;
226         MDeformVert *dvert, *dvert_array;
227         int i, idg, icdg, dvert_tot;
228
229         if (ob->type != OB_MESH && ob->type != OB_LATTICE)
230                 return;
231
232         dg = BLI_findlink (&ob->defbase, (ob->actdef-1));
233         if (!dg)
234                 return;
235         
236         if (strstr(dg->name, "_copy")) {
237                 BLI_strncpy (name, dg->name, 32); /* will be renamed _copy.001... etc */
238         } else {
239                 BLI_snprintf (name, 32, "%s_copy", dg->name);
240                 while (get_named_vertexgroup (ob, name)) {
241                         if ((strlen (name) + 6) > 32) {
242                                 error ("Error: the name for the new group is > 32 characters");
243                                 return;
244                         }
245                         strcpy (s, name);
246                         BLI_snprintf (name, 32, "%s_copy", s);
247                 }
248         }               
249
250         cdg = copy_defgroup (dg);
251         strcpy (cdg->name, name);
252         unique_vertexgroup_name(cdg, ob);
253         
254         BLI_addtail (&ob->defbase, cdg);
255
256         idg = (ob->actdef-1);
257         ob->actdef = BLI_countlist (&ob->defbase);
258         icdg = (ob->actdef-1);
259
260         if(ob->type == OB_MESH) {
261                 Mesh *me = get_mesh (ob);
262                 dvert_array= me->dvert;
263                 dvert_tot= me->totvert;
264         }
265         else if (ob->type == OB_LATTICE) {
266                 Lattice *lt= (Lattice *)ob->data;
267                 dvert_array= lt->dvert;
268                 dvert_tot= lt->pntsu*lt->pntsv*lt->pntsw;
269         }
270         
271         if (!dvert_array)
272                 return;
273
274         for (i = 0; i < dvert_tot; i++) {
275                 dvert = dvert_array+i;
276                 org = get_defweight (dvert, idg);
277                 if (org) {
278                         float weight = org->weight;
279                         /* verify_defweight re-allocs org so need to store the weight first */
280                         cpy = verify_defweight (dvert, icdg);
281                         cpy->weight = weight;
282                 }
283         }
284 }
285
286 static void del_defgroup_update_users(Object *ob, int id)
287 {
288         ExplodeModifierData *emd;
289         ModifierData *md;
290         ParticleSystem *psys;
291         ClothModifierData *clmd;
292         ClothSimSettings *clsim;
293         int a;
294
295         /* these cases don't use names to refer to vertex groups, so when
296          * they get deleted the numbers get out of sync, this corrects that */
297
298         if(ob->soft) {
299                 if(ob->soft->vertgroup == id)
300                         ob->soft->vertgroup= 0;
301                 else if(ob->soft->vertgroup > id)
302                         ob->soft->vertgroup--;
303         }
304
305         for(md=ob->modifiers.first; md; md=md->next) {
306                 if(md->type == eModifierType_Explode) {
307                         emd= (ExplodeModifierData*)md;
308
309                         if(emd->vgroup == id)
310                                 emd->vgroup= 0;
311                         else if(emd->vgroup > id)
312                                 emd->vgroup--;
313                 }
314                 else if(md->type == eModifierType_Cloth) {
315                         clmd= (ClothModifierData*)md;
316                         clsim= clmd->sim_parms;
317
318                         if(clsim) {
319                                 if(clsim->vgroup_mass == id)
320                                         clsim->vgroup_mass= 0;
321                                 else if(clsim->vgroup_mass > id)
322                                         clsim->vgroup_mass--;
323
324                                 if(clsim->vgroup_bend == id)
325                                         clsim->vgroup_bend= 0;
326                                 else if(clsim->vgroup_bend > id)
327                                         clsim->vgroup_bend--;
328
329                                 if(clsim->vgroup_struct == id)
330                                         clsim->vgroup_struct= 0;
331                                 else if(clsim->vgroup_struct > id)
332                                         clsim->vgroup_struct--;
333                         }
334                 }
335         }
336
337         for(psys=ob->particlesystem.first; psys; psys=psys->next) {
338                 for(a=0; a<PSYS_TOT_VG; a++)
339                         if(psys->vgroup[a] == id)
340                                 psys->vgroup[a]= 0;
341                         else if(psys->vgroup[a] > id)
342                                 psys->vgroup[a]--;
343         }
344 }
345
346 void del_defgroup_in_object_mode ( Object *ob )
347 {
348         bDeformGroup *dg;
349         MDeformVert *dvert_array, *dvert;
350         
351         int i, e, dvert_tot;
352
353         if ((!ob) || (ob->type != OB_MESH && ob->type != OB_LATTICE))
354                 return;
355
356         if(ob->type == OB_MESH) {
357                 Mesh *me = get_mesh (ob);
358                 dvert_array= me->dvert;
359                 dvert_tot= me->totvert;
360         }
361         else if (ob->type == OB_LATTICE) {
362                 Lattice *lt= (Lattice *)ob->data;
363                 dvert_array= lt->dvert;
364                 dvert_tot= lt->pntsu*lt->pntsv*lt->pntsw;
365         }
366         
367         dg = BLI_findlink (&ob->defbase, (ob->actdef-1));
368         if (!dg)
369                 return;
370         
371         if (dvert_array) {
372                 for (i = 0; i < dvert_tot; i++) {
373                         dvert = dvert_array + i;
374                         if (dvert) {
375                                 if (get_defweight (dvert, (ob->actdef-1)))
376                                         remove_vert_defgroup (ob, dg, i);
377                         }
378                 }
379
380                 for (i = 0; i < dvert_tot; i++) {
381                         dvert = dvert_array+i;
382                         if (dvert) {
383                                 for (e = 0; e < dvert->totweight; e++) {
384                                         if (dvert->dw[e].def_nr > (ob->actdef-1))
385                                                 dvert->dw[e].def_nr--;
386                                 }
387                         }
388                 }
389         }
390
391         del_defgroup_update_users(ob, ob->actdef);
392
393         /* Update the active deform index if necessary */
394         if (ob->actdef == BLI_countlist(&ob->defbase))
395                 ob->actdef--;
396   
397         /* Remove the group */
398         BLI_freelinkN (&ob->defbase, dg);
399 }
400
401 void del_defgroup (Object *ob)
402 {
403         bDeformGroup    *defgroup;
404         int                             i;
405
406         if (!ob)
407                 return;
408
409         if (!ob->actdef)
410                 return;
411
412         defgroup = BLI_findlink(&ob->defbase, ob->actdef-1);
413         if (!defgroup)
414                 return;
415
416         /* Make sure that no verts are using this group */
417         remove_verts_defgroup(ob, 1);
418
419         /* Make sure that any verts with higher indices are adjusted accordingly */
420         if(ob->type==OB_MESH) {
421                 Mesh *me= ob->data;
422                 EditMesh *em = BKE_mesh_get_editmesh(me);
423                 EditVert *eve;
424                 MDeformVert *dvert;
425                 
426                 for (eve=em->verts.first; eve; eve=eve->next){
427                         dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
428
429                         if (dvert)
430                                 for (i=0; i<dvert->totweight; i++)
431                                         if (dvert->dw[i].def_nr > (ob->actdef-1))
432                                                 dvert->dw[i].def_nr--;
433                 }
434                 BKE_mesh_end_editmesh(me, em);
435         }
436         else if(ob->type==OB_LATTICE) {
437                 Lattice *lt= def_get_lattice(ob);
438                 BPoint *bp;
439                 MDeformVert *dvert= lt->dvert;
440                 int a, tot;
441                 
442                 if (dvert) {
443                         tot= lt->pntsu*lt->pntsv*lt->pntsw;
444                         for(a=0, bp= lt->def; a<tot; a++, bp++, dvert++) {
445                                 for (i=0; i<dvert->totweight; i++){
446                                         if (dvert->dw[i].def_nr > (ob->actdef-1))
447                                                 dvert->dw[i].def_nr--;
448                                 }
449                         }
450                 }
451         }
452
453         del_defgroup_update_users(ob, ob->actdef);
454
455         /* Update the active deform index if necessary */
456         if (ob->actdef==BLI_countlist(&ob->defbase))
457                 ob->actdef--;
458         
459         /* Remove the group */
460         BLI_freelinkN (&ob->defbase, defgroup);
461         
462         /* remove all dverts */
463         if(ob->actdef==0) {
464                 if(ob->type==OB_MESH) {
465                         Mesh *me= ob->data;
466                         CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert);
467                         me->dvert= NULL;
468                 }
469                 else if(ob->type==OB_LATTICE) {
470                         Lattice *lt= def_get_lattice(ob);
471                         if (lt->dvert) {
472                                 MEM_freeN(lt->dvert);
473                                 lt->dvert= NULL;
474                         }
475                 }
476         }
477 }
478
479 void del_all_defgroups (Object *ob)
480 {
481         /* Sanity check */
482         if (ob == NULL)
483                 return;
484         
485         /* Remove all DVerts */
486         if (ob->type==OB_MESH) {
487                 Mesh *me= ob->data;
488                 CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert);
489                 me->dvert= NULL;
490         }
491         else if(ob->type==OB_LATTICE) {
492                 Lattice *lt= def_get_lattice(ob);
493                 if (lt->dvert) {
494                         MEM_freeN(lt->dvert);
495                         lt->dvert= NULL;
496                 }
497         }
498         
499         /* Remove all DefGroups */
500         BLI_freelistN(&ob->defbase);
501         
502         /* Fix counters/indices */
503         ob->actdef= 0;
504 }
505
506 void create_dverts(ID *id)
507 {
508         /* create deform verts
509          */
510
511         if( GS(id->name)==ID_ME) {
512                 Mesh *me= (Mesh *)id;
513                 me->dvert= CustomData_add_layer(&me->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, me->totvert);
514         }
515         else if( GS(id->name)==ID_LT) {
516                 Lattice *lt= (Lattice *)id;
517                 lt->dvert= MEM_callocN(sizeof(MDeformVert)*lt->pntsu*lt->pntsv*lt->pntsw, "lattice deformVert");
518         }
519 }
520
521 /* for mesh in object mode
522    lattice can be in editmode */
523 void remove_vert_def_nr (Object *ob, int def_nr, int vertnum)
524 {
525         /* This routine removes the vertex from the deform
526          * group with number def_nr.
527          *
528          * This routine is meant to be fast, so it is the
529          * responsibility of the calling routine to:
530          *   a) test whether ob is non-NULL
531          *   b) test whether ob is a mesh
532          *   c) calculate def_nr
533          */
534
535         MDeformWeight *newdw;
536         MDeformVert *dvert= NULL;
537         int i;
538
539         /* get the deform vertices corresponding to the
540          * vertnum
541          */
542         if(ob->type==OB_MESH) {
543                 if( ((Mesh*)ob->data)->dvert )
544                         dvert = ((Mesh*)ob->data)->dvert + vertnum;
545         }
546         else if(ob->type==OB_LATTICE) {
547                 Lattice *lt= def_get_lattice(ob);
548                 
549                 if(lt->dvert)
550                         dvert = lt->dvert + vertnum;
551         }
552         
553         if(dvert==NULL)
554                 return;
555         
556         /* for all of the deform weights in the
557          * deform vert
558          */
559         for (i=dvert->totweight - 1 ; i>=0 ; i--){
560
561                 /* if the def_nr is the same as the one
562                  * for our weight group then remove it
563                  * from this deform vert.
564                  */
565                 if (dvert->dw[i].def_nr == def_nr) {
566                         dvert->totweight--;
567         
568                         /* if there are still other deform weights
569                          * attached to this vert then remove this
570                          * deform weight, and reshuffle the others
571                          */
572                         if (dvert->totweight) {
573                                 newdw = MEM_mallocN (sizeof(MDeformWeight)*(dvert->totweight), 
574                                                                          "deformWeight");
575                                 if (dvert->dw){
576                                         memcpy (newdw, dvert->dw, sizeof(MDeformWeight)*i);
577                                         memcpy (newdw+i, dvert->dw+i+1, 
578                                                         sizeof(MDeformWeight)*(dvert->totweight-i));
579                                         MEM_freeN (dvert->dw);
580                                 }
581                                 dvert->dw=newdw;
582                         }
583                         /* if there are no other deform weights
584                          * left then just remove the deform weight
585                          */
586                         else {
587                                 MEM_freeN (dvert->dw);
588                                 dvert->dw = NULL;
589                                 break;
590                         }
591                 }
592         }
593
594 }
595
596 /* for Mesh in Object mode */
597 /* allows editmode for Lattice */
598 void add_vert_defnr (Object *ob, int def_nr, int vertnum, 
599                            float weight, int assignmode)
600 {
601         /* add the vert to the deform group with the
602          * specified number
603          */
604         MDeformVert *dv= NULL;
605         MDeformWeight *newdw;
606         int     i;
607
608         /* get the vert */
609         if(ob->type==OB_MESH) {
610                 if(((Mesh*)ob->data)->dvert)
611                         dv = ((Mesh*)ob->data)->dvert + vertnum;
612         }
613         else if(ob->type==OB_LATTICE) {
614                 Lattice *lt= def_get_lattice(ob);
615                 
616                 if(lt->dvert)
617                         dv = lt->dvert + vertnum;
618         }
619         
620         if(dv==NULL)
621                 return;
622         
623         /* Lets first check to see if this vert is
624          * already in the weight group -- if so
625          * lets update it
626          */
627         for (i=0; i<dv->totweight; i++){
628                 
629                 /* if this weight cooresponds to the
630                  * deform group, then add it using
631                  * the assign mode provided
632                  */
633                 if (dv->dw[i].def_nr == def_nr){
634                         
635                         switch (assignmode) {
636                         case WEIGHT_REPLACE:
637                                 dv->dw[i].weight=weight;
638                                 break;
639                         case WEIGHT_ADD:
640                                 dv->dw[i].weight+=weight;
641                                 if (dv->dw[i].weight >= 1.0)
642                                         dv->dw[i].weight = 1.0;
643                                 break;
644                         case WEIGHT_SUBTRACT:
645                                 dv->dw[i].weight-=weight;
646                                 /* if the weight is zero or less then
647                                  * remove the vert from the deform group
648                                  */
649                                 if (dv->dw[i].weight <= 0.0)
650                                         remove_vert_def_nr(ob, def_nr, vertnum);
651                                 break;
652                         }
653                         return;
654                 }
655         }
656
657         /* if the vert wasn't in the deform group then
658          * we must take a different form of action ...
659          */
660
661         switch (assignmode) {
662         case WEIGHT_SUBTRACT:
663                 /* if we are subtracting then we don't
664                  * need to do anything
665                  */
666                 return;
667
668         case WEIGHT_REPLACE:
669         case WEIGHT_ADD:
670                 /* if we are doing an additive assignment, then
671                  * we need to create the deform weight
672                  */
673                 newdw = MEM_callocN (sizeof(MDeformWeight)*(dv->totweight+1), 
674                                                          "deformWeight");
675                 if (dv->dw){
676                         memcpy (newdw, dv->dw, sizeof(MDeformWeight)*dv->totweight);
677                         MEM_freeN (dv->dw);
678                 }
679                 dv->dw=newdw;
680     
681                 dv->dw[dv->totweight].weight=weight;
682                 dv->dw[dv->totweight].def_nr=def_nr;
683     
684                 dv->totweight++;
685                 break;
686         }
687 }
688
689 /* called while not in editmode */
690 void add_vert_to_defgroup (Object *ob, bDeformGroup *dg, int vertnum, 
691                            float weight, int assignmode)
692 {
693         /* add the vert to the deform group with the
694          * specified assign mode
695          */
696         int     def_nr;
697
698         /* get the deform group number, exit if
699          * it can't be found
700          */
701         def_nr = get_defgroup_num(ob, dg);
702         if (def_nr < 0) return;
703
704         /* if there's no deform verts then
705          * create some
706          */
707         if(ob->type==OB_MESH) {
708                 if (!((Mesh*)ob->data)->dvert)
709                         create_dverts(ob->data);
710         }
711         else if(ob->type==OB_LATTICE) {
712                 if (!((Lattice*)ob->data)->dvert)
713                         create_dverts(ob->data);
714         }
715
716         /* call another function to do the work
717          */
718         add_vert_defnr (ob, def_nr, vertnum, weight, assignmode);
719 }
720
721 /* Only available in editmode */
722 void assign_verts_defgroup (Object *obedit, float weight)
723 {
724         Object *ob;
725         EditVert *eve;
726         bDeformGroup *dg, *eg;
727         MDeformWeight *newdw;
728         MDeformVert *dvert;
729         int     i, done;
730         
731 // XXX  if(multires_level1_test()) return;
732
733         ob= obedit;
734
735         if (!ob)
736                 return;
737
738         dg=BLI_findlink(&ob->defbase, ob->actdef-1);
739         if (!dg){
740                 error ("No vertex group is active");
741                 return;
742         }
743
744         switch (ob->type){
745         case OB_MESH:
746         {
747                 Mesh *me= ob->data;
748                 EditMesh *em = BKE_mesh_get_editmesh(me);
749
750                 if (!CustomData_has_layer(&em->vdata, CD_MDEFORMVERT))
751                         EM_add_data_layer(em, &em->vdata, CD_MDEFORMVERT);
752
753                 /* Go through the list of editverts and assign them */
754                 for (eve=em->verts.first; eve; eve=eve->next){
755                         dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
756
757                         if (dvert && (eve->f & 1)){
758                                 done=0;
759                                 /* See if this vert already has a reference to this group */
760                                 /*              If so: Change its weight */
761                                 done=0;
762                                 for (i=0; i<dvert->totweight; i++){
763                                         eg = BLI_findlink (&ob->defbase, dvert->dw[i].def_nr);
764                                         /* Find the actual group */
765                                         if (eg==dg){
766                                                 dvert->dw[i].weight= weight;
767                                                 done=1;
768                                                 break;
769                                         }
770                                 }
771                                 /*              If not: Add the group and set its weight */
772                                 if (!done){
773                                         newdw = MEM_callocN (sizeof(MDeformWeight)*(dvert->totweight+1), "deformWeight");
774                                         if (dvert->dw){
775                                                 memcpy (newdw, dvert->dw, sizeof(MDeformWeight)*dvert->totweight);
776                                                 MEM_freeN (dvert->dw);
777                                         }
778                                         dvert->dw=newdw;
779
780                                         dvert->dw[dvert->totweight].weight= weight;
781                                         dvert->dw[dvert->totweight].def_nr= ob->actdef-1;
782
783                                         dvert->totweight++;
784
785                                 }
786                         }
787                 }
788                 BKE_mesh_end_editmesh(me, em);
789         }
790                 break;
791         case OB_LATTICE:
792                 {
793                         Lattice *lt= def_get_lattice(ob);
794                         BPoint *bp;
795                         int a, tot;
796                         
797                         if(lt->dvert==NULL)
798                                 create_dverts(&lt->id);
799                         
800                         tot= lt->pntsu*lt->pntsv*lt->pntsw;
801                         for(a=0, bp= lt->def; a<tot; a++, bp++) {
802                                 if(bp->f1 & SELECT)
803                                         add_vert_defnr (ob, ob->actdef-1, a, weight, WEIGHT_REPLACE);
804                         }
805                 }
806                 break;
807         default:
808                 printf ("Assigning deformation groups to unknown object type\n");
809                 break;
810         }
811
812 }
813
814 /* mesh object mode, lattice can be in editmode */
815 void remove_vert_defgroup (Object *ob, bDeformGroup     *dg, int vertnum)
816 {
817         /* This routine removes the vertex from the specified
818          * deform group.
819          */
820
821         int def_nr;
822
823         /* if the object is NULL abort
824          */
825         if (!ob)
826                 return;
827
828         /* get the deform number that cooresponds
829          * to this deform group, and abort if it
830          * can not be found.
831          */
832         def_nr = get_defgroup_num(ob, dg);
833         if (def_nr < 0) return;
834
835         /* call another routine to do the work
836          */
837         remove_vert_def_nr (ob, def_nr, vertnum);
838 }
839
840 /* for mesh in object mode lattice can be in editmode */
841 static float get_vert_def_nr (Object *ob, int def_nr, int vertnum)
842 {
843         MDeformVert *dvert= NULL;
844         int i;
845
846         /* get the deform vertices corresponding to the
847          * vertnum
848          */
849         if(ob->type==OB_MESH) {
850                 if( ((Mesh*)ob->data)->dvert )
851                         dvert = ((Mesh*)ob->data)->dvert + vertnum;
852         }
853         else if(ob->type==OB_LATTICE) {
854                 Lattice *lt= def_get_lattice(ob);
855                 
856                 if(lt->dvert)
857                         dvert = lt->dvert + vertnum;
858         }
859         
860         if(dvert==NULL)
861                 return 0.0f;
862         
863         for(i=dvert->totweight-1 ; i>=0 ; i--)
864                 if(dvert->dw[i].def_nr == def_nr)
865                         return dvert->dw[i].weight;
866
867         return 0.0f;
868 }
869
870 /* mesh object mode, lattice can be in editmode */
871 float get_vert_defgroup (Object *ob, bDeformGroup *dg, int vertnum)
872 {
873         int def_nr;
874
875         if(!ob)
876                 return 0.0f;
877
878         def_nr = get_defgroup_num(ob, dg);
879         if(def_nr < 0) return 0.0f;
880
881         return get_vert_def_nr (ob, def_nr, vertnum);
882 }
883
884 /* Only available in editmode */
885 /* removes from active defgroup, if allverts==0 only selected vertices */
886 void remove_verts_defgroup (Object *obedit, int allverts)
887 {
888         Object *ob;
889         EditVert *eve;
890         MDeformVert *dvert;
891         MDeformWeight *newdw;
892         bDeformGroup *dg, *eg;
893         int     i;
894         
895 // XXX  if(multires_level1_test()) return;
896
897         ob= obedit;
898
899         if (!ob)
900                 return;
901
902         dg=BLI_findlink(&ob->defbase, ob->actdef-1);
903         if (!dg){
904                 error ("No vertex group is active");
905                 return;
906         }
907
908         switch (ob->type){
909         case OB_MESH:
910         {
911                 Mesh *me= ob->data;
912                 EditMesh *em = BKE_mesh_get_editmesh(me);
913
914                 for (eve=em->verts.first; eve; eve=eve->next){
915                         dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
916                 
917                         if (dvert && dvert->dw && ((eve->f & 1) || allverts)){
918                                 for (i=0; i<dvert->totweight; i++){
919                                         /* Find group */
920                                         eg = BLI_findlink (&ob->defbase, dvert->dw[i].def_nr);
921                                         if (eg == dg){
922                                                 dvert->totweight--;
923                                                 if (dvert->totweight){
924                                                         newdw = MEM_mallocN (sizeof(MDeformWeight)*(dvert->totweight), "deformWeight");
925                                                         
926                                                         if (dvert->dw){
927                                                                 memcpy (newdw, dvert->dw, sizeof(MDeformWeight)*i);
928                                                                 memcpy (newdw+i, dvert->dw+i+1, sizeof(MDeformWeight)*(dvert->totweight-i));
929                                                                 MEM_freeN (dvert->dw);
930                                                         }
931                                                         dvert->dw=newdw;
932                                                 }
933                                                 else{
934                                                         MEM_freeN (dvert->dw);
935                                                         dvert->dw=NULL;
936                                                         break;
937                                                 }
938                                         }
939                                 }
940                         }
941                 }
942                 BKE_mesh_end_editmesh(me, em);
943         }
944                 break;
945         case OB_LATTICE:
946         {
947                 Lattice *lt= def_get_lattice(ob);
948                 
949                 if(lt->dvert) {
950                         BPoint *bp;
951                         int a, tot= lt->pntsu*lt->pntsv*lt->pntsw;
952                                 
953                         for(a=0, bp= lt->def; a<tot; a++, bp++) {
954                                 if(allverts || (bp->f1 & SELECT))
955                                         remove_vert_defgroup (ob, dg, a);
956                         }
957                 }
958         }
959                 break;
960                 
961         default:
962                 printf ("Removing deformation groups from unknown object type\n");
963                 break;
964         }
965 }
966
967 /* Only available in editmode */
968 /* removes from all defgroup, if allverts==0 only selected vertices */
969 void remove_verts_defgroups(Object *obedit, int allverts)
970 {
971         Object *ob;
972         int actdef, defCount;
973         
974 //  XXX if (multires_level1_test()) return;
975
976         ob= obedit;
977         if (ob == NULL) return;
978         
979         actdef= ob->actdef;
980         defCount= BLI_countlist(&ob->defbase);
981         
982         if (defCount == 0) {
983                 error("Object has no vertex groups");
984                 return;
985         }
986         
987         /* To prevent code redundancy, we just use remove_verts_defgroup, but that
988          * only operates on the active vgroup. So we iterate through all groups, by changing
989          * active group index
990          */
991         for (ob->actdef= 1; ob->actdef <= defCount; ob->actdef++)
992                 remove_verts_defgroup(ob, allverts);
993                 
994         ob->actdef= actdef;
995 }
996
997 void vertexgroup_select_by_name(Object *ob, char *name)
998 {
999         bDeformGroup *curdef;
1000         int actdef= 1;
1001         
1002         if(ob==NULL) return;
1003         
1004         for (curdef = ob->defbase.first; curdef; curdef=curdef->next, actdef++){
1005                 if (!strcmp(curdef->name, name)) {
1006                         ob->actdef= actdef;
1007                         return;
1008                 }
1009         }
1010         ob->actdef=0;   // this signals on painting to create a new one, if a bone in posemode is selected */
1011 }
1012
1013 /* This function provides a shortcut for adding/removing verts from 
1014  * vertex groups. It is called by the Ctrl-G hotkey in EditMode for Meshes
1015  * and Lattices. (currently only restricted to those two)
1016  * It is only responsible for 
1017  */
1018 void vgroup_assign_with_menu(Scene *scene, Object *ob)
1019 {
1020         VPaint *wp= scene->toolsettings->wpaint;
1021         int defCount;
1022         int mode= 0;
1023         
1024         /* prevent crashes */
1025         if (wp==NULL || ob==NULL) return;
1026         
1027         defCount= BLI_countlist(&ob->defbase);
1028         
1029         /* give user choices of adding to current/new or removing from current */
1030 // XXX  if (defCount && ob->actdef)
1031 //              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");
1032 //      else
1033 //              mode= pupmenu("Vertex Groups %t|Add Selected to New Group %x1");
1034         
1035         /* handle choices */
1036         switch (mode) {
1037                 case 1: /* add to new group */
1038                         add_defgroup(ob);
1039                         assign_verts_defgroup(ob, wp->brush->alpha);
1040                         BIF_undo_push("Assign to vertex group");
1041                         break;
1042                 case 2: /* add to current group */
1043                         assign_verts_defgroup(ob, wp->brush->alpha);
1044                         BIF_undo_push("Assign to vertex group");
1045                         break;
1046                 case 3: /* remove from current group */
1047                         remove_verts_defgroup(ob, 0);
1048                         BIF_undo_push("Remove from vertex group");
1049                         break;
1050                 case 4: /* remove from all groups */
1051                         remove_verts_defgroups(ob, 0);
1052                         BIF_undo_push("Remove from all vertex groups");
1053                         break;
1054         }
1055 }
1056
1057 /* This function provides a shortcut for commonly used vertex group 
1058  * functions - change weight (not implemented), change active group, delete active group,
1059  * when Ctrl-Shift-G is used in EditMode, for Meshes and Lattices (only for now).
1060  */
1061 void vgroup_operation_with_menu(Object *ob)
1062 {
1063         int defCount;
1064         int mode= 0;
1065         
1066         /* prevent crashes and useless cases */
1067         if (ob==NULL) return;
1068         
1069         defCount= BLI_countlist(&ob->defbase);
1070         if (defCount == 0) return;
1071         
1072         /* give user choices of adding to current/new or removing from current */
1073 // XXX  if (ob->actdef)
1074 //              mode = pupmenu("Vertex Groups %t|Change Active Group%x1|Delete Active Group%x2|Delete All Groups%x3");
1075 //      else
1076 //              mode= pupmenu("Vertex Groups %t|Change Active Group%x1|Delete All Groups%x3");
1077         
1078         /* handle choices */
1079         switch (mode) {
1080                 case 1: /* change active group*/
1081                         {
1082                                 char *menustr= NULL; // XXX get_vertexgroup_menustr(ob);
1083                                 short nr;
1084                                 
1085                                 if (menustr) {
1086 // XXX                                  nr= pupmenu(menustr);
1087                                         
1088                                         if ((nr >= 1) && (nr <= defCount)) 
1089                                                 ob->actdef= nr;
1090                                                 
1091                                         MEM_freeN(menustr);
1092                                 }
1093                         }
1094                         break;
1095                 case 2: /* delete active group  */
1096                         {
1097                                 del_defgroup(ob);
1098                                 BIF_undo_push("Delete vertex group");
1099                         }
1100                         break;
1101                 case 3: /* delete all groups */
1102                         {
1103                                 del_all_defgroups(ob);
1104                                 BIF_undo_push("Delete all vertex groups");
1105                         }
1106                         break;
1107         }
1108 }
1109
1110