use_verify option to defvert_sync_mapped and defvert_sync was flipped, also minor...
[blender.git] / source / blender / blenkernel / intern / deform.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): Reevan McKay
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/blenkernel/intern/deform.c
29  *  \ingroup bke
30  */
31
32
33 #include <string.h>
34 #include <math.h>
35 #include "ctype.h"
36
37 #include "MEM_guardedalloc.h"
38
39 #include "DNA_meshdata_types.h"
40 #include "DNA_object_types.h"
41
42 #include "BKE_deform.h"
43
44 #include "BLI_blenlib.h"
45 #include "BLI_utildefines.h"
46
47
48 void defgroup_copy_list (ListBase *outbase, ListBase *inbase)
49 {
50         bDeformGroup *defgroup, *defgroupn;
51
52         outbase->first= outbase->last= NULL;
53
54         for (defgroup = inbase->first; defgroup; defgroup=defgroup->next){
55                 defgroupn= defgroup_duplicate(defgroup);
56                 BLI_addtail(outbase, defgroupn);
57         }
58 }
59
60 bDeformGroup *defgroup_duplicate (bDeformGroup *ingroup)
61 {
62         bDeformGroup *outgroup;
63
64         if (!ingroup)
65                 return NULL;
66
67         outgroup=MEM_callocN(sizeof(bDeformGroup), "copy deformGroup");
68         
69         /* For now, just copy everything over. */
70         memcpy (outgroup, ingroup, sizeof(bDeformGroup));
71
72         outgroup->next=outgroup->prev=NULL;
73
74         return outgroup;
75 }
76
77 /* copy & overwrite weights */
78 void defvert_copy (MDeformVert *dvert_r, const MDeformVert *dvert)
79 {
80         if(dvert_r->totweight == dvert->totweight) {
81                 if(dvert->totweight)
82                         memcpy(dvert_r->dw, dvert->dw, dvert->totweight * sizeof(MDeformWeight));
83         }
84         else {
85                 if(dvert_r->dw)
86                         MEM_freeN(dvert_r->dw);
87
88                 if(dvert->totweight)
89                         dvert_r->dw= MEM_dupallocN(dvert->dw);
90                 else
91                         dvert_r->dw= NULL;
92
93                 dvert_r->totweight = dvert->totweight;
94         }
95 }
96
97 /* only sync over matching weights, don't add or remove groups
98  * warning, loop within loop.
99  */
100 void defvert_sync (MDeformVert *dvert_r, const MDeformVert *dvert, int use_verify)
101 {
102         if(dvert->totweight && dvert_r->totweight) {
103                 int i;
104                 MDeformWeight *dw;
105                 for(i=0, dw=dvert->dw; i < dvert->totweight; i++, dw++) {
106                         MDeformWeight *dw_r;
107                         if(use_verify)  dw_r= defvert_verify_index(dvert_r, dw->def_nr);
108                         else                    dw_r= defvert_find_index(dvert_r, dw->def_nr);
109
110                         if(dw_r) {
111                                 dw_r->weight= dw->weight;
112                         }
113                 }
114         }
115 }
116
117 /* be sure all flip_map values are valid */
118 void defvert_sync_mapped (MDeformVert *dvert_r, const MDeformVert *dvert, const int *flip_map, const int flip_map_len, const int use_verify)
119 {
120         if (dvert->totweight && dvert_r->totweight) {
121                 int i;
122                 MDeformWeight *dw;
123                 for (i=0, dw=dvert->dw; i < dvert->totweight; i++, dw++) {
124                         if (dw->def_nr < flip_map_len) {
125                                 MDeformWeight *dw_r;
126                                 if(use_verify)  dw_r= defvert_verify_index(dvert_r, flip_map[dw->def_nr]);
127                                 else                    dw_r= defvert_find_index(dvert_r, flip_map[dw->def_nr]);
128
129                                 if(dw_r) {
130                                         dw_r->weight= dw->weight;
131                                 }
132                         }
133                 }
134         }
135 }
136
137 /* be sure all flip_map values are valid */
138 void defvert_remap (MDeformVert *dvert, int *map)
139 {
140         MDeformWeight *dw;
141         int i;
142         for(i=0, dw=dvert->dw; i<dvert->totweight; i++, dw++) {
143                 dw->def_nr= map[dw->def_nr];
144         }
145 }
146
147 void defvert_normalize (MDeformVert *dvert)
148 {
149         if(dvert->totweight<=0) {
150                 /* nothing */
151         }
152         else if (dvert->totweight==1) {
153                 dvert->dw[0].weight= 1.0f;
154         }
155         else {
156                 int i;
157                 float tot= 0.0f;
158                 MDeformWeight *dw;
159                 for(i=0, dw=dvert->dw; i < dvert->totweight; i++, dw++)
160                         tot += dw->weight;
161
162                 if(tot > 0.0f) {
163                         for(i=0, dw=dvert->dw; i < dvert->totweight; i++, dw++)
164                                 dw->weight /= tot;
165                 }
166         }
167 }
168
169 void defvert_flip (MDeformVert *dvert, const int *flip_map, const int flip_map_len)
170 {
171         MDeformWeight *dw;
172         int i;
173
174         for(dw= dvert->dw, i=0; i<dvert->totweight; dw++, i++) {
175                 if((dw->def_nr < flip_map_len) && (flip_map[dw->def_nr] >= 0)) {
176                         dw->def_nr= flip_map[dw->def_nr];
177                 }
178         }
179 }
180
181
182 bDeformGroup *defgroup_find_name (Object *ob, const char *name)
183 {
184         /* return a pointer to the deform group with this name
185          * or return NULL otherwise.
186          */
187         bDeformGroup *curdef;
188
189         for (curdef = ob->defbase.first; curdef; curdef=curdef->next) {
190                 if (!strcmp(curdef->name, name)) {
191                         return curdef;
192                 }
193         }
194         return NULL;
195 }
196
197 int defgroup_name_index (Object *ob, const char *name)
198 {
199         /* Return the location of the named deform group within the list of
200          * deform groups. This function is a combination of defgroup_find_index and
201          * defgroup_find_name. The other two could be called instead, but that
202          * require looping over the vertexgroups twice.
203          */
204         bDeformGroup *curdef;
205         int def_nr;
206         
207         if(name && name[0] != '\0') {
208                 for (curdef=ob->defbase.first, def_nr=0; curdef; curdef=curdef->next, def_nr++) {
209                         if (!strcmp(curdef->name, name))
210                                 return def_nr;
211                 }
212         }
213
214         return -1;
215 }
216
217 int defgroup_find_index (Object *ob, bDeformGroup *dg)
218 {
219         /* Fetch the location of this deform group
220          * within the linked list of deform groups.
221          * (this number is stored in the deform
222          * weights of the deform verts to link them
223          * to this deform group).
224          *
225          * note: this is zero based, ob->actdef starts at 1.
226          */
227
228         bDeformGroup *eg;
229         int def_nr;
230
231         eg = ob->defbase.first;
232         def_nr = 0;
233
234         /* loop through all deform groups */
235         while (eg != NULL) {
236
237                 /* if the current deform group is
238                  * the one we are after, return
239                  * def_nr
240                  */
241                 if (eg == dg) {
242                         break;
243                 }
244                 ++def_nr;
245                 eg = eg->next;
246         }
247
248         /* if there was no deform group found then
249          * return -1 (should set up a nice symbolic
250          * constant for this)
251          */
252         if (eg == NULL) return -1;
253         
254         return def_nr;
255 }
256
257 /* note, must be freed */
258 int *defgroup_flip_map(Object *ob, int *flip_map_len, int use_default)
259 {
260         bDeformGroup *dg;
261         int totdg= *flip_map_len= BLI_countlist(&ob->defbase);
262
263         if(totdg==0) {
264                 return NULL;
265         }
266         else {
267                 char name[sizeof(dg->name)];
268                 int i, flip_num, *map= MEM_mallocN(totdg * sizeof(int), __func__);
269
270                 memset(map, -1, totdg * sizeof(int));
271
272                 for (dg=ob->defbase.first, i=0; dg; dg=dg->next, i++) {
273                         if(map[i] == -1) { /* may be calculated previously */
274
275                                 /* incase no valid value is found, use this */
276                                 if(use_default)
277                                         map[i]= i;
278
279                                 flip_side_name(name, dg->name, 0);
280                                 if(strcmp(name, dg->name)) {
281                                         flip_num= defgroup_name_index(ob, name);
282                                         if(flip_num >= 0) {
283                                                 map[i]= flip_num;
284                                                 map[flip_num]= i; /* save an extra lookup */
285                                         }
286                                 }
287                         }
288                 }
289                 return map;
290         }
291 }
292
293 int defgroup_flip_index(Object *ob, int index, int use_default)
294 {
295         bDeformGroup *dg= BLI_findlink(&ob->defbase, index);
296         int flip_index = -1;
297
298         if(dg) {
299                 char name[sizeof(dg->name)];
300                 flip_side_name(name, dg->name, 0);
301
302                 if(strcmp(name, dg->name))
303                         flip_index= defgroup_name_index(ob, name);
304         }
305
306         return (flip_index==-1 && use_default) ? index : flip_index;
307 }
308
309 static int defgroup_find_name_dupe(const char *name, bDeformGroup *dg, Object *ob)
310 {
311         bDeformGroup *curdef;
312         
313         for (curdef = ob->defbase.first; curdef; curdef=curdef->next) {
314                 if (dg!=curdef) {
315                         if (!strcmp(curdef->name, name)) {
316                                 return 1;
317                         }
318                 }
319         }
320
321         return 0;
322 }
323
324 static int defgroup_unique_check(void *arg, const char *name)
325 {
326         struct {Object *ob; void *dg;} *data= arg;
327         return defgroup_find_name_dupe(name, data->dg, data->ob);
328 }
329
330 void defgroup_unique_name (bDeformGroup *dg, Object *ob)
331 {
332         struct {Object *ob; void *dg;} data;
333         data.ob= ob;
334         data.dg= dg;
335
336         BLI_uniquename_cb(defgroup_unique_check, &data, "Group", '.', dg->name, sizeof(dg->name));
337 }
338
339 /* finds the best possible flipped name. For renaming; check for unique names afterwards */
340 /* if strip_number: removes number extensions
341  * note: dont use sizeof() for 'name' or 'from_name' */
342 void flip_side_name (char name[MAX_VGROUP_NAME], const char from_name[MAX_VGROUP_NAME], int strip_number)
343 {
344         int     len;
345         char    prefix[MAX_VGROUP_NAME]=  "";   /* The part before the facing */
346         char    suffix[MAX_VGROUP_NAME]=  "";   /* The part after the facing */
347         char    replace[MAX_VGROUP_NAME]= "";   /* The replacement string */
348         char    number[MAX_VGROUP_NAME]=  "";   /* The number extension string */
349         char    *index=NULL;
350
351         len= BLI_strnlen(from_name, MAX_VGROUP_NAME);
352         if(len<3) return; // we don't do names like .R or .L
353
354         BLI_strncpy(name, from_name, MAX_VGROUP_NAME);
355
356         /* We first check the case with a .### extension, let's find the last period */
357         if(isdigit(name[len-1])) {
358                 index= strrchr(name, '.'); // last occurrence
359                 if (index && isdigit(index[1]) ) { // doesnt handle case bone.1abc2 correct..., whatever!
360                         if(strip_number==0)
361                                 BLI_strncpy(number, index, sizeof(number));
362                         *index= 0;
363                         len= BLI_strnlen(name, MAX_VGROUP_NAME);
364                 }
365         }
366
367         BLI_strncpy(prefix, name, sizeof(prefix));
368
369 #define IS_SEPARATOR(a) ((a)=='.' || (a)==' ' || (a)=='-' || (a)=='_')
370
371         /* first case; separator . - _ with extensions r R l L  */
372         if( IS_SEPARATOR(name[len-2]) ) {
373                 switch(name[len-1]) {
374                         case 'l':
375                                 prefix[len-1]= 0;
376                                 strcpy(replace, "r");
377                                 break;
378                         case 'r':
379                                 prefix[len-1]= 0;
380                                 strcpy(replace, "l");
381                                 break;
382                         case 'L':
383                                 prefix[len-1]= 0;
384                                 strcpy(replace, "R");
385                                 break;
386                         case 'R':
387                                 prefix[len-1]= 0;
388                                 strcpy(replace, "L");
389                                 break;
390                 }
391         }
392         /* case; beginning with r R l L , with separator after it */
393         else if( IS_SEPARATOR(name[1]) ) {
394                 switch(name[0]) {
395                         case 'l':
396                                 strcpy(replace, "r");
397                                 strcpy(suffix, name+1);
398                                 prefix[0]= 0;
399                                 break;
400                         case 'r':
401                                 strcpy(replace, "l");
402                                 strcpy(suffix, name+1);
403                                 prefix[0]= 0;
404                                 break;
405                         case 'L':
406                                 strcpy(replace, "R");
407                                 strcpy(suffix, name+1);
408                                 prefix[0]= 0;
409                                 break;
410                         case 'R':
411                                 strcpy(replace, "L");
412                                 strcpy(suffix, name+1);
413                                 prefix[0]= 0;
414                                 break;
415                 }
416         }
417         else if(len > 5) {
418                 /* hrms, why test for a separator? lets do the rule 'ultimate left or right' */
419                 index = BLI_strcasestr(prefix, "right");
420                 if (index==prefix || index==prefix+len-5) {
421                         if(index[0]=='r')
422                                 strcpy (replace, "left");
423                         else {
424                                 if(index[1]=='I')
425                                         strcpy (replace, "LEFT");
426                                 else
427                                         strcpy (replace, "Left");
428                         }
429                         *index= 0;
430                         strcpy (suffix, index+5);
431                 }
432                 else {
433                         index = BLI_strcasestr(prefix, "left");
434                         if (index==prefix || index==prefix+len-4) {
435                                 if(index[0]=='l')
436                                         strcpy (replace, "right");
437                                 else {
438                                         if(index[1]=='E')
439                                                 strcpy (replace, "RIGHT");
440                                         else
441                                                 strcpy (replace, "Right");
442                                 }
443                                 *index= 0;
444                                 strcpy (suffix, index+4);
445                         }
446                 }
447         }
448
449 #undef IS_SEPARATOR
450
451         BLI_snprintf (name, MAX_VGROUP_NAME, "%s%s%s%s", prefix, replace, suffix, number);
452 }
453
454 float defvert_find_weight(const struct MDeformVert *dvert, const int group_num)
455 {
456         MDeformWeight *dw= defvert_find_index(dvert, group_num);
457         return dw ? dw->weight : 0.0f;
458 }
459
460 float defvert_array_find_weight_safe(const struct MDeformVert *dvert, int index, int group_num)
461 {
462         if(group_num == -1 || dvert == NULL)
463                 return 1.0f;
464
465         return defvert_find_weight(dvert+index, group_num);
466 }
467
468
469 MDeformWeight *defvert_find_index(const MDeformVert *dvert, const int defgroup)
470 {
471         if(dvert && defgroup >= 0) {
472                 MDeformWeight *dw = dvert->dw;
473                 int i;
474
475                 for(i=dvert->totweight; i>0; i--, dw++)
476                         if(dw->def_nr == defgroup)
477                                 return dw;
478         }
479
480         return NULL;
481 }
482
483 /* Ensures that mv has a deform weight entry for the specified defweight group */
484 /* Note this function is mirrored in editmesh_tools.c, for use for editvertices */
485 MDeformWeight *defvert_verify_index(MDeformVert *dv, const int defgroup)
486 {
487         MDeformWeight *newdw;
488
489         /* do this check always, this function is used to check for it */
490         if(!dv || defgroup < 0)
491                 return NULL;
492
493         newdw= defvert_find_index(dv, defgroup);
494         if(newdw)
495                 return newdw;
496
497         newdw= MEM_callocN(sizeof(MDeformWeight)*(dv->totweight+1), "deformWeight");
498         if (dv->dw) {
499                 memcpy(newdw, dv->dw, sizeof(MDeformWeight)*dv->totweight);
500                 MEM_freeN(dv->dw);
501         }
502         dv->dw= newdw;
503         newdw += dv->totweight;
504         newdw->weight= 0.0f;
505         newdw->def_nr= defgroup;
506         /* Group index */
507
508         dv->totweight++;
509
510         return newdw;
511 }