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