sim: Remove "continue physics" code
[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 #include <stdlib.h>
37 #include <stddef.h>
38
39 #include "MEM_guardedalloc.h"
40
41 #include "DNA_meshdata_types.h"
42 #include "DNA_object_types.h"
43
44 #include "BKE_deform.h"
45
46 #include "BLI_listbase.h"
47 #include "BLI_math.h"
48 #include "BLI_path_util.h"
49 #include "BLI_string.h"
50 #include "BLI_utildefines.h"
51
52
53 void defgroup_copy_list(ListBase *outbase, ListBase *inbase)
54 {
55         bDeformGroup *defgroup, *defgroupn;
56
57         outbase->first = outbase->last = NULL;
58
59         for (defgroup = inbase->first; defgroup; defgroup = defgroup->next) {
60                 defgroupn = defgroup_duplicate(defgroup);
61                 BLI_addtail(outbase, defgroupn);
62         }
63 }
64
65 bDeformGroup *defgroup_duplicate(bDeformGroup *ingroup)
66 {
67         bDeformGroup *outgroup;
68
69         if (!ingroup)
70                 return NULL;
71
72         outgroup = MEM_callocN(sizeof(bDeformGroup), "copy deformGroup");
73
74         /* For now, just copy everything over. */
75         memcpy(outgroup, ingroup, sizeof(bDeformGroup));
76
77         outgroup->next = outgroup->prev = NULL;
78
79         return outgroup;
80 }
81
82 /* copy & overwrite weights */
83 void defvert_copy(MDeformVert *dvert_dst, const MDeformVert *dvert_src)
84 {
85         if (dvert_dst->totweight == dvert_src->totweight) {
86                 if (dvert_src->totweight)
87                         memcpy(dvert_dst->dw, dvert_src->dw, dvert_src->totweight * sizeof(MDeformWeight));
88         }
89         else {
90                 if (dvert_dst->dw)
91                         MEM_freeN(dvert_dst->dw);
92
93                 if (dvert_src->totweight)
94                         dvert_dst->dw = MEM_dupallocN(dvert_src->dw);
95                 else
96                         dvert_dst->dw = NULL;
97
98                 dvert_dst->totweight = dvert_src->totweight;
99         }
100 }
101
102 /* copy an index from one dvert to another
103  * - do nothing if neither are set.
104  * - add destination weight if needed.
105  */
106 void defvert_copy_index(MDeformVert *dvert_dst, const MDeformVert *dvert_src, const int defgroup)
107 {
108         MDeformWeight *dw_src, *dw_dst;
109
110         dw_src = defvert_find_index(dvert_src, defgroup);
111
112         if (dw_src) {
113                 /* source is valid, verify destination */
114                 dw_dst = defvert_verify_index(dvert_dst, defgroup);
115                 dw_dst->weight = dw_src->weight;
116         }
117         else {
118                 /* source was NULL, assign zero, could also remove */
119                 dw_dst = defvert_find_index(dvert_dst, defgroup);
120
121                 if (dw_dst) {
122                         dw_dst->weight = 0.0f;
123                 }
124         }
125 }
126
127 /* only sync over matching weights, don't add or remove groups
128  * warning, loop within loop.
129  */
130 void defvert_sync(MDeformVert *dvert_dst, const MDeformVert *dvert_src, int use_verify)
131 {
132         if (dvert_src->totweight && dvert_dst->totweight) {
133                 int i;
134                 MDeformWeight *dw_src;
135                 for (i = 0, dw_src = dvert_src->dw; i < dvert_src->totweight; i++, dw_src++) {
136                         MDeformWeight *dw_dst;
137                         if (use_verify) dw_dst = defvert_verify_index(dvert_dst, dw_src->def_nr);
138                         else            dw_dst = defvert_find_index(dvert_dst, dw_src->def_nr);
139
140                         if (dw_dst) {
141                                 dw_dst->weight = dw_src->weight;
142                         }
143                 }
144         }
145 }
146
147 /* be sure all flip_map values are valid */
148 void defvert_sync_mapped(MDeformVert *dvert_dst, const MDeformVert *dvert_src,
149                          const int *flip_map, const int flip_map_len, const int use_verify)
150 {
151         if (dvert_src->totweight && dvert_dst->totweight) {
152                 int i;
153                 MDeformWeight *dw_src;
154                 for (i = 0, dw_src = dvert_src->dw; i < dvert_src->totweight; i++, dw_src++) {
155                         if (dw_src->def_nr < flip_map_len) {
156                                 MDeformWeight *dw_dst;
157                                 if (use_verify) dw_dst = defvert_verify_index(dvert_dst, flip_map[dw_src->def_nr]);
158                                 else            dw_dst = defvert_find_index(dvert_dst, flip_map[dw_src->def_nr]);
159
160                                 if (dw_dst) {
161                                         dw_dst->weight = dw_src->weight;
162                                 }
163                         }
164                 }
165         }
166 }
167
168 /* be sure all flip_map values are valid */
169 void defvert_remap(MDeformVert *dvert, int *map, const int map_len)
170 {
171         MDeformWeight *dw = dvert->dw;
172         unsigned int i;
173         for (i = dvert->totweight; i != 0; i--, dw++) {
174                 if (dw->def_nr < map_len) {
175                         dw->def_nr = map[dw->def_nr];
176
177                         /* just in case */
178                         BLI_assert(dw->def_nr >= 0);
179                 }
180         }
181 }
182
183 void defvert_normalize(MDeformVert *dvert)
184 {
185         if (dvert->totweight <= 0) {
186                 /* nothing */
187         }
188         else if (dvert->totweight == 1) {
189                 dvert->dw[0].weight = 1.0f;
190         }
191         else {
192                 MDeformWeight *dw;
193                 unsigned int i;
194                 float tot_weight = 0.0f;
195
196                 for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
197                         tot_weight += dw->weight;
198                 }
199
200                 if (tot_weight > 0.0f) {
201                         float scalar = 1.0f / tot_weight;
202                         for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
203                                 dw->weight *= scalar;
204
205                                 /* in case of division errors with very low weights */
206                                 CLAMP(dw->weight, 0.0f, 1.0f);
207                         }
208                 }
209         }
210 }
211
212 void defvert_normalize_lock_single(MDeformVert *dvert, const int def_nr_lock)
213 {
214         if (dvert->totweight <= 0) {
215                 /* nothing */
216         }
217         else if (dvert->totweight == 1) {
218                 if (def_nr_lock != 0) {
219                         dvert->dw[0].weight = 1.0f;
220                 }
221         }
222         else {
223                 MDeformWeight *dw_lock = NULL;
224                 MDeformWeight *dw;
225                 unsigned int i;
226                 float tot_weight = 0.0f;
227                 float lock_iweight = 1.0f;
228
229                 for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
230                         if (dw->def_nr != def_nr_lock) {
231                                 tot_weight += dw->weight;
232                         }
233                         else {
234                                 dw_lock = dw;
235                                 lock_iweight = (1.0f - dw_lock->weight);
236                                 CLAMP(lock_iweight, 0.0f, 1.0f);
237                         }
238                 }
239
240                 if (tot_weight > 0.0f) {
241                         /* paranoid, should be 1.0 but in case of float error clamp anyway */
242
243                         float scalar = (1.0f / tot_weight) * lock_iweight;
244                         for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
245                                 if (dw != dw_lock) {
246                                         dw->weight *= scalar;
247
248                                         /* in case of division errors with very low weights */
249                                         CLAMP(dw->weight, 0.0f, 1.0f);
250                                 }
251                         }
252                 }
253         }
254 }
255
256 void defvert_normalize_lock_map(MDeformVert *dvert, const char *lock_flags, const int defbase_tot)
257 {
258         if (dvert->totweight <= 0) {
259                 /* nothing */
260         }
261         else if (dvert->totweight == 1) {
262                 if (LIKELY(defbase_tot >= 1) && lock_flags[0]) {
263                         dvert->dw[0].weight = 1.0f;
264                 }
265         }
266         else {
267                 MDeformWeight *dw;
268                 unsigned int i;
269                 float tot_weight = 0.0f;
270                 float lock_iweight = 0.0f;
271
272                 for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
273                         if ((dw->def_nr < defbase_tot) && (lock_flags[dw->def_nr] == FALSE)) {
274                                 tot_weight += dw->weight;
275                         }
276                         else {
277                                 /* invert after */
278                                 lock_iweight += dw->weight;
279                         }
280                 }
281
282                 lock_iweight = max_ff(0.0f, 1.0f - lock_iweight);
283
284                 if (tot_weight > 0.0f) {
285                         /* paranoid, should be 1.0 but in case of float error clamp anyway */
286
287                         float scalar = (1.0f / tot_weight) * lock_iweight;
288                         for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
289                                 if ((dw->def_nr < defbase_tot) && (lock_flags[dw->def_nr] == FALSE)) {
290                                         dw->weight *= scalar;
291
292                                         /* in case of division errors with very low weights */
293                                         CLAMP(dw->weight, 0.0f, 1.0f);
294                                 }
295                         }
296                 }
297         }
298 }
299
300 void defvert_flip(MDeformVert *dvert, const int *flip_map, const int flip_map_len)
301 {
302         MDeformWeight *dw;
303         int i;
304
305         for (dw = dvert->dw, i = 0; i < dvert->totweight; dw++, i++) {
306                 if (dw->def_nr < flip_map_len) {
307                         if (flip_map[dw->def_nr] >= 0) {
308                                 dw->def_nr = flip_map[dw->def_nr];
309                         }
310                 }
311         }
312 }
313
314 void defvert_flip_merged(MDeformVert *dvert, const int *flip_map, const int flip_map_len)
315 {
316         MDeformWeight *dw, *dw_cpy;
317         float weight;
318         int i, totweight = dvert->totweight;
319
320         /* copy weights */
321         for (dw = dvert->dw, i = 0; i < totweight; dw++, i++) {
322                 if (dw->def_nr < flip_map_len) {
323                         if (flip_map[dw->def_nr] >= 0) {
324                                 /* error checkers complain of this but we'll never get NULL return */
325                                 dw_cpy = defvert_verify_index(dvert, flip_map[dw->def_nr]);
326                                 dw = &dvert->dw[i]; /* in case array got realloced */
327
328                                 /* distribute weights: if only one of the vertex groups was
329                                  * assigned this will halve the weights, otherwise it gets
330                                  * evened out. this keeps it proportional to other groups */
331                                 weight = 0.5f * (dw_cpy->weight + dw->weight);
332                                 dw_cpy->weight = weight;
333                                 dw->weight = weight;
334                         }
335                 }
336         }
337 }
338
339 bDeformGroup *defgroup_find_name(Object *ob, const char *name)
340 {
341         return BLI_findstring(&ob->defbase, name, offsetof(bDeformGroup, name));
342 }
343
344 int defgroup_name_index(Object *ob, const char *name)
345 {
346         return (name) ? BLI_findstringindex(&ob->defbase, name, offsetof(bDeformGroup, name)) : -1;
347 }
348
349 /* note, must be freed */
350 int *defgroup_flip_map(Object *ob, int *flip_map_len, int use_default)
351 {
352         int defbase_tot = *flip_map_len = BLI_countlist(&ob->defbase);
353
354         if (defbase_tot == 0) {
355                 return NULL;
356         }
357         else {
358                 bDeformGroup *dg;
359                 char name[sizeof(dg->name)];
360                 int i, flip_num, *map = MEM_mallocN(defbase_tot * sizeof(int), __func__);
361
362                 for (i = 0; i < defbase_tot; i++) {
363                         map[i] = -1;
364                 }
365
366                 for (dg = ob->defbase.first, i = 0; dg; dg = dg->next, i++) {
367                         if (map[i] == -1) { /* may be calculated previously */
368
369                                 /* in case no valid value is found, use this */
370                                 if (use_default)
371                                         map[i] = i;
372
373                                 flip_side_name(name, dg->name, FALSE);
374                                 if (strcmp(name, dg->name)) {
375                                         flip_num = defgroup_name_index(ob, name);
376                                         if (flip_num >= 0) {
377                                                 map[i] = flip_num;
378                                                 map[flip_num] = i; /* save an extra lookup */
379                                         }
380                                 }
381                         }
382                 }
383                 return map;
384         }
385 }
386
387 /* note, must be freed */
388 int *defgroup_flip_map_single(Object *ob, int *flip_map_len, int use_default, int defgroup)
389 {
390         int defbase_tot = *flip_map_len = BLI_countlist(&ob->defbase);
391
392         if (defbase_tot == 0) {
393                 return NULL;
394         }
395         else {
396                 bDeformGroup *dg;
397                 char name[sizeof(dg->name)];
398                 int i, flip_num, *map = MEM_mallocN(defbase_tot * sizeof(int), __func__);
399
400                 for (i = 0; i < defbase_tot; i++) {
401                         map[i] = use_default ? i : -1;
402                 }
403
404                 dg = BLI_findlink(&ob->defbase, defgroup);
405
406                 flip_side_name(name, dg->name, FALSE);
407                 if (strcmp(name, dg->name)) {
408                         flip_num = defgroup_name_index(ob, name);
409
410                         if (flip_num != -1) {
411                                 map[defgroup] = flip_num;
412                                 map[flip_num] = defgroup;
413                         }
414                 }
415
416                 return map;
417         }
418 }
419
420 int defgroup_flip_index(Object *ob, int index, int use_default)
421 {
422         bDeformGroup *dg = BLI_findlink(&ob->defbase, index);
423         int flip_index = -1;
424
425         if (dg) {
426                 char name[sizeof(dg->name)];
427                 flip_side_name(name, dg->name, 0);
428
429                 if (strcmp(name, dg->name))
430                         flip_index = defgroup_name_index(ob, name);
431         }
432
433         return (flip_index == -1 && use_default) ? index : flip_index;
434 }
435
436 static int defgroup_find_name_dupe(const char *name, bDeformGroup *dg, Object *ob)
437 {
438         bDeformGroup *curdef;
439
440         for (curdef = ob->defbase.first; curdef; curdef = curdef->next) {
441                 if (dg != curdef) {
442                         if (!strcmp(curdef->name, name)) {
443                                 return 1;
444                         }
445                 }
446         }
447
448         return 0;
449 }
450
451 static int defgroup_unique_check(void *arg, const char *name)
452 {
453         struct {Object *ob; void *dg; } *data = arg;
454         return defgroup_find_name_dupe(name, data->dg, data->ob);
455 }
456
457 void defgroup_unique_name(bDeformGroup *dg, Object *ob)
458 {
459         struct {Object *ob; void *dg; } data;
460         data.ob = ob;
461         data.dg = dg;
462
463         BLI_uniquename_cb(defgroup_unique_check, &data, "Group", '.', dg->name, sizeof(dg->name));
464 }
465
466 static int is_char_sep(const char c)
467 {
468         return ELEM4(c, '.', ' ', '-', '_');
469 }
470
471 /* based on BLI_split_dirfile() / os.path.splitext(), "a.b.c" -> ("a.b", ".c") */
472
473 void BKE_deform_split_suffix(const char string[MAX_VGROUP_NAME], char body[MAX_VGROUP_NAME], char suf[MAX_VGROUP_NAME])
474 {
475         size_t len = BLI_strnlen(string, MAX_VGROUP_NAME);
476         size_t i;
477
478         body[0] = suf[0] = '\0';
479
480         for (i = len - 1; i > 1; i--) {
481                 if (is_char_sep(string[i])) {
482                         BLI_strncpy(body, string, i + 1);
483                         BLI_strncpy(suf, string + i,  (len + 1) - i);
484                         return;
485                 }
486         }
487
488         BLI_strncpy(body, string, len);
489 }
490
491 /* "a.b.c" -> ("a.", "b.c") */
492 void BKE_deform_split_prefix(const char string[MAX_VGROUP_NAME], char pre[MAX_VGROUP_NAME], char body[MAX_VGROUP_NAME])
493 {
494         size_t len = BLI_strnlen(string, MAX_VGROUP_NAME);
495         size_t i;
496
497         body[0] = pre[0] = '\0';
498
499         for (i = 1; i < len; i++) {
500                 if (is_char_sep(string[i])) {
501                         i++;
502                         BLI_strncpy(pre, string, i + 1);
503                         BLI_strncpy(body, string + i, (len + 1) - i);
504                         return;
505                 }
506         }
507
508         BLI_strncpy(body, string, len);
509 }
510
511 /* finds the best possible flipped name. For renaming; check for unique names afterwards */
512 /* if strip_number: removes number extensions
513  * note: don't use sizeof() for 'name' or 'from_name' */
514 void flip_side_name(char name[MAX_VGROUP_NAME], const char from_name[MAX_VGROUP_NAME], int strip_number)
515 {
516         int     len;
517         char    prefix[MAX_VGROUP_NAME]  = "";   /* The part before the facing */
518         char    suffix[MAX_VGROUP_NAME]  = "";   /* The part after the facing */
519         char    replace[MAX_VGROUP_NAME] = "";   /* The replacement string */
520         char    number[MAX_VGROUP_NAME]  = "";   /* The number extension string */
521         char    *index = NULL;
522
523         /* always copy the name, since this can be called with an uninitialized string */
524         BLI_strncpy(name, from_name, MAX_VGROUP_NAME);
525
526         len = BLI_strnlen(from_name, MAX_VGROUP_NAME);
527         if (len < 3) {
528                 /* we don't do names like .R or .L */
529                 return;
530         }
531
532         /* We first check the case with a .### extension, let's find the last period */
533         if (isdigit(name[len - 1])) {
534                 index = strrchr(name, '.'); // last occurrence
535                 if (index && isdigit(index[1])) { // doesnt handle case bone.1abc2 correct..., whatever!
536                         if (strip_number == 0) {
537                                 BLI_strncpy(number, index, sizeof(number));
538                         }
539                         *index = 0;
540                         len = BLI_strnlen(name, MAX_VGROUP_NAME);
541                 }
542         }
543
544         BLI_strncpy(prefix, name, sizeof(prefix));
545
546         /* first case; separator . - _ with extensions r R l L  */
547         if (is_char_sep(name[len - 2])) {
548                 switch (name[len - 1]) {
549                         case 'l':
550                                 prefix[len - 1] = 0;
551                                 strcpy(replace, "r");
552                                 break;
553                         case 'r':
554                                 prefix[len - 1] = 0;
555                                 strcpy(replace, "l");
556                                 break;
557                         case 'L':
558                                 prefix[len - 1] = 0;
559                                 strcpy(replace, "R");
560                                 break;
561                         case 'R':
562                                 prefix[len - 1] = 0;
563                                 strcpy(replace, "L");
564                                 break;
565                 }
566         }
567         /* case; beginning with r R l L, with separator after it */
568         else if (is_char_sep(name[1])) {
569                 switch (name[0]) {
570                         case 'l':
571                                 strcpy(replace, "r");
572                                 BLI_strncpy(suffix, name + 1, sizeof(suffix));
573                                 prefix[0] = 0;
574                                 break;
575                         case 'r':
576                                 strcpy(replace, "l");
577                                 BLI_strncpy(suffix, name + 1, sizeof(suffix));
578                                 prefix[0] = 0;
579                                 break;
580                         case 'L':
581                                 strcpy(replace, "R");
582                                 BLI_strncpy(suffix, name + 1, sizeof(suffix));
583                                 prefix[0] = 0;
584                                 break;
585                         case 'R':
586                                 strcpy(replace, "L");
587                                 BLI_strncpy(suffix, name + 1, sizeof(suffix));
588                                 prefix[0] = 0;
589                                 break;
590                 }
591         }
592         else if (len > 5) {
593                 /* hrms, why test for a separator? lets do the rule 'ultimate left or right' */
594                 index = BLI_strcasestr(prefix, "right");
595                 if (index == prefix || index == prefix + len - 5) {
596                         if (index[0] == 'r')
597                                 strcpy(replace, "left");
598                         else {
599                                 if (index[1] == 'I')
600                                         strcpy(replace, "LEFT");
601                                 else
602                                         strcpy(replace, "Left");
603                         }
604                         *index = 0;
605                         BLI_strncpy(suffix, index + 5, sizeof(suffix));
606                 }
607                 else {
608                         index = BLI_strcasestr(prefix, "left");
609                         if (index == prefix || index == prefix + len - 4) {
610                                 if (index[0] == 'l')
611                                         strcpy(replace, "right");
612                                 else {
613                                         if (index[1] == 'E')
614                                                 strcpy(replace, "RIGHT");
615                                         else
616                                                 strcpy(replace, "Right");
617                                 }
618                                 *index = 0;
619                                 BLI_strncpy(suffix, index + 4, sizeof(suffix));
620                         }
621                 }
622         }
623
624         BLI_snprintf(name, MAX_VGROUP_NAME, "%s%s%s%s", prefix, replace, suffix, number);
625 }
626
627 float defvert_find_weight(const struct MDeformVert *dvert, const int defgroup)
628 {
629         MDeformWeight *dw = defvert_find_index(dvert, defgroup);
630         return dw ? dw->weight : 0.0f;
631 }
632
633 /* take care with this the rationale is:
634  * - if the object has no vertex group. act like vertex group isn't set and return 1.0,
635  * - if the vertex group exists but the 'defgroup' isn't found on this vertex, _still_ return 0.0
636  *
637  * This is a bit confusing, just saves some checks from the caller.
638  */
639 float defvert_array_find_weight_safe(const struct MDeformVert *dvert, const int index, const int defgroup)
640 {
641         if (defgroup == -1 || dvert == NULL)
642                 return 1.0f;
643
644         return defvert_find_weight(dvert + index, defgroup);
645 }
646
647
648 MDeformWeight *defvert_find_index(const MDeformVert *dvert, const int defgroup)
649 {
650         if (dvert && defgroup >= 0) {
651                 MDeformWeight *dw = dvert->dw;
652                 unsigned int i;
653
654                 for (i = dvert->totweight; i != 0; i--, dw++) {
655                         if (dw->def_nr == defgroup) {
656                                 return dw;
657                         }
658                 }
659         }
660
661         return NULL;
662 }
663
664 /* Ensures that mv has a deform weight entry for the specified defweight group */
665 /* Note this function is mirrored in editmesh_tools.c, for use for editvertices */
666 MDeformWeight *defvert_verify_index(MDeformVert *dvert, const int defgroup)
667 {
668         MDeformWeight *dw_new;
669
670         /* do this check always, this function is used to check for it */
671         if (!dvert || defgroup < 0)
672                 return NULL;
673
674         dw_new = defvert_find_index(dvert, defgroup);
675         if (dw_new)
676                 return dw_new;
677
678         dw_new = MEM_callocN(sizeof(MDeformWeight) * (dvert->totweight + 1), "deformWeight");
679         if (dvert->dw) {
680                 memcpy(dw_new, dvert->dw, sizeof(MDeformWeight) * dvert->totweight);
681                 MEM_freeN(dvert->dw);
682         }
683         dvert->dw = dw_new;
684         dw_new += dvert->totweight;
685         dw_new->weight = 0.0f;
686         dw_new->def_nr = defgroup;
687         /* Group index */
688
689         dvert->totweight++;
690
691         return dw_new;
692 }
693
694 /* TODO. merge with code above! */
695
696 /* Adds the given vertex to the specified vertex group, with given weight.
697  * warning, this does NOT check for existing, assume caller already knows its not there */
698 void defvert_add_index_notest(MDeformVert *dvert, int defgroup, const float weight)
699 {
700         MDeformWeight *dw_new;
701
702         /* do this check always, this function is used to check for it */
703         if (!dvert || defgroup < 0)
704                 return;
705
706         dw_new = MEM_callocN(sizeof(MDeformWeight) * (dvert->totweight + 1), "defvert_add_to group, new deformWeight");
707         if (dvert->dw) {
708                 memcpy(dw_new, dvert->dw, sizeof(MDeformWeight) * dvert->totweight);
709                 MEM_freeN(dvert->dw);
710         }
711         dvert->dw = dw_new;
712         dw_new += dvert->totweight;
713         dw_new->weight = weight;
714         dw_new->def_nr = defgroup;
715         dvert->totweight++;
716 }
717
718
719 /* Removes the given vertex from the vertex group.
720  * WARNING: This function frees the given MDeformWeight, do not use it afterward! */
721 void defvert_remove_group(MDeformVert *dvert, MDeformWeight *dw)
722 {
723         if (dvert && dw) {
724                 MDeformWeight *dw_new;
725                 int i = dw - dvert->dw;
726
727                 /* Security check! */
728                 if (i < 0 || i >= dvert->totweight) {
729                         return;
730                 }
731
732                 dvert->totweight--;
733                 /* If there are still other deform weights attached to this vert then remove
734                  * this deform weight, and reshuffle the others.
735                  */
736                 if (dvert->totweight) {
737                         dw_new = MEM_mallocN(sizeof(MDeformWeight) * (dvert->totweight), __func__);
738                         if (dvert->dw) {
739 #if 1           /* since we don't care about order, swap this with the last, save a memcpy */
740                                 if (i != dvert->totweight) {
741                                         dvert->dw[i] = dvert->dw[dvert->totweight];
742                                 }
743                                 memcpy(dw_new, dvert->dw, sizeof(MDeformWeight) * dvert->totweight);
744 #else
745                                 memcpy(dw_new, dvert->dw, sizeof(MDeformWeight) * i);
746                                 memcpy(dw_new + i, dvert->dw + i + 1, sizeof(MDeformWeight) * (dvert->totweight - i));
747 #endif
748                                 MEM_freeN(dvert->dw);
749                         }
750                         dvert->dw = dw_new;
751                 }
752                 else {
753                         /* If there are no other deform weights left then just remove this one. */
754                         MEM_freeN(dvert->dw);
755                         dvert->dw = NULL;
756                 }
757         }
758 }
759
760 void defvert_clear(MDeformVert *dvert)
761 {
762         if (dvert->dw) {
763                 MEM_freeN(dvert->dw);
764                 dvert->dw = NULL;
765         }
766
767         dvert->totweight = 0;
768 }
769
770 /**
771  * \return The first group index shared by both deform verts
772  * or -1 if none are found.
773  */
774 int defvert_find_shared(const MDeformVert *dvert_a, const MDeformVert *dvert_b)
775 {
776         if (dvert_a->totweight && dvert_b->totweight) {
777                 MDeformWeight *dw = dvert_a->dw;
778                 unsigned int i;
779
780                 for (i = dvert_a->totweight; i != 0; i--, dw++) {
781                         if (dw->weight > 0.0f && defvert_find_weight(dvert_b, dw->def_nr) > 0.0f) {
782                                 return dw->def_nr;
783                         }
784                 }
785         }
786
787         return -1;
788 }
789
790 /* -------------------------------------------------------------------- */
791 /* Defvert Array functions */
792
793 void BKE_defvert_array_copy(MDeformVert *dst, const MDeformVert *src, int copycount)
794 {
795         /* Assumes dst is already set up */
796         int i;
797
798         if (!src || !dst)
799                 return;
800
801         memcpy(dst, src, copycount * sizeof(MDeformVert));
802
803         for (i = 0; i < copycount; i++) {
804                 if (src[i].dw) {
805                         dst[i].dw = MEM_mallocN(sizeof(MDeformWeight) * src[i].totweight, "copy_deformWeight");
806                         memcpy(dst[i].dw, src[i].dw, sizeof(MDeformWeight) * src[i].totweight);
807                 }
808         }
809
810 }
811
812 void BKE_defvert_array_free(MDeformVert *dvert, int totvert)
813 {
814         /* Instead of freeing the verts directly,
815          * call this function to delete any special
816          * vert data */
817         int i;
818
819         if (!dvert)
820                 return;
821
822         /* Free any special data from the verts */
823         for (i = 0; i < totvert; i++) {
824                 if (dvert[i].dw) MEM_freeN(dvert[i].dw);
825         }
826         MEM_freeN(dvert);
827 }
828