053151e5c4b00403eab3c19e458c11b9ced6107f
[blender.git] / source / blender / src / editdeform.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  * Creator-specific support for vertex deformation groups
32  * Added: apply deform function (ton)
33  */
34
35 #include <string.h>
36
37 #include "MEM_guardedalloc.h"
38
39 #include "DNA_curve_types.h"
40 #include "DNA_mesh_types.h"
41 #include "DNA_meshdata_types.h"
42 #include "DNA_object_types.h"
43
44 #include "BLI_blenlib.h"
45 #include "BLI_editVert.h"
46
47 #include "BKE_DerivedMesh.h"
48 #include "BKE_depsgraph.h"
49 #include "BKE_global.h"
50 #include "BKE_deform.h"
51 #include "BKE_displist.h"
52 #include "BKE_mesh.h"
53
54 #include "BIF_editdeform.h"
55 #include "BIF_editmesh.h"
56 #include "BIF_toolbox.h"
57
58 #include "BSE_edit.h"
59
60 #ifdef HAVE_CONFIG_H
61 #include <config.h>
62 #endif
63
64 /* ----------------- function prototypes ---------------- */
65 void remove_vert_def_nr (Object *, int , int );
66 void add_vert_defnr (Object *, int , int vertnum, float , int );
67
68
69 void sel_verts_defgroup (int select)
70 {
71         EditMesh *em = G.editMesh;
72         EditVert                *eve;
73         Object                  *ob;
74         int                             i;
75
76         ob=G.obedit;
77
78         if (!ob)
79                 return;
80
81         switch (ob->type){
82         case OB_MESH:
83                 for (eve=em->verts.first; eve; eve=eve->next){
84                         if (eve->totweight){
85                                 for (i=0; i<eve->totweight; i++){
86                                         if (eve->dw[i].def_nr == (ob->actdef-1)){
87                                                 if (select) eve->f |= SELECT;
88                                                 else eve->f &= ~SELECT;
89                                                 
90                                                 break;
91                                         }
92                                 }
93                         }
94                 }
95                 break;
96         default:
97                 break;
98         }
99         countall();
100         /* this has to be called, because this function operates on vertices only */
101         if(select) EM_select_flush();   // vertices to edges/faces
102         else EM_deselect_flush();
103 }
104
105 MDeformWeight *verify_defweight (MDeformVert *dv, int defgroup)
106 /* Ensures that mv has a deform weight entry for
107 the specified defweight group */
108 {
109         int     i;
110         MDeformWeight *newdw;
111
112         if (!dv)
113                 return NULL;
114
115         for (i=0; i<dv->totweight; i++){
116                 if (dv->dw[i].def_nr == defgroup)
117                         return dv->dw+i;
118         }
119
120         newdw = MEM_callocN (sizeof(MDeformWeight)*(dv->totweight+1), "deformWeight");
121         if (dv->dw){
122                 memcpy (newdw, dv->dw, sizeof(MDeformWeight)*dv->totweight);
123                 MEM_freeN (dv->dw);
124         }
125         dv->dw=newdw;
126         
127         dv->dw[dv->totweight].weight=0;
128         dv->dw[dv->totweight].def_nr=defgroup;
129         /* Group index */
130         
131         dv->totweight++;
132
133         return dv->dw+(dv->totweight-1);
134 }
135
136 void add_defgroup (Object *ob) {
137         add_defgroup_name (ob, "Group");
138 }
139
140 bDeformGroup *add_defgroup_name (Object *ob, char *name)
141 {
142         bDeformGroup    *defgroup;
143         
144         if (!ob)
145                 return NULL;
146         
147         defgroup = MEM_callocN (sizeof(bDeformGroup), "deformGroup");
148
149         /* I think there should be some length
150          * checking here -- don't know why NaN
151          * never checks name lengths (see
152          * unique_vertexgroup_name, for example).
153          */
154         strcpy (defgroup->name, name);
155
156         BLI_addtail(&ob->defbase, defgroup);
157         unique_vertexgroup_name(defgroup, ob);
158
159         ob->actdef = BLI_countlist(&ob->defbase);
160
161         return defgroup;
162 }
163
164 void del_defgroup (Object *ob)
165 {
166         EditMesh *em = G.editMesh;
167         bDeformGroup    *defgroup;
168         EditVert                *eve;
169         int                             i;
170
171
172         if (!ob)
173                 return;
174
175         if (!ob->actdef)
176                 return;
177
178         defgroup = BLI_findlink(&ob->defbase, ob->actdef-1);
179         if (!defgroup)
180                 return;
181
182         /* Make sure that no verts are using this group */
183         remove_verts_defgroup(1);
184
185         /* Make sure that any verts with higher indices are adjusted accordingly */
186         for (eve=em->verts.first; eve; eve=eve->next){
187                 for (i=0; i<eve->totweight; i++){
188                         if (eve->dw[i].def_nr > (ob->actdef-1))
189                                 eve->dw[i].def_nr--;
190                 }
191         }
192
193         /* Update the active material index if necessary */
194         if (ob->actdef==BLI_countlist(&ob->defbase))
195                 ob->actdef--;
196         
197         /* Remove the group */
198         BLI_freelinkN (&ob->defbase, defgroup);
199         
200         /* remove all dverts */
201         if(ob->actdef==0) {
202                 Mesh *me= ob->data;
203                 free_dverts(me->dvert, me->totvert);
204                 me->dvert= NULL;
205         }
206 }
207
208 void create_dverts(Mesh *me)
209 {
210         /* create deform verts for the mesh
211          */
212         int i;
213
214         me->dvert= MEM_mallocN(sizeof(MDeformVert)*me->totvert, "deformVert");
215         for (i=0; i < me->totvert; ++i) {
216                 me->dvert[i].totweight = 0;
217                 me->dvert[i].dw        = NULL;
218         }
219 }
220
221 void remove_vert_def_nr (Object *ob, int def_nr, int vertnum)
222 {
223         /* This routine removes the vertex from the deform
224          * group with number def_nr.
225          *
226          * This routine is meant to be fast, so it is the
227          * responsibility of the calling routine to:
228          *   a) test whether ob is non-NULL
229          *   b) test whether ob is a mesh
230          *   c) calculate def_nr
231          */
232
233         MDeformWeight *newdw;
234         MDeformVert *dvert;
235         int i;
236
237         /* if this mesh has no deform mesh abort
238          */
239         if (!((Mesh*)ob->data)->dvert) return;
240
241         /* get the deform mesh cooresponding to the
242          * vertnum
243          */
244         dvert = ((Mesh*)ob->data)->dvert + vertnum;
245
246         /* for all of the deform weights in the
247          * deform vert
248          */
249         for (i=dvert->totweight - 1 ; i>=0 ; i--){
250
251                 /* if the def_nr is the same as the one
252                  * for our weight group then remove it
253                  * from this deform vert.
254                  */
255                 if (dvert->dw[i].def_nr == def_nr) {
256                         dvert->totweight--;
257         
258                         /* if there are still other deform weights
259                          * attached to this vert then remove this
260                          * deform weight, and reshuffle the others
261                          */
262                         if (dvert->totweight) {
263                                 newdw = MEM_mallocN (sizeof(MDeformWeight)*(dvert->totweight), 
264                                                                          "deformWeight");
265                                 if (dvert->dw){
266                                         memcpy (newdw, dvert->dw, sizeof(MDeformWeight)*i);
267                                         memcpy (newdw+i, dvert->dw+i+1, 
268                                                         sizeof(MDeformWeight)*(dvert->totweight-i));
269                                         MEM_freeN (dvert->dw);
270                                 }
271                                 dvert->dw=newdw;
272                         }
273                         /* if there are no other deform weights
274                          * left then just remove the deform weight
275                          */
276                         else {
277                                 MEM_freeN (dvert->dw);
278                                 dvert->dw = NULL;
279                         }
280                 }
281         }
282
283 }
284
285 void add_vert_defnr (Object *ob, int def_nr, int vertnum, 
286                            float weight, int assignmode)
287 {
288         /* add the vert to the deform group with the
289          * specified number
290          */
291
292         MDeformVert *dv;
293         MDeformWeight *newdw;
294         int     i;
295
296         /* get the vert
297          */
298         if(((Mesh*)ob->data)->dvert)
299                 dv = ((Mesh*)ob->data)->dvert + vertnum;
300         else 
301                 return;
302         
303         /* Lets first check to see if this vert is
304          * already in the weight group -- if so
305          * lets update it
306          */
307         for (i=0; i<dv->totweight; i++){
308                 
309                 /* if this weight cooresponds to the
310                  * deform group, then add it using
311                  * the assign mode provided
312                  */
313                 if (dv->dw[i].def_nr == def_nr){
314                         
315                         switch (assignmode) {
316                         case WEIGHT_REPLACE:
317                                 dv->dw[i].weight=weight;
318                                 break;
319                         case WEIGHT_ADD:
320                                 dv->dw[i].weight+=weight;
321                                 if (dv->dw[i].weight >= 1.0)
322                                         dv->dw[i].weight = 1.0;
323                                 break;
324                         case WEIGHT_SUBTRACT:
325                                 dv->dw[i].weight-=weight;
326                                 /* if the weight is zero or less then
327                                  * remove the vert from the deform group
328                                  */
329                                 if (dv->dw[i].weight <= 0.0)
330                                         remove_vert_def_nr(ob, def_nr, vertnum);
331                                 break;
332                         }
333                         return;
334                 }
335         }
336
337         /* if the vert wasn't in the deform group then
338          * we must take a different form of action ...
339          */
340
341         switch (assignmode) {
342         case WEIGHT_SUBTRACT:
343                 /* if we are subtracting then we don't
344                  * need to do anything
345                  */
346                 return;
347
348         case WEIGHT_REPLACE:
349         case WEIGHT_ADD:
350                 /* if we are doing an additive assignment, then
351                  * we need to create the deform weight
352                  */
353                 newdw = MEM_callocN (sizeof(MDeformWeight)*(dv->totweight+1), 
354                                                          "deformWeight");
355                 if (dv->dw){
356                         memcpy (newdw, dv->dw, sizeof(MDeformWeight)*dv->totweight);
357                         MEM_freeN (dv->dw);
358                 }
359                 dv->dw=newdw;
360     
361                 dv->dw[dv->totweight].weight=weight;
362                 dv->dw[dv->totweight].def_nr=def_nr;
363     
364                 dv->totweight++;
365                 break;
366         }
367 }
368
369 void add_vert_to_defgroup (Object *ob, bDeformGroup *dg, int vertnum, 
370                            float weight, int assignmode)
371 {
372         /* add the vert to the deform group with the
373          * specified assign mode
374          */
375         int     def_nr;
376
377         /* get the deform group number, exit if
378          * it can't be found
379          */
380         def_nr = get_defgroup_num(ob, dg);
381         if (def_nr < 0) return;
382
383         /* if this mesh has no deform verts then
384          * create some
385          */
386         if (!((Mesh*)ob->data)->dvert) {
387                 create_dverts((Mesh*)ob->data);
388         }
389
390         /* call another function to do the work
391          */
392         add_vert_defnr (ob, def_nr, vertnum, weight, assignmode);
393 }
394
395
396 void assign_verts_defgroup (void)
397 /* Only available in editmode */
398 {
399         EditMesh *em = G.editMesh;
400         Object *ob;
401         EditVert *eve;
402         bDeformGroup    *dg, *eg;
403         extern float editbutvweight;    /* buttons.c */
404         int     i, done;
405         MDeformWeight *newdw;
406
407         ob=G.obedit;
408
409         if (!ob)
410                 return;
411
412         dg=BLI_findlink(&ob->defbase, ob->actdef-1);
413         if (!dg){
414                 error ("No vertex group is active");
415                 return;
416         }
417
418         switch (ob->type){
419         case OB_MESH:
420                 /* Go through the list of editverts and assign them */
421                 for (eve=em->verts.first; eve; eve=eve->next){
422                         if (eve->f & 1){
423                                 done=0;
424                                 /* See if this vert already has a reference to this group */
425                                 /*              If so: Change its weight */
426                                 done=0;
427                                 for (i=0; i<eve->totweight; i++){
428                                         eg = BLI_findlink (&ob->defbase, eve->dw[i].def_nr);
429                                         /* Find the actual group */
430                                         if (eg==dg){
431                                                 eve->dw[i].weight=editbutvweight;
432                                                 done=1;
433                                                 break;
434                                         }
435                                 }
436                                 /*              If not: Add the group and set its weight */
437                                 if (!done){
438                                         newdw = MEM_callocN (sizeof(MDeformWeight)*(eve->totweight+1), "deformWeight");
439                                         if (eve->dw){
440                                                 memcpy (newdw, eve->dw, sizeof(MDeformWeight)*eve->totweight);
441                                                 MEM_freeN (eve->dw);
442                                         }
443                                         eve->dw=newdw;
444
445                                         eve->dw[eve->totweight].weight=editbutvweight;
446                                         eve->dw[eve->totweight].def_nr=ob->actdef-1;
447
448                                         eve->totweight++;
449
450                                 }
451                         }
452                 }
453                 break;
454         default:
455                 printf ("Assigning deformation groups to unknown object type\n");
456                 break;
457         }
458
459 }
460
461 void remove_vert_defgroup (Object *ob, bDeformGroup     *dg, int vertnum)
462 {
463         /* This routine removes the vertex from the specified
464          * deform group.
465          */
466
467         int def_nr;
468
469         /* if the object is NULL abort
470          */
471         if (!ob)
472                 return;
473
474         /* if this isn't a mesh abort
475          */
476         if (ob->type != OB_MESH) return;
477
478         /* get the deform number that cooresponds
479          * to this deform group, and abort if it
480          * can not be found.
481          */
482         def_nr = get_defgroup_num(ob, dg);
483         if (def_nr < 0) return;
484
485         /* call another routine to do the work
486          */
487         remove_vert_def_nr (ob, def_nr, vertnum);
488 }
489
490 void remove_verts_defgroup (int allverts)
491 /* Only available in editmode */
492 {
493         EditMesh *em = G.editMesh;
494         Object *ob;
495         EditVert *eve;
496         MDeformWeight *newdw;
497         bDeformGroup    *dg, *eg;
498         int     i;
499
500         ob=G.obedit;
501
502         if (!ob)
503                 return;
504
505         dg=BLI_findlink(&ob->defbase, ob->actdef-1);
506         if (!dg){
507                 error ("No vertex group is active");
508                 return;
509         }
510
511         switch (ob->type){
512         case OB_MESH:
513                 for (eve=em->verts.first; eve; eve=eve->next){
514                         if (eve->dw && ((eve->f & 1) || allverts)){
515                                 for (i=0; i<eve->totweight; i++){
516                                         /* Find group */
517                                         eg = BLI_findlink (&ob->defbase, eve->dw[i].def_nr);
518                                         if (eg == dg){
519                                                 eve->totweight--;
520                                                 if (eve->totweight){
521                                                         newdw = MEM_mallocN (sizeof(MDeformWeight)*(eve->totweight), "deformWeight");
522                                                         
523                                                         if (eve->dw){
524                                                                 memcpy (newdw, eve->dw, sizeof(MDeformWeight)*i);
525                                                                 memcpy (newdw+i, eve->dw+i+1, sizeof(MDeformWeight)*(eve->totweight-i));
526                                                                 MEM_freeN (eve->dw);
527                                                         }
528                                                         eve->dw=newdw;
529                                                 }
530                                                 else{
531                                                         MEM_freeN (eve->dw);
532                                                         eve->dw=NULL;
533                                                 }
534                                         }
535                                 }
536                         }
537                 }
538                 break;
539         default:
540                 printf ("Removing deformation groups from unknown object type\n");
541                 break;
542         }
543 }
544
545 void verify_defgroups (Object *ob)
546 {
547         /* Ensure the defbase & the dverts match */
548         switch (ob->type){
549         case OB_MESH:
550
551                 /* I'm pretty sure this means "If there are no
552                  * deform groups defined, yet there are deform
553                  * vertices, then delete the deform vertices
554                  */
555                 if (!ob->defbase.first){
556                         if (((Mesh*)ob->data)->dvert){
557                                 free_dverts(((Mesh*)ob->data)->dvert, 
558                                                         ((Mesh*)ob->data)->totvert);
559                                 ((Mesh*)ob->data)->dvert=NULL;
560                         }
561                 }
562                 break;
563         default:
564                 break;
565         }
566 }
567
568 void unique_vertexgroup_name (bDeformGroup *dg, Object *ob)
569 {
570         char            tempname[64];
571         int                     number;
572         char            *dot;
573         int exists = 0;
574         bDeformGroup *curdef;
575         
576         if (!ob)
577                 return;
578         /* See if we even need to do this */
579         for (curdef = ob->defbase.first; curdef; curdef=curdef->next){
580                 if (dg!=curdef){
581                         if (!strcmp(curdef->name, dg->name)){
582                                 exists = 1;
583                                 break;
584                         }
585                 }
586         }
587         
588         if (!exists)
589                 return;
590
591         /*      Strip off the suffix */
592         dot=strchr(dg->name, '.');
593         if (dot)
594                 *dot=0;
595         
596         for (number = 1; number <=999; number++){
597                 sprintf (tempname, "%s.%03d", dg->name, number);
598                 
599                 exists = 0;
600                 for (curdef=ob->defbase.first; curdef; curdef=curdef->next){
601                         if (dg!=curdef){
602                                 if (!strcmp (curdef->name, tempname)){
603                                         exists = 1;
604                                         break;
605                                 }
606                         }
607                 }
608                 if (!exists){
609                         strcpy (dg->name, tempname);
610                         return;
611                 }
612         }       
613 }
614
615 void vertexgroup_select_by_name(Object *ob, char *name)
616 {
617         bDeformGroup *curdef;
618         int actdef= 1;
619         
620         if(ob==NULL || ob->type!=OB_MESH) return;
621         for (curdef = ob->defbase.first; curdef; curdef=curdef->next, actdef++){
622                 if (!strcmp(curdef->name, name)) {
623                         ob->actdef= actdef;
624                 }
625         }
626 }
627
628
629 /* ******************* other deform edit stuff ********** */
630
631 void object_apply_deform(Object *ob)
632 {
633         char *err= NULL;
634         
635         if(ob->type==OB_MESH) {
636                 Mesh *me= ob->data;
637                 if(me->id.us>1) {
638                         err= "Can't apply deformation to Mesh with other users";
639                 } else {
640                         int i, dmNeedsFree;
641                         DerivedMesh *dm = mesh_get_derived_deform(ob, &dmNeedsFree);
642
643                         for (i=0; i<me->totvert; i++) {
644                                 dm->getVertCo(dm, i, me->mvert[i].co);
645                         }
646
647                         if (dmNeedsFree)
648                                 dm->release(dm);
649
650                         DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
651                 }
652         }
653         else if (ob->type==OB_CURVE || ob->type==OB_SURF) {
654                 Curve *cu= ob->data;
655                 if(cu->id.us>1) {
656                         err= "Can't apply deformation to Curve with other users";
657                 } else {
658                         freedisplist(&ob->disp);
659                 }
660         }
661
662         if(err) error(err);
663 }
664