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