diff options
author | Campbell Barton <ideasman42@gmail.com> | 2010-01-15 20:28:00 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2010-01-15 20:28:00 +0300 |
commit | ace8d45c1c7cdd754771f9e4aceae80de2154653 (patch) | |
tree | bba878b9d1a1c2f2b835d2d678e88e34b7e85c74 /source/blender/blenkernel/intern | |
parent | a4732eefa5fa4ba06b8042c530748be6a4e4194c (diff) |
- particle drawing was using invalid memory with weights.
- particle set weight operator (Shift + K) and from the menu.
- mirror vertex groups operator can also flip weight group names.
a number of utility functions for weight groups added
int *get_defgroup_flip_map(struct Object *ob);
void flip_vertexgroup_name (char *name_r, const char *name, int strip_number); // moved from modifier.c
void copy_defvert (struct MDeformVert *dvert_r, const struct MDeformVert *dvert);
void flip_defvert (struct MDeformVert *dvert, int *flip_map);
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r-- | source/blender/blenkernel/intern/deform.c | 176 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/modifier.c | 116 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/particle.c | 19 |
3 files changed, 187 insertions, 124 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) diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 7e211f60cd5..3c925e5ff25 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -39,7 +39,6 @@ #include "stdarg.h" #include "math.h" #include "float.h" -#include "ctype.h" #include "BLI_math.h" #include "BLI_blenlib.h" @@ -1801,118 +1800,6 @@ static void mirrorModifier_updateDepgraph(ModifierData *md, DagForest *forest, S } } -/* finds the best possible flipped name. For renaming; check for unique names afterwards */ -/* if strip_number: removes number extensions */ -static void vertgroup_flip_name (char *name, int strip_number) -{ - int len; - char prefix[128]={""}; /* The part before the facing */ - char suffix[128]={""}; /* The part after the facing */ - char replace[128]={""}; /* The replacement string */ - char number[128]={""}; /* 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, "%s%s%s%s", prefix, replace, suffix, number); -} - static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, Object *ob, DerivedMesh *dm, @@ -2022,8 +1909,7 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, continue; def = vector_def[dvert->dw[j].def_nr]; - strcpy(tmpname, def->name); - vertgroup_flip_name(tmpname,0); + flip_vertexgroup_name(tmpname, def->name, 0); for(b = 0, defb = ob->defbase.first; defb; defb = defb->next, b++) diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 63d681cce0b..006e05370b1 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -2999,8 +2999,8 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf /* should init_particle_interpolation set this ? */ if(pset->brushtype==PE_BRUSH_WEIGHT){ - pind.hkey[0] = pa->hair; - pind.hkey[1] = pa->hair + 1; + pind.hkey[0] = NULL; + pind.hkey[1] = pa->hair; } @@ -3036,12 +3036,6 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf do_particle_interpolation(psys, i, pa, t, frs_sec, &pind, &result); - /* should init_particle_interpolation set this ? */ - if(pset->brushtype==PE_BRUSH_WEIGHT){ - pind.hkey[0] = pind.hkey[1]; - pind.hkey[1]++; - } - /* non-hair points are already in global space */ if(psys && !(psys->flag & PSYS_GLOBAL_HAIR)) { mul_m4_v3(hairmat, result.co); @@ -3099,10 +3093,17 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf /* selection coloring in edit mode */ if(pset->brushtype==PE_BRUSH_WEIGHT){ - if(k==steps) + if(k==0) + weight_to_rgb(pind.hkey[1]->weight, ca->col, ca->col+1, ca->col+2); + else if(k >= steps - 1) weight_to_rgb(pind.hkey[0]->weight, ca->col, ca->col+1, ca->col+2); else weight_to_rgb((1.0f - keytime) * pind.hkey[0]->weight + keytime * pind.hkey[1]->weight, ca->col, ca->col+1, ca->col+2); + + /* at the moment this is only used for weight painting. + * will need to move out of this check if its used elsewhere. */ + pind.hkey[0] = pind.hkey[1]; + pind.hkey[1]++; } else { if((ekey + (pind.ekey[0] - point->keys))->flag & PEK_SELECT){ |