diff options
Diffstat (limited to 'source/blender/blenkernel/intern/deform.c')
-rw-r--r-- | source/blender/blenkernel/intern/deform.c | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c index c1e45243bb5..620e114bad2 100644 --- a/source/blender/blenkernel/intern/deform.c +++ b/source/blender/blenkernel/intern/deform.c @@ -34,6 +34,7 @@ #include <string.h> #include <math.h> +#include "ctype.h" #include "MEM_guardedalloc.h" @@ -95,6 +96,36 @@ bDeformGroup *copy_defgroup (bDeformGroup *ingroup) return outgroup; } +void copy_defvert (MDeformVert *dvert_r, const MDeformVert *dvert) +{ + if(dvert_r->totweight == dvert->totweight) { + if(dvert->totweight) + memcpy(dvert_r->dw, dvert->dw, dvert->totweight * sizeof(MDeformWeight)); + } + else { + if(dvert_r->dw) + MEM_freeN(dvert_r->dw); + + if(dvert->totweight) + dvert_r->dw= MEM_dupallocN(dvert->dw); + else + dvert_r->dw= NULL; + + dvert_r->totweight = dvert->totweight; + } +} + +void flip_defvert (MDeformVert *dvert, int *flip_map) +{ + MDeformWeight *dw; + int i; + + for(dw= dvert->dw, i=0; i<dvert->totweight; dw++, i++) + if(flip_map[dw->def_nr] >= 0) + dw->def_nr= flip_map[dw->def_nr]; +} + + bDeformGroup *get_named_vertexgroup (Object *ob, char *name) { /* return a pointer to the deform group with this name @@ -167,6 +198,36 @@ int get_defgroup_num (Object *ob, bDeformGroup *dg) } +/* note, must be freed */ +int *get_defgroup_flip_map(Object *ob) +{ + bDeformGroup *dg; + int totdg= BLI_countlist(&ob->defbase); + + if(totdg==0) { + return NULL; + } + else { + char name[sizeof(dg->name)]; + int i, flip_num, *map= MEM_mallocN(totdg * sizeof(int), "get_defgroup_flip_map"); + memset(map, -1, totdg * sizeof(int)); + + for (dg=ob->defbase.first, i=0; dg; dg=dg->next, i++) { + if(map[i] == -1) { /* may be calculated previously */ + flip_vertexgroup_name(name, dg->name, 0); + if(strcmp(name, dg->name)) { + flip_num= get_named_vertexgroup_num(ob, name); + if(flip_num > -1) { + map[i]= flip_num; + map[flip_num]= i; /* save an extra lookup */ + } + } + } + } + return map; + } +} + void unique_vertexgroup_name (bDeformGroup *dg, Object *ob) { bDeformGroup *curdef; @@ -221,6 +282,121 @@ void unique_vertexgroup_name (bDeformGroup *dg, Object *ob) } } + +/* finds the best possible flipped name. For renaming; check for unique names afterwards */ +/* if strip_number: removes number extensions */ +void flip_vertexgroup_name (char *name_r, const char *name, int strip_number) +{ + int len; + char prefix[sizeof((bDeformGroup *)NULL)->name]={""}; /* The part before the facing */ + char suffix[sizeof((bDeformGroup *)NULL)->name]={""}; /* The part after the facing */ + char replace[sizeof((bDeformGroup *)NULL)->name]={""}; /* The replacement string */ + char number[sizeof((bDeformGroup *)NULL)->name]={""}; /* The number extension string */ + char *index=NULL; + + len= strlen(name); + if(len<3) return; // we don't do names like .R or .L + + /* We first check the case with a .### extension, let's find the last period */ + if(isdigit(name[len-1])) { + index= strrchr(name, '.'); // last occurrence + if (index && isdigit(index[1]) ) { // doesnt handle case bone.1abc2 correct..., whatever! + if(strip_number==0) + strcpy(number, index); + *index= 0; + len= strlen(name); + } + } + + strcpy (prefix, name); + +#define IS_SEPARATOR(a) ((a)=='.' || (a)==' ' || (a)=='-' || (a)=='_') + + /* first case; separator . - _ with extensions r R l L */ + if( IS_SEPARATOR(name[len-2]) ) { + switch(name[len-1]) { + case 'l': + prefix[len-1]= 0; + strcpy(replace, "r"); + break; + case 'r': + prefix[len-1]= 0; + strcpy(replace, "l"); + break; + case 'L': + prefix[len-1]= 0; + strcpy(replace, "R"); + break; + case 'R': + prefix[len-1]= 0; + strcpy(replace, "L"); + break; + } + } + /* case; beginning with r R l L , with separator after it */ + else if( IS_SEPARATOR(name[1]) ) { + switch(name[0]) { + case 'l': + strcpy(replace, "r"); + strcpy(suffix, name+1); + prefix[0]= 0; + break; + case 'r': + strcpy(replace, "l"); + strcpy(suffix, name+1); + prefix[0]= 0; + break; + case 'L': + strcpy(replace, "R"); + strcpy(suffix, name+1); + prefix[0]= 0; + break; + case 'R': + strcpy(replace, "L"); + strcpy(suffix, name+1); + prefix[0]= 0; + break; + } + } + else if(len > 5) { + /* hrms, why test for a separator? lets do the rule 'ultimate left or right' */ + index = BLI_strcasestr(prefix, "right"); + if (index==prefix || index==prefix+len-5) { + if(index[0]=='r') + strcpy (replace, "left"); + else { + if(index[1]=='I') + strcpy (replace, "LEFT"); + else + strcpy (replace, "Left"); + } + *index= 0; + strcpy (suffix, index+5); + } + else { + index = BLI_strcasestr(prefix, "left"); + if (index==prefix || index==prefix+len-4) { + if(index[0]=='l') + strcpy (replace, "right"); + else { + if(index[1]=='E') + strcpy (replace, "RIGHT"); + else + strcpy (replace, "Right"); + } + *index= 0; + strcpy (suffix, index+4); + } + } + } + +#undef IS_SEPARATOR + + sprintf (name_r, "%s%s%s%s", prefix, replace, suffix, number); +} + + + float deformvert_get_weight(const struct MDeformVert *dvert, int group_num) { if(dvert) |