2 * ***** BEGIN GPL LICENSE BLOCK *****
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.
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.
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.
18 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19 * All rights reserved.
21 * The Original Code is: all of this file.
23 * Contributor(s): Reevan McKay
25 * ***** END GPL LICENSE BLOCK *****
28 /** \file blender/blenkernel/intern/deform.c
37 #include "MEM_guardedalloc.h"
39 #include "DNA_meshdata_types.h"
40 #include "DNA_object_types.h"
42 #include "BKE_deform.h"
44 #include "BLI_blenlib.h"
45 #include "BLI_utildefines.h"
48 void defgroup_copy_list(ListBase *outbase, ListBase *inbase)
50 bDeformGroup *defgroup, *defgroupn;
52 outbase->first = outbase->last = NULL;
54 for (defgroup = inbase->first; defgroup; defgroup = defgroup->next) {
55 defgroupn = defgroup_duplicate(defgroup);
56 BLI_addtail(outbase, defgroupn);
60 bDeformGroup *defgroup_duplicate(bDeformGroup *ingroup)
62 bDeformGroup *outgroup;
67 outgroup = MEM_callocN(sizeof(bDeformGroup), "copy deformGroup");
69 /* For now, just copy everything over. */
70 memcpy(outgroup, ingroup, sizeof(bDeformGroup));
72 outgroup->next = outgroup->prev = NULL;
77 /* copy & overwrite weights */
78 void defvert_copy(MDeformVert *dvert_dst, const MDeformVert *dvert_src)
80 if (dvert_dst->totweight == dvert_src->totweight) {
81 if (dvert_src->totweight)
82 memcpy(dvert_dst->dw, dvert_src->dw, dvert_src->totweight * sizeof(MDeformWeight));
86 MEM_freeN(dvert_dst->dw);
88 if (dvert_src->totweight)
89 dvert_dst->dw = MEM_dupallocN(dvert_src->dw);
93 dvert_dst->totweight = dvert_src->totweight;
97 /* copy an index from one dvert to another
98 * - do nothing if neither are set.
99 * - add destination weight if needed.
101 void defvert_copy_index(MDeformVert *dvert_dst, const MDeformVert *dvert_src, const int defgroup)
103 MDeformWeight *dw_src, *dw_dst;
105 dw_src = defvert_find_index(dvert_src, defgroup);
108 /* source is valid, verify destination */
109 dw_dst = defvert_verify_index(dvert_dst, defgroup);
110 dw_dst->weight = dw_src->weight;
113 /* source was NULL, assign zero, could also remove */
114 dw_dst = defvert_find_index(dvert_dst, defgroup);
117 dw_dst->weight = 0.0f;
122 /* only sync over matching weights, don't add or remove groups
123 * warning, loop within loop.
125 void defvert_sync(MDeformVert *dvert_dst, const MDeformVert *dvert_src, int use_verify)
127 if (dvert_src->totweight && dvert_dst->totweight) {
129 MDeformWeight *dw_src;
130 for (i = 0, dw_src = dvert_src->dw; i < dvert_src->totweight; i++, dw_src++) {
131 MDeformWeight *dw_dst;
132 if (use_verify) dw_dst = defvert_verify_index(dvert_dst, dw_src->def_nr);
133 else dw_dst = defvert_find_index(dvert_dst, dw_src->def_nr);
136 dw_dst->weight = dw_src->weight;
142 /* be sure all flip_map values are valid */
143 void defvert_sync_mapped(MDeformVert *dvert_dst, const MDeformVert *dvert_src,
144 const int *flip_map, const int flip_map_len, const int use_verify)
146 if (dvert_src->totweight && dvert_dst->totweight) {
148 MDeformWeight *dw_src;
149 for (i = 0, dw_src = dvert_src->dw; i < dvert_src->totweight; i++, dw_src++) {
150 if (dw_src->def_nr < flip_map_len) {
151 MDeformWeight *dw_dst;
152 if (use_verify) dw_dst = defvert_verify_index(dvert_dst, flip_map[dw_src->def_nr]);
153 else dw_dst = defvert_find_index(dvert_dst, flip_map[dw_src->def_nr]);
156 dw_dst->weight = dw_src->weight;
163 /* be sure all flip_map values are valid */
164 void defvert_remap(MDeformVert *dvert, int *map, const int map_len)
166 MDeformWeight *dw = dvert->dw;
168 for (i = dvert->totweight; i != 0; i--, dw++) {
169 if (dw->def_nr < map_len) {
170 dw->def_nr = map[dw->def_nr];
173 BLI_assert(dw->def_nr >= 0);
178 void defvert_normalize(MDeformVert *dvert)
180 if (dvert->totweight <= 0) {
183 else if (dvert->totweight == 1) {
184 dvert->dw[0].weight = 1.0f;
189 float tot_weight = 0.0f;
191 for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
192 tot_weight += dw->weight;
195 if (tot_weight > 0.0f) {
196 float scalar = 1.0f / tot_weight;
197 for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
198 dw->weight *= scalar;
200 /* in case of division errors with very low weights */
201 CLAMP(dw->weight, 0.0f, 1.0f);
207 void defvert_normalize_lock(MDeformVert *dvert, const int def_nr_lock)
209 if (dvert->totweight <= 0) {
212 else if (dvert->totweight == 1) {
213 dvert->dw[0].weight = 1.0f;
216 MDeformWeight *dw_lock = NULL;
219 float tot_weight = 0.0f;
220 float lock_iweight = 1.0f;
222 for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
223 if (dw->def_nr != def_nr_lock) {
224 tot_weight += dw->weight;
228 lock_iweight = (1.0f - dw_lock->weight);
229 CLAMP(lock_iweight, 0.0f, 1.0f);
233 if (tot_weight > 0.0f) {
234 /* paranoid, should be 1.0 but in case of float error clamp anyway */
236 float scalar = (1.0f / tot_weight) * lock_iweight;
237 for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
239 dw->weight *= scalar;
241 /* in case of division errors with very low weights */
242 CLAMP(dw->weight, 0.0f, 1.0f);
249 void defvert_flip(MDeformVert *dvert, const int *flip_map, const int flip_map_len)
254 for (dw = dvert->dw, i = 0; i<dvert->totweight; dw++, i++) {
255 if (dw->def_nr < flip_map_len) {
256 if (flip_map[dw->def_nr] >= 0) {
257 dw->def_nr = flip_map[dw->def_nr];
263 void defvert_flip_merged(MDeformVert *dvert, const int *flip_map, const int flip_map_len)
265 MDeformWeight *dw, *dw_cpy;
267 int i, totweight = dvert->totweight;
270 for (dw = dvert->dw, i = 0; i < totweight; dw++, i++) {
271 if (dw->def_nr < flip_map_len) {
272 if (flip_map[dw->def_nr] >= 0) {
273 /* error checkers complain of this but we'll never get NULL return */
274 dw_cpy = defvert_verify_index(dvert, flip_map[dw->def_nr]);
275 dw = &dvert->dw[i]; /* in case array got realloced */
277 /* distribute weights: if only one of the vertex groups was
278 * assigned this will halve the weights, otherwise it gets
279 * evened out. this keeps it proportional to other groups */
280 weight = 0.5f * (dw_cpy->weight + dw->weight);
281 dw_cpy->weight = weight;
288 bDeformGroup *defgroup_find_name(Object *ob, const char *name)
290 /* return a pointer to the deform group with this name
291 * or return NULL otherwise.
293 bDeformGroup *curdef;
295 for (curdef = ob->defbase.first; curdef; curdef = curdef->next) {
296 if (!strcmp(curdef->name, name)) {
303 int defgroup_name_index(Object *ob, const char *name)
305 /* Return the location of the named deform group within the list of
306 * deform groups. This function is a combination of BLI_findlink and
307 * defgroup_find_name. The other two could be called instead, but that
308 * require looping over the vertexgroups twice.
310 bDeformGroup *curdef;
313 if (name && name[0] != '\0') {
314 for (curdef = ob->defbase.first, def_nr = 0; curdef; curdef = curdef->next, def_nr++) {
315 if (!strcmp(curdef->name, name))
323 /* note, must be freed */
324 int *defgroup_flip_map(Object *ob, int *flip_map_len, int use_default)
326 int defbase_tot = *flip_map_len = BLI_countlist(&ob->defbase);
328 if (defbase_tot == 0) {
333 char name[sizeof(dg->name)];
334 int i, flip_num, *map = MEM_mallocN(defbase_tot * sizeof(int), __func__);
336 for (i = 0; i < defbase_tot; i++) {
340 for (dg = ob->defbase.first, i = 0; dg; dg = dg->next, i++) {
341 if (map[i] == -1) { /* may be calculated previously */
343 /* in case no valid value is found, use this */
347 flip_side_name(name, dg->name, FALSE);
348 if (strcmp(name, dg->name)) {
349 flip_num = defgroup_name_index(ob, name);
352 map[flip_num] = i; /* save an extra lookup */
361 /* note, must be freed */
362 int *defgroup_flip_map_single(Object *ob, int *flip_map_len, int use_default, int defgroup)
364 int defbase_tot = *flip_map_len = BLI_countlist(&ob->defbase);
366 if (defbase_tot == 0) {
371 char name[sizeof(dg->name)];
372 int i, flip_num, *map = MEM_mallocN(defbase_tot * sizeof(int), __func__);
374 for (i = 0; i < defbase_tot; i++) {
375 map[i] = use_default ? i : -1;
378 dg = BLI_findlink(&ob->defbase, defgroup);
380 flip_side_name(name, dg->name, FALSE);
381 if (strcmp(name, dg->name)) {
382 flip_num = defgroup_name_index(ob, name);
385 map[defgroup] = flip_num;
386 map[flip_num] = defgroup;
394 int defgroup_flip_index(Object *ob, int index, int use_default)
396 bDeformGroup *dg = BLI_findlink(&ob->defbase, index);
400 char name[sizeof(dg->name)];
401 flip_side_name(name, dg->name, 0);
403 if (strcmp(name, dg->name))
404 flip_index = defgroup_name_index(ob, name);
407 return (flip_index == -1 && use_default) ? index : flip_index;
410 static int defgroup_find_name_dupe(const char *name, bDeformGroup *dg, Object *ob)
412 bDeformGroup *curdef;
414 for (curdef = ob->defbase.first; curdef; curdef = curdef->next) {
416 if (!strcmp(curdef->name, name)) {
425 static int defgroup_unique_check(void *arg, const char *name)
427 struct {Object *ob; void *dg;} *data = arg;
428 return defgroup_find_name_dupe(name, data->dg, data->ob);
431 void defgroup_unique_name(bDeformGroup *dg, Object *ob)
433 struct {Object *ob; void *dg;} data;
437 BLI_uniquename_cb(defgroup_unique_check, &data, "Group", '.', dg->name, sizeof(dg->name));
440 BLI_INLINE int is_char_sep(const char c)
442 return ELEM4(c, '.', ' ', '-', '_');
445 /* finds the best possible flipped name. For renaming; check for unique names afterwards */
446 /* if strip_number: removes number extensions
447 * note: don't use sizeof() for 'name' or 'from_name' */
448 void flip_side_name(char name[MAX_VGROUP_NAME], const char from_name[MAX_VGROUP_NAME], int strip_number)
451 char prefix[MAX_VGROUP_NAME] = ""; /* The part before the facing */
452 char suffix[MAX_VGROUP_NAME] = ""; /* The part after the facing */
453 char replace[MAX_VGROUP_NAME] = ""; /* The replacement string */
454 char number[MAX_VGROUP_NAME] = ""; /* The number extension string */
457 /* always copy the name, since this can be called with an uninitialized string */
458 BLI_strncpy(name, from_name, MAX_VGROUP_NAME);
460 len = BLI_strnlen(from_name, MAX_VGROUP_NAME);
462 /* we don't do names like .R or .L */
466 /* We first check the case with a .### extension, let's find the last period */
467 if (isdigit(name[len - 1])) {
468 index = strrchr(name, '.'); // last occurrence
469 if (index && isdigit(index[1]) ) { // doesnt handle case bone.1abc2 correct..., whatever!
470 if (strip_number == 0) {
471 BLI_strncpy(number, index, sizeof(number));
474 len = BLI_strnlen(name, MAX_VGROUP_NAME);
478 BLI_strncpy(prefix, name, sizeof(prefix));
480 /* first case; separator . - _ with extensions r R l L */
481 if (is_char_sep(name[len - 2]) ) {
482 switch(name[len - 1]) {
485 strcpy(replace, "r");
489 strcpy(replace, "l");
493 strcpy(replace, "R");
497 strcpy(replace, "L");
501 /* case; beginning with r R l L , with separator after it */
502 else if (is_char_sep(name[1]) ) {
505 strcpy(replace, "r");
506 BLI_strncpy(suffix, name + 1, sizeof(suffix));
510 strcpy(replace, "l");
511 BLI_strncpy(suffix, name + 1, sizeof(suffix));
515 strcpy(replace, "R");
516 BLI_strncpy(suffix, name + 1, sizeof(suffix));
520 strcpy(replace, "L");
521 BLI_strncpy(suffix, name + 1, sizeof(suffix));
527 /* hrms, why test for a separator? lets do the rule 'ultimate left or right' */
528 index = BLI_strcasestr(prefix, "right");
529 if (index == prefix || index == prefix + len - 5) {
531 strcpy(replace, "left");
534 strcpy(replace, "LEFT");
536 strcpy(replace, "Left");
539 BLI_strncpy(suffix, index + 5, sizeof(suffix));
542 index = BLI_strcasestr(prefix, "left");
543 if (index == prefix || index == prefix + len - 4) {
545 strcpy(replace, "right");
548 strcpy(replace, "RIGHT");
550 strcpy(replace, "Right");
553 BLI_strncpy(suffix, index + 4, sizeof(suffix));
558 BLI_snprintf (name, MAX_VGROUP_NAME, "%s%s%s%s", prefix, replace, suffix, number);
561 float defvert_find_weight(const struct MDeformVert *dvert, const int defgroup)
563 MDeformWeight *dw = defvert_find_index(dvert, defgroup);
564 return dw ? dw->weight : 0.0f;
567 /* take care with this the rationale is:
568 * - if the object has no vertex group. act like vertex group isn't set and return 1.0,
569 * - if the vertex group exists but the 'defgroup' isn't found on this vertex, _still_ return 0.0
571 * This is a bit confusing, just saves some checks from the caller.
573 float defvert_array_find_weight_safe(const struct MDeformVert *dvert, const int index, const int defgroup)
575 if (defgroup == -1 || dvert == NULL)
578 return defvert_find_weight(dvert + index, defgroup);
582 MDeformWeight *defvert_find_index(const MDeformVert *dvert, const int defgroup)
584 if (dvert && defgroup >= 0) {
585 MDeformWeight *dw = dvert->dw;
588 for (i = dvert->totweight; i != 0; i--, dw++) {
589 if (dw->def_nr == defgroup) {
598 /* Ensures that mv has a deform weight entry for the specified defweight group */
599 /* Note this function is mirrored in editmesh_tools.c, for use for editvertices */
600 MDeformWeight *defvert_verify_index(MDeformVert *dvert, const int defgroup)
602 MDeformWeight *dw_new;
604 /* do this check always, this function is used to check for it */
605 if (!dvert || defgroup < 0)
608 dw_new = defvert_find_index(dvert, defgroup);
612 dw_new = MEM_callocN(sizeof(MDeformWeight) * (dvert->totweight + 1), "deformWeight");
614 memcpy(dw_new, dvert->dw, sizeof(MDeformWeight) * dvert->totweight);
615 MEM_freeN(dvert->dw);
618 dw_new += dvert->totweight;
619 dw_new->weight = 0.0f;
620 dw_new->def_nr = defgroup;
628 /* TODO. merge with code above! */
630 /* Adds the given vertex to the specified vertex group, with given weight.
631 * warning, this does NOT check for existing, assume caller already knows its not there */
632 void defvert_add_index_notest(MDeformVert *dvert, int defgroup, const float weight)
634 MDeformWeight *dw_new;
636 /* do this check always, this function is used to check for it */
637 if (!dvert || defgroup < 0)
640 dw_new = MEM_callocN(sizeof(MDeformWeight) * (dvert->totweight + 1), "defvert_add_to group, new deformWeight");
642 memcpy(dw_new, dvert->dw, sizeof(MDeformWeight) * dvert->totweight);
643 MEM_freeN(dvert->dw);
646 dw_new += dvert->totweight;
647 dw_new->weight = weight;
648 dw_new->def_nr = defgroup;
653 /* Removes the given vertex from the vertex group.
654 * WARNING: This function frees the given MDeformWeight, do not use it afterward! */
655 void defvert_remove_group(MDeformVert *dvert, MDeformWeight *dw)
658 MDeformWeight *dw_new;
659 int i = dw - dvert->dw;
661 /* Security check! */
662 if (i < 0 || i >= dvert->totweight) {
667 /* If there are still other deform weights attached to this vert then remove
668 * this deform weight, and reshuffle the others.
670 if (dvert->totweight) {
671 dw_new = MEM_mallocN(sizeof(MDeformWeight) * (dvert->totweight), __func__);
673 #if 1 /* since we don't care about order, swap this with the last, save a memcpy */
674 if (i != dvert->totweight) {
675 dvert->dw[i] = dvert->dw[dvert->totweight];
677 memcpy(dw_new, dvert->dw, sizeof(MDeformWeight) * dvert->totweight);
679 memcpy(dw_new, dvert->dw, sizeof(MDeformWeight) * i);
680 memcpy(dw_new + i, dvert->dw + i + 1, sizeof(MDeformWeight) * (dvert->totweight - i));
682 MEM_freeN(dvert->dw);
687 /* If there are no other deform weights left then just remove this one. */
688 MEM_freeN(dvert->dw);
694 void defvert_clear(MDeformVert *dvert)
697 MEM_freeN(dvert->dw);
701 dvert->totweight = 0;