=== Custom Transform Orientation ===
[blender.git] / source / blender / src / editdeform.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL 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. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  * Creator-specific support for vertex deformation groups
32  * Added: apply deform function (ton)
33  */
34
35 #include <string.h>
36
37 #include "MEM_guardedalloc.h"
38
39 #include "DNA_curve_types.h"
40 #include "DNA_lattice_types.h"
41 #include "DNA_mesh_types.h"
42 #include "DNA_meshdata_types.h"
43 #include "DNA_object_types.h"
44
45 #include "BLI_blenlib.h"
46 #include "BLI_editVert.h"
47
48 #include "BKE_customdata.h"
49 #include "BKE_DerivedMesh.h"
50 #include "BKE_depsgraph.h"
51 #include "BKE_deform.h"
52 #include "BKE_displist.h"
53 #include "BKE_global.h"
54 #include "BKE_lattice.h"
55 #include "BKE_mesh.h"
56 #include "BKE_utildefines.h"
57
58 #include "BIF_interface.h"
59 #include "BIF_editdeform.h"
60 #include "BIF_editmesh.h"
61 #include "BIF_space.h"
62 #include "BIF_toolbox.h"
63
64 #include "BSE_edit.h"
65
66 #include "butspace.h"
67 #include "mydevice.h"
68 #include "editmesh.h"
69 #include "multires.h"
70
71 #ifdef HAVE_CONFIG_H
72 #include <config.h>
73 #endif
74
75 /* only in editmode */
76 void sel_verts_defgroup (int select)
77 {
78         EditVert *eve;
79         Object *ob;
80         int i;
81         MDeformVert *dvert;
82
83         ob= G.obedit;
84
85         if (!ob)
86                 return;
87
88         switch (ob->type){
89         case OB_MESH:
90                 for (eve=G.editMesh->verts.first; eve; eve=eve->next){
91                         dvert= CustomData_em_get(&G.editMesh->vdata, eve->data, CD_MDEFORMVERT);
92
93                         if (dvert && dvert->totweight){
94                                 for (i=0; i<dvert->totweight; i++){
95                                         if (dvert->dw[i].def_nr == (ob->actdef-1)){
96                                                 if (select) eve->f |= SELECT;
97                                                 else eve->f &= ~SELECT;
98                                                 
99                                                 break;
100                                         }
101                                 }
102                         }
103                 }
104                 /* this has to be called, because this function operates on vertices only */
105                 if(select) EM_select_flush();   // vertices to edges/faces
106                 else EM_deselect_flush();
107                 
108                 break;
109         case OB_LATTICE:
110                 if(editLatt->dvert) {
111                         BPoint *bp;
112                         int a, tot;
113                         
114                         dvert= editLatt->dvert;
115
116                         tot= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
117                         for(a=0, bp= editLatt->def; a<tot; a++, bp++, dvert++) {
118                                 for (i=0; i<dvert->totweight; i++){
119                                         if (dvert->dw[i].def_nr == (ob->actdef-1)) {
120                                                 if(select) bp->f1 |= SELECT;
121                                                 else bp->f1 &= ~SELECT;
122                                                 
123                                                 break;
124                                         }
125                                 }
126                         }
127                 }       
128                 break;
129                 
130         default:
131                 break;
132         }
133         
134         countall();
135         
136 }
137
138 /* check if deform vertex has defgroup index */
139 MDeformWeight *get_defweight (MDeformVert *dv, int defgroup)
140 {
141         int i;
142         
143         if (!dv || defgroup<0)
144                 return NULL;
145         
146         for (i=0; i<dv->totweight; i++){
147                 if (dv->dw[i].def_nr == defgroup)
148                         return dv->dw+i;
149         }
150         return NULL;
151 }
152
153 /* Ensures that mv has a deform weight entry for
154    the specified defweight group */
155 /* Note this function is mirrored in editmesh_tools.c, for use for editvertices */
156 MDeformWeight *verify_defweight (MDeformVert *dv, int defgroup)
157 {
158         MDeformWeight *newdw;
159
160         /* do this check always, this function is used to check for it */
161         if (!dv || defgroup<0)
162                 return NULL;
163         
164         newdw = get_defweight (dv, defgroup);
165         if (newdw)
166                 return newdw;
167         
168         newdw = MEM_callocN (sizeof(MDeformWeight)*(dv->totweight+1), "deformWeight");
169         if (dv->dw){
170                 memcpy (newdw, dv->dw, sizeof(MDeformWeight)*dv->totweight);
171                 MEM_freeN (dv->dw);
172         }
173         dv->dw=newdw;
174         
175         dv->dw[dv->totweight].weight=0.0f;
176         dv->dw[dv->totweight].def_nr=defgroup;
177         /* Group index */
178         
179         dv->totweight++;
180
181         return dv->dw+(dv->totweight-1);
182 }
183
184 void add_defgroup (Object *ob) 
185 {
186         add_defgroup_name (ob, "Group");
187 }
188
189 bDeformGroup *add_defgroup_name (Object *ob, char *name)
190 {
191         bDeformGroup    *defgroup;
192         
193         if (!ob)
194                 return NULL;
195         
196         defgroup = MEM_callocN (sizeof(bDeformGroup), "add deformGroup");
197
198         BLI_strncpy (defgroup->name, name, 32);
199
200         BLI_addtail(&ob->defbase, defgroup);
201         unique_vertexgroup_name(defgroup, ob);
202
203         ob->actdef = BLI_countlist(&ob->defbase);
204
205         return defgroup;
206 }
207
208 void duplicate_defgroup ( Object *ob )
209 {
210         bDeformGroup *dg, *cdg;
211         char name[32], s[32];
212         MDeformWeight *org, *cpy;
213         MDeformVert *dvert;
214         Mesh *me;
215         int i, idg, icdg;
216
217         if (ob->type != OB_MESH)
218                 return;
219
220         dg = BLI_findlink (&ob->defbase, (ob->actdef-1));
221         if (!dg)
222                 return;
223
224         BLI_snprintf (name, 32, "%s_copy", dg->name);
225         while (get_named_vertexgroup (ob, name)) {
226                 if ((strlen (name) + 6) > 32) {
227                         error ("Error: the name for the new group is > 32 characters");
228                         return;
229                 }
230                 strcpy (s, name);
231                 BLI_snprintf (name, 32, "%s_copy", s);
232         }
233
234         cdg = copy_defgroup (dg);
235         strcpy (cdg->name, name);
236         BLI_addtail (&ob->defbase, cdg);
237
238         idg = (ob->actdef-1);
239         ob->actdef = BLI_countlist (&ob->defbase);
240         icdg = (ob->actdef-1);
241
242         me = get_mesh (ob);
243         if (!me->dvert)
244                 return;
245
246         for (i = 0; i < me->totvert; i++) {
247                 dvert = me->dvert+i;
248                 org = get_defweight (dvert, idg);
249                 if (org) {
250                         cpy = verify_defweight (dvert, icdg);
251                         cpy->weight = org->weight;
252                 }
253         }
254 }
255
256 void del_defgroup_in_object_mode ( Object *ob )
257 {
258         bDeformGroup *dg;
259         MDeformVert *dvert;
260         Mesh *me;
261         int i, e;
262
263         if ((!ob) || (ob->type != OB_MESH))
264                 return;
265
266         dg = BLI_findlink (&ob->defbase, (ob->actdef-1));
267         if (!dg)
268                 return;
269
270         me = get_mesh (ob);
271         if (me->dvert) {
272                 for (i = 0; i < me->totvert; i++) {
273                         dvert = me->dvert + i;
274                         if (dvert) {
275                                 if (get_defweight (dvert, (ob->actdef-1)))
276                                         remove_vert_defgroup (ob, dg, i);
277                         }
278                 }
279
280                 for (i = 0; i < me->totvert; i++) {
281                         dvert = me->dvert+i;
282                         if (dvert) {
283                                 for (e = 0; e < dvert->totweight; e++) {
284                                         if (dvert->dw[e].def_nr > (ob->actdef-1))
285                                                 dvert->dw[e].def_nr--;
286                                 }
287                         }
288                 }
289         }
290
291         /* Update the active deform index if necessary */
292         if (ob->actdef == BLI_countlist(&ob->defbase))
293                 ob->actdef--;
294   
295         /* Remove the group */
296         BLI_freelinkN (&ob->defbase, dg);
297 }
298
299 void del_defgroup (Object *ob)
300 {
301         bDeformGroup    *defgroup;
302         int                             i;
303
304         if (!ob)
305                 return;
306
307         if (!ob->actdef)
308                 return;
309
310         defgroup = BLI_findlink(&ob->defbase, ob->actdef-1);
311         if (!defgroup)
312                 return;
313
314         /* Make sure that no verts are using this group */
315         remove_verts_defgroup(1);
316
317         /* Make sure that any verts with higher indices are adjusted accordingly */
318         if(ob->type==OB_MESH) {
319                 EditMesh *em = G.editMesh;
320                 EditVert *eve;
321                 MDeformVert *dvert;
322                 
323                 for (eve=em->verts.first; eve; eve=eve->next){
324                         dvert= CustomData_em_get(&G.editMesh->vdata, eve->data, CD_MDEFORMVERT);
325
326                         if (dvert)
327                                 for (i=0; i<dvert->totweight; i++)
328                                         if (dvert->dw[i].def_nr > (ob->actdef-1))
329                                                 dvert->dw[i].def_nr--;
330                 }
331         }
332         else {
333                 BPoint *bp;
334                 MDeformVert *dvert= editLatt->dvert;
335                 int a, tot;
336                 
337                 if (dvert) {
338                         tot= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
339                         for(a=0, bp= editLatt->def; a<tot; a++, bp++, dvert++) {
340                                 for (i=0; i<dvert->totweight; i++){
341                                         if (dvert->dw[i].def_nr > (ob->actdef-1))
342                                                 dvert->dw[i].def_nr--;
343                                 }
344                         }
345                 }
346         }
347
348         /* Update the active deform index if necessary */
349         if (ob->actdef==BLI_countlist(&ob->defbase))
350                 ob->actdef--;
351         
352         /* Remove the group */
353         BLI_freelinkN (&ob->defbase, defgroup);
354         
355         /* remove all dverts */
356         if(ob->actdef==0) {
357                 if(ob->type==OB_MESH) {
358                         Mesh *me= ob->data;
359                         CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert);
360                         me->dvert= NULL;
361                 }
362                 else {
363                         if (editLatt->dvert) {
364                                 MEM_freeN(editLatt->dvert);
365                                 editLatt->dvert= NULL;
366                         }
367                 }
368         }
369 }
370
371 void create_dverts(ID *id)
372 {
373         /* create deform verts
374          */
375
376         if( GS(id->name)==ID_ME) {
377                 Mesh *me= (Mesh *)id;
378                 me->dvert= CustomData_add_layer(&me->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, me->totvert);
379         }
380         else if( GS(id->name)==ID_LT) {
381                 Lattice *lt= (Lattice *)id;
382                 lt->dvert= MEM_callocN(sizeof(MDeformVert)*lt->pntsu*lt->pntsv*lt->pntsw, "lattice deformVert");
383         }
384 }
385
386 /* for mesh in object mode
387    lattice can be in editmode */
388 void remove_vert_def_nr (Object *ob, int def_nr, int vertnum)
389 {
390         /* This routine removes the vertex from the deform
391          * group with number def_nr.
392          *
393          * This routine is meant to be fast, so it is the
394          * responsibility of the calling routine to:
395          *   a) test whether ob is non-NULL
396          *   b) test whether ob is a mesh
397          *   c) calculate def_nr
398          */
399
400         MDeformWeight *newdw;
401         MDeformVert *dvert= NULL;
402         int i;
403
404         /* get the deform vertices corresponding to the
405          * vertnum
406          */
407         if(ob->type==OB_MESH) {
408                 if( ((Mesh*)ob->data)->dvert )
409                         dvert = ((Mesh*)ob->data)->dvert + vertnum;
410         }
411         else if(ob->type==OB_LATTICE) {
412                 Lattice *lt= ob->data;
413                 
414                 if(ob==G.obedit)
415                         lt= editLatt;
416                 
417                 if(lt->dvert)
418                         dvert = lt->dvert + vertnum;
419         }
420         
421         if(dvert==NULL)
422                 return;
423         
424         /* for all of the deform weights in the
425          * deform vert
426          */
427         for (i=dvert->totweight - 1 ; i>=0 ; i--){
428
429                 /* if the def_nr is the same as the one
430                  * for our weight group then remove it
431                  * from this deform vert.
432                  */
433                 if (dvert->dw[i].def_nr == def_nr) {
434                         dvert->totweight--;
435         
436                         /* if there are still other deform weights
437                          * attached to this vert then remove this
438                          * deform weight, and reshuffle the others
439                          */
440                         if (dvert->totweight) {
441                                 newdw = MEM_mallocN (sizeof(MDeformWeight)*(dvert->totweight), 
442                                                                          "deformWeight");
443                                 if (dvert->dw){
444                                         memcpy (newdw, dvert->dw, sizeof(MDeformWeight)*i);
445                                         memcpy (newdw+i, dvert->dw+i+1, 
446                                                         sizeof(MDeformWeight)*(dvert->totweight-i));
447                                         MEM_freeN (dvert->dw);
448                                 }
449                                 dvert->dw=newdw;
450                         }
451                         /* if there are no other deform weights
452                          * left then just remove the deform weight
453                          */
454                         else {
455                                 MEM_freeN (dvert->dw);
456                                 dvert->dw = NULL;
457                                 break;
458                         }
459                 }
460         }
461
462 }
463
464 /* for Mesh in Object mode */
465 /* allows editmode for Lattice */
466 void add_vert_defnr (Object *ob, int def_nr, int vertnum, 
467                            float weight, int assignmode)
468 {
469         /* add the vert to the deform group with the
470          * specified number
471          */
472         MDeformVert *dv= NULL;
473         MDeformWeight *newdw;
474         int     i;
475
476         /* get the vert */
477         if(ob->type==OB_MESH) {
478                 if(((Mesh*)ob->data)->dvert)
479                         dv = ((Mesh*)ob->data)->dvert + vertnum;
480         }
481         else if(ob->type==OB_LATTICE) {
482                 Lattice *lt;
483                 
484                 if(ob==G.obedit)
485                         lt= editLatt;
486                 else
487                         lt= ob->data;
488                         
489                 if(lt->dvert)
490                         dv = lt->dvert + vertnum;
491         }
492         
493         if(dv==NULL)
494                 return;
495         
496         /* Lets first check to see if this vert is
497          * already in the weight group -- if so
498          * lets update it
499          */
500         for (i=0; i<dv->totweight; i++){
501                 
502                 /* if this weight cooresponds to the
503                  * deform group, then add it using
504                  * the assign mode provided
505                  */
506                 if (dv->dw[i].def_nr == def_nr){
507                         
508                         switch (assignmode) {
509                         case WEIGHT_REPLACE:
510                                 dv->dw[i].weight=weight;
511                                 break;
512                         case WEIGHT_ADD:
513                                 dv->dw[i].weight+=weight;
514                                 if (dv->dw[i].weight >= 1.0)
515                                         dv->dw[i].weight = 1.0;
516                                 break;
517                         case WEIGHT_SUBTRACT:
518                                 dv->dw[i].weight-=weight;
519                                 /* if the weight is zero or less then
520                                  * remove the vert from the deform group
521                                  */
522                                 if (dv->dw[i].weight <= 0.0)
523                                         remove_vert_def_nr(ob, def_nr, vertnum);
524                                 break;
525                         }
526                         return;
527                 }
528         }
529
530         /* if the vert wasn't in the deform group then
531          * we must take a different form of action ...
532          */
533
534         switch (assignmode) {
535         case WEIGHT_SUBTRACT:
536                 /* if we are subtracting then we don't
537                  * need to do anything
538                  */
539                 return;
540
541         case WEIGHT_REPLACE:
542         case WEIGHT_ADD:
543                 /* if we are doing an additive assignment, then
544                  * we need to create the deform weight
545                  */
546                 newdw = MEM_callocN (sizeof(MDeformWeight)*(dv->totweight+1), 
547                                                          "deformWeight");
548                 if (dv->dw){
549                         memcpy (newdw, dv->dw, sizeof(MDeformWeight)*dv->totweight);
550                         MEM_freeN (dv->dw);
551                 }
552                 dv->dw=newdw;
553     
554                 dv->dw[dv->totweight].weight=weight;
555                 dv->dw[dv->totweight].def_nr=def_nr;
556     
557                 dv->totweight++;
558                 break;
559         }
560 }
561
562 /* called while not in editmode */
563 void add_vert_to_defgroup (Object *ob, bDeformGroup *dg, int vertnum, 
564                            float weight, int assignmode)
565 {
566         /* add the vert to the deform group with the
567          * specified assign mode
568          */
569         int     def_nr;
570
571         /* get the deform group number, exit if
572          * it can't be found
573          */
574         def_nr = get_defgroup_num(ob, dg);
575         if (def_nr < 0) return;
576
577         /* if there's no deform verts then
578          * create some
579          */
580         if(ob->type==OB_MESH) {
581                 if (!((Mesh*)ob->data)->dvert)
582                         create_dverts(ob->data);
583         }
584         else if(ob->type==OB_LATTICE) {
585                 if (!((Lattice*)ob->data)->dvert)
586                         create_dverts(ob->data);
587         }
588
589         /* call another function to do the work
590          */
591         add_vert_defnr (ob, def_nr, vertnum, weight, assignmode);
592 }
593
594 /* Only available in editmode */
595 void assign_verts_defgroup (void)
596 {
597         extern float editbutvweight;    /* buttons.c */
598         Object *ob;
599         EditVert *eve;
600         bDeformGroup *dg, *eg;
601         MDeformWeight *newdw;
602         MDeformVert *dvert;
603         int     i, done;
604         
605         if(multires_level1_test()) return;
606
607         ob= G.obedit;
608
609         if (!ob)
610                 return;
611
612         dg=BLI_findlink(&ob->defbase, ob->actdef-1);
613         if (!dg){
614                 error ("No vertex group is active");
615                 return;
616         }
617
618         switch (ob->type){
619         case OB_MESH:
620                 if (!CustomData_has_layer(&G.editMesh->vdata, CD_MDEFORMVERT))
621                         EM_add_data_layer(&G.editMesh->vdata, CD_MDEFORMVERT);
622
623                 /* Go through the list of editverts and assign them */
624                 for (eve=G.editMesh->verts.first; eve; eve=eve->next){
625                         dvert= CustomData_em_get(&G.editMesh->vdata, eve->data, CD_MDEFORMVERT);
626
627                         if (dvert && (eve->f & 1)){
628                                 done=0;
629                                 /* See if this vert already has a reference to this group */
630                                 /*              If so: Change its weight */
631                                 done=0;
632                                 for (i=0; i<dvert->totweight; i++){
633                                         eg = BLI_findlink (&ob->defbase, dvert->dw[i].def_nr);
634                                         /* Find the actual group */
635                                         if (eg==dg){
636                                                 dvert->dw[i].weight=editbutvweight;
637                                                 done=1;
638                                                 break;
639                                         }
640                                 }
641                                 /*              If not: Add the group and set its weight */
642                                 if (!done){
643                                         newdw = MEM_callocN (sizeof(MDeformWeight)*(dvert->totweight+1), "deformWeight");
644                                         if (dvert->dw){
645                                                 memcpy (newdw, dvert->dw, sizeof(MDeformWeight)*dvert->totweight);
646                                                 MEM_freeN (dvert->dw);
647                                         }
648                                         dvert->dw=newdw;
649
650                                         dvert->dw[dvert->totweight].weight= editbutvweight;
651                                         dvert->dw[dvert->totweight].def_nr= ob->actdef-1;
652
653                                         dvert->totweight++;
654
655                                 }
656                         }
657                 }
658                 break;
659         case OB_LATTICE:
660                 {
661                         BPoint *bp;
662                         int a, tot;
663                         
664                         if(editLatt->dvert==NULL)
665                                 create_dverts(&editLatt->id);
666                         
667                         tot= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
668                         for(a=0, bp= editLatt->def; a<tot; a++, bp++) {
669                                 if(bp->f1 & SELECT)
670                                         add_vert_defnr (ob, ob->actdef-1, a, editbutvweight, WEIGHT_REPLACE);
671                         }
672                 }       
673                 break;
674         default:
675                 printf ("Assigning deformation groups to unknown object type\n");
676                 break;
677         }
678
679 }
680
681 /* mesh object mode, lattice can be in editmode */
682 void remove_vert_defgroup (Object *ob, bDeformGroup     *dg, int vertnum)
683 {
684         /* This routine removes the vertex from the specified
685          * deform group.
686          */
687
688         int def_nr;
689
690         /* if the object is NULL abort
691          */
692         if (!ob)
693                 return;
694
695         /* get the deform number that cooresponds
696          * to this deform group, and abort if it
697          * can not be found.
698          */
699         def_nr = get_defgroup_num(ob, dg);
700         if (def_nr < 0) return;
701
702         /* call another routine to do the work
703          */
704         remove_vert_def_nr (ob, def_nr, vertnum);
705 }
706
707 /* for mesh in object mode lattice can be in editmode */
708 static float get_vert_def_nr (Object *ob, int def_nr, int vertnum)
709 {
710         MDeformVert *dvert= NULL;
711         int i;
712
713         /* get the deform vertices corresponding to the
714          * vertnum
715          */
716         if(ob->type==OB_MESH) {
717                 if( ((Mesh*)ob->data)->dvert )
718                         dvert = ((Mesh*)ob->data)->dvert + vertnum;
719         }
720         else if(ob->type==OB_LATTICE) {
721                 Lattice *lt= ob->data;
722                 
723                 if(ob==G.obedit)
724                         lt= editLatt;
725                 
726                 if(lt->dvert)
727                         dvert = lt->dvert + vertnum;
728         }
729         
730         if(dvert==NULL)
731                 return 0.0f;
732         
733         for(i=dvert->totweight-1 ; i>=0 ; i--)
734                 if(dvert->dw[i].def_nr == def_nr)
735                         return dvert->dw[i].weight;
736
737         return 0.0f;
738 }
739
740 /* mesh object mode, lattice can be in editmode */
741 float get_vert_defgroup (Object *ob, bDeformGroup *dg, int vertnum)
742 {
743         int def_nr;
744
745         if(!ob)
746                 return 0.0f;
747
748         def_nr = get_defgroup_num(ob, dg);
749         if(def_nr < 0) return 0.0f;
750
751         return get_vert_def_nr (ob, def_nr, vertnum);
752 }
753
754 /* Only available in editmode */
755 /* removes from active defgroup, if allverts==0 only selected vertices */
756 void remove_verts_defgroup (int allverts)
757 {
758         Object *ob;
759         EditVert *eve;
760         MDeformVert *dvert;
761         MDeformWeight *newdw;
762         bDeformGroup *dg, *eg;
763         int     i;
764         
765         if(multires_level1_test()) return;
766
767         ob= G.obedit;
768
769         if (!ob)
770                 return;
771
772         dg=BLI_findlink(&ob->defbase, ob->actdef-1);
773         if (!dg){
774                 error ("No vertex group is active");
775                 return;
776         }
777
778         switch (ob->type){
779         case OB_MESH:
780                 for (eve=G.editMesh->verts.first; eve; eve=eve->next){
781                         dvert= CustomData_em_get(&G.editMesh->vdata, eve->data, CD_MDEFORMVERT);
782
783                         if (dvert && dvert->dw && ((eve->f & 1) || allverts)){
784                                 for (i=0; i<dvert->totweight; i++){
785                                         /* Find group */
786                                         eg = BLI_findlink (&ob->defbase, dvert->dw[i].def_nr);
787                                         if (eg == dg){
788                                                 dvert->totweight--;
789                                                 if (dvert->totweight){
790                                                         newdw = MEM_mallocN (sizeof(MDeformWeight)*(dvert->totweight), "deformWeight");
791                                                         
792                                                         if (dvert->dw){
793                                                                 memcpy (newdw, dvert->dw, sizeof(MDeformWeight)*i);
794                                                                 memcpy (newdw+i, dvert->dw+i+1, sizeof(MDeformWeight)*(dvert->totweight-i));
795                                                                 MEM_freeN (dvert->dw);
796                                                         }
797                                                         dvert->dw=newdw;
798                                                 }
799                                                 else{
800                                                         MEM_freeN (dvert->dw);
801                                                         dvert->dw=NULL;
802                                                         break;
803                                                 }
804                                         }
805                                 }
806                         }
807                 }
808                 break;
809         case OB_LATTICE:
810                 
811                 if(editLatt->dvert) {
812                         BPoint *bp;
813                         int a, tot= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
814                                 
815                         for(a=0, bp= editLatt->def; a<tot; a++, bp++) {
816                                 if(allverts || (bp->f1 & SELECT))
817                                         remove_vert_defgroup (ob, dg, a);
818                         }
819                 }
820                 break;
821                 
822         default:
823                 printf ("Removing deformation groups from unknown object type\n");
824                 break;
825         }
826 }
827
828 void vertexgroup_select_by_name(Object *ob, char *name)
829 {
830         bDeformGroup *curdef;
831         int actdef= 1;
832         
833         if(ob==NULL) return;
834         
835         for (curdef = ob->defbase.first; curdef; curdef=curdef->next, actdef++){
836                 if (!strcmp(curdef->name, name)) {
837                         ob->actdef= actdef;
838                         return;
839                 }
840         }
841         ob->actdef=0;   // this signals on painting to create a new one, if a bone in posemode is selected */
842 }
843
844 /* This function provides a shortcut for adding/removing verts from 
845  * vertex groups. It is called by the Ctrl-G hotkey in EditMode for Meshes
846  * and Lattices. (currently only restricted to those two)
847  * It is only responsible for 
848  */
849 void vgroup_assign_with_menu(void)
850 {
851         Object *ob= G.obedit;
852         int defCount;
853         int mode;
854         
855         /* prevent crashes */
856         if (ob==NULL) return;
857         
858         defCount= BLI_countlist(&ob->defbase);
859         
860         /* give user choices of adding to current/new or removing from current */
861         if (defCount && ob->actdef)
862                 mode = pupmenu("Vertex Groups %t|Add Selected to New Group %x1|Add Selected to Active Group %x2|Remove Selected from Active Group %x3");
863         else
864                 mode= pupmenu("Vertex Groups %t|Add Selected to New Group %x1");
865         
866         /* handle choices */
867         switch (mode) {
868                 case 1: /* add to new group */
869                         add_defgroup(ob);
870                         assign_verts_defgroup();
871                         allqueue(REDRAWVIEW3D, 1);
872                         BIF_undo_push("Assign to vertex group");
873                         break;
874                 case 2: /* add to current group */
875                         assign_verts_defgroup();
876                         allqueue(REDRAWVIEW3D, 1);
877                         BIF_undo_push("Assign to vertex group");
878                         break;
879                 case 3: /* remove from current group */
880                         remove_verts_defgroup(0);
881                         allqueue(REDRAWVIEW3D, 1);
882                         BIF_undo_push("Remove from vertex group");
883                         break;
884         }
885 }
886
887 /* This function provides a shortcut for commonly used vertex group 
888  * functions - change weight (not implemented), change active group, delete active group,
889  * when Ctrl-Shift-G is used in EditMode, for Meshes and Lattices (only for now).
890  */
891 void vgroup_operation_with_menu(void)
892 {
893         Object *ob= G.obedit;
894         int defCount;
895         int mode;
896         
897         /* prevent crashes and useless cases */
898         if (ob==NULL) return;
899         
900         defCount= BLI_countlist(&ob->defbase);
901         if (defCount == 0) return;
902         
903         /* give user choices of adding to current/new or removing from current */
904         if (ob->actdef)
905                 mode = pupmenu("Vertex Groups %t|Change Active Group%x1|Delete Active Group%x2");
906         else
907                 mode= pupmenu("Vertex Groups %t|Change Active Group%x1");
908         
909         /* handle choices */
910         switch (mode) {
911                 case 1: /* change active group*/
912                         {
913                                 char *menustr= get_vertexgroup_menustr(ob);
914                                 short nr;
915                                 
916                                 if (menustr) {
917                                         nr= pupmenu(menustr);
918                                         
919                                         if ((nr >= 1) && (nr <= defCount)) 
920                                                 ob->actdef= nr;
921                                                 
922                                         MEM_freeN(menustr);
923                                 }
924                                 allqueue(REDRAWBUTSALL, 0);
925                         }
926                         break;
927                 case 2: /* delete active group  */
928                         {
929                                 del_defgroup(ob);
930                                 allqueue (REDRAWVIEW3D, 1);
931                                 allqueue(REDRAWOOPS, 0);
932                                 BIF_undo_push("Delete vertex group");
933                         }
934                         break;
935         }
936 }
937
938 /* ******************* other deform edit stuff ********** */
939
940 void object_apply_deform(Object *ob)
941 {
942         notice("Apply Deformation now only availble in Modifier buttons");
943 }
944