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