diff options
author | Campbell Barton <ideasman42@gmail.com> | 2010-11-01 10:19:41 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2010-11-01 10:19:41 +0300 |
commit | daa4feaaeae4312eb23f66b948b668a7e9dc1959 (patch) | |
tree | dabd2bedd213f9fdfbfc31e6710b2913707dfa1f /source/blender/blenkernel/intern | |
parent | 8bbcef4c7a377045f6b93580efda93eb4adf800d (diff) |
bugfix [#24477] Can easily create bones with duplicate names
- fixed this error 7 different functions (deform groups, uv layers & similar).
- support for numbers over 999.
- renamed splitIDname() to BLI_split_name_num(), moved to BLI_path_utils
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r-- | source/blender/blenkernel/intern/customdata.c | 93 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/deform.c | 68 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/library.c | 33 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mball.c | 18 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/nla.c | 32 |
5 files changed, 92 insertions, 152 deletions
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 9c4f0d790ca..c1aaa869876 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -2249,69 +2249,56 @@ static int CustomData_is_property_layer(int type) return 0; } -void CustomData_set_layer_unique_name(CustomData *data, int index) +static int cd_layer_find_dupe(CustomData *data, const char *name, int type, int index) { - char tempname[64]; - int number, i, type; - char *dot, *name; - CustomDataLayer *layer, *nlayer= &data->layers[index]; - const LayerTypeInfo *typeInfo= layerType_getInfo(nlayer->type); - - if (!typeInfo->defaultname) - return; - - type = nlayer->type; - name = nlayer->name; - - if (name[0] == '\0') - BLI_strncpy(nlayer->name, typeInfo->defaultname, sizeof(nlayer->name)); - + int i; /* see if there is a duplicate */ for(i=0; i<data->totlayer; i++) { - layer = &data->layers[i]; - - if(CustomData_is_property_layer(type)){ - if(i!=index && CustomData_is_property_layer(layer->type) && - strcmp(layer->name, name)==0) - break; - - } - else{ - if(i!=index && layer->type==type && strcmp(layer->name, name)==0) - break; + if(i != index) { + CustomDataLayer *layer= &data->layers[i]; + + if(CustomData_is_property_layer(type)) { + if(CustomData_is_property_layer(layer->type) && strcmp(layer->name, name)==0) { + return 1; + } + } + else{ + if(i!=index && layer->type==type && strcmp(layer->name, name)==0) { + return 1; + } + } } } + + return 0; +} - if(i == data->totlayer) - return; +void CustomData_set_layer_unique_name(CustomData *data, int index) +{ + CustomDataLayer *nlayer= &data->layers[index]; + const LayerTypeInfo *typeInfo= layerType_getInfo(nlayer->type); - /* strip off the suffix */ - dot = strchr(nlayer->name, '.'); - if(dot) *dot=0; - - for(number=1; number <=999; number++) { - sprintf(tempname, "%s.%03d", nlayer->name, number); + if (!typeInfo->defaultname) + return; - for(i=0; i<data->totlayer; i++) { - layer = &data->layers[i]; - - if(CustomData_is_property_layer(type)){ - if(i!=index && CustomData_is_property_layer(layer->type) && - strcmp(layer->name, tempname)==0) + if (nlayer->name[0] == '\0') + BLI_strncpy(nlayer->name, typeInfo->defaultname, sizeof(nlayer->name)); - break; + if(cd_layer_find_dupe(data, nlayer->name, nlayer->type, index)) { + /* note: this block is used in other places, when changing logic apply to all others, search this message */ + char tempname[sizeof(nlayer->name)]; + char left[sizeof(nlayer->name)]; + int number; + int len= BLI_split_name_num(left, &number, nlayer->name); + do { /* nested while loop looks bad but likely it wont run most times */ + while(BLI_snprintf(tempname, sizeof(tempname), "%s.%03d", left, number) >= sizeof(tempname)) { + if(len > 0) left[--len]= '\0'; /* word too long */ + else number= 0; /* reset, must be a massive number */ } - else{ - if(i!=index && layer->type==type && strcmp(layer->name, tempname)==0) - break; - } - } - - if(i == data->totlayer) { - BLI_strncpy(nlayer->name, tempname, sizeof(nlayer->name)); - return; - } - } + } while(number++, cd_layer_find_dupe(data, tempname, nlayer->type, index)); + + BLI_strncpy(nlayer->name, tempname, sizeof(nlayer->name)); + } } int CustomData_verify_versions(struct CustomData *data, int index) diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c index 91584b6236f..10fbd247c84 100644 --- a/source/blender/blenkernel/intern/deform.c +++ b/source/blender/blenkernel/intern/deform.c @@ -304,14 +304,23 @@ int defgroup_flip_index(Object *ob, int index, int use_default) return (flip_index==-1 && use_default) ? index : flip_index; } -void defgroup_unique_name (bDeformGroup *dg, Object *ob) +static int defgroup_find_name_dupe(const char *name, bDeformGroup *dg, Object *ob) { bDeformGroup *curdef; - int number; - int exists = 0; - char tempname[64]; - char *dot; + for (curdef = ob->defbase.first; curdef; curdef=curdef->next) { + if (dg!=curdef) { + if (!strcmp(curdef->name, name)) { + return 1; + } + } + } + + return 0; +} + +void defgroup_unique_name (bDeformGroup *dg, Object *ob) +{ if (!ob) return; @@ -320,44 +329,23 @@ void defgroup_unique_name (bDeformGroup *dg, Object *ob) /* give it default name first */ strcpy (dg->name, "Group"); } - - /* See if we even need to do this */ - for (curdef = ob->defbase.first; curdef; curdef=curdef->next) { - if (dg!=curdef) { - if (!strcmp(curdef->name, dg->name)) { - exists = 1; - break; - } - } - } - - if (!exists) - return; - /* Strip off the suffix */ - dot=strchr(dg->name, '.'); - if (dot) - *dot=0; - - for (number = 1; number <=999; number++) { - sprintf (tempname, "%s.%03d", dg->name, number); - - exists = 0; - for (curdef=ob->defbase.first; curdef; curdef=curdef->next) { - if (dg!=curdef) { - if (!strcmp (curdef->name, tempname)) { - exists = 1; - break; - } + if(defgroup_find_name_dupe(dg->name, dg, ob)) { + /* note: this block is used in other places, when changing logic apply to all others, search this message */ + char tempname[sizeof(dg->name)]; + char left[sizeof(dg->name)]; + int number; + int len= BLI_split_name_num(left, &number, dg->name); + do { /* nested while loop looks bad but likely it wont run most times */ + while(BLI_snprintf(tempname, sizeof(tempname), "%s.%03d", left, number) >= sizeof(tempname)) { + if(len > 0) left[--len]= '\0'; /* word too long */ + else number= 0; /* reset, must be a massive number */ } - } - if (!exists) { - BLI_strncpy (dg->name, tempname, 32); - return; - } - } -} + } while(number++, defgroup_find_name_dupe(tempname, dg, ob)); + BLI_strncpy(dg->name, tempname, sizeof(dg->name)); + } +} /* finds the best possible flipped name. For renaming; check for unique names afterwards */ /* if strip_number: removes number extensions */ diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index dc3c120ab19..4227c633c0b 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -984,35 +984,6 @@ void IMAnames_to_pupstring(char **str, char *title, char *extraops, ListBase *lb BLI_dynstr_free(pupds); } - -/* used by buttons.c library.c mball.c */ -int splitIDname(char *name, char *left, int *nr) -{ - int a; - - *nr= 0; - strncpy(left, name, 21); - - a= strlen(name); - if(a>1 && name[a-1]=='.') return a; - - while(a--) { - if( name[a]=='.' ) { - left[a]= 0; - *nr= atol(name+a+1); - return a; - } - if( isdigit(name[a])==0 ) break; - - left[a]= 0; - } - - for(a= 0; name[a]; a++) - left[a]= name[a]; - - return a; -} - static void sort_alpha_id(ListBase *lb, ID *id) { ID *idtest; @@ -1092,7 +1063,7 @@ static int check_for_dupid(ListBase *lb, ID *id, char *name) memset(in_use, 0, sizeof(in_use)); /* get name portion, number portion ("name.number") */ - left_len= splitIDname(name, left, &nr); + left_len= BLI_split_name_num(left, &nr, name); /* if new name will be too long, truncate it */ if(nr > 999 && left_len > 16) { @@ -1109,7 +1080,7 @@ static int check_for_dupid(ListBase *lb, ID *id, char *name) (idtest->lib == NULL) && (*name == *(idtest->name+2)) && (strncmp(name, idtest->name+2, left_len)==0) && - (splitIDname(idtest->name+2, leftest, &nrtest) == left_len) + (BLI_split_name_num(leftest, &nrtest, idtest->name+2) == left_len) ) { if(nrtest < sizeof(in_use)) in_use[nrtest]= 1; /* mark as used */ diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c index e6f38e04d76..fd3bc47da9e 100644 --- a/source/blender/blenkernel/intern/mball.c +++ b/source/blender/blenkernel/intern/mball.c @@ -330,8 +330,8 @@ int is_mball_basis_for(Object *ob1, Object *ob2) int basis1nr, basis2nr; char basis1name[32], basis2name[32]; - splitIDname(ob1->id.name+2, basis1name, &basis1nr); - splitIDname(ob2->id.name+2, basis2name, &basis2nr); + BLI_split_name_num(basis1name, &basis1nr, ob1->id.name+2); + BLI_split_name_num(basis2name, &basis2nr, ob2->id.name+2); if(!strcmp(basis1name, basis2name)) return is_basis_mball(ob1); else return 0; @@ -352,7 +352,7 @@ void copy_mball_properties(Scene *scene, Object *active_object) int basisnr, obnr; char basisname[32], obname[32]; - splitIDname(active_object->id.name+2, basisname, &basisnr); + BLI_split_name_num(basisname, &basisnr, active_object->id.name+2); /* XXX recursion check, see scene.c, just too simple code this next_object() */ if(F_ERROR==next_object(&sce_iter, 0, 0, 0)) @@ -361,7 +361,7 @@ void copy_mball_properties(Scene *scene, Object *active_object) while(next_object(&sce_iter, 1, &base, &ob)) { if (ob->type==OB_MBALL) { if(ob!=active_object){ - splitIDname(ob->id.name+2, obname, &obnr); + BLI_split_name_num(obname, &obnr, ob->id.name+2); /* Object ob has to be in same "group" ... it means, that it has to have * same base of its name */ @@ -394,8 +394,8 @@ Object *find_basis_mball(Scene *scene, Object *basis) MetaElem *ml=NULL; int basisnr, obnr; char basisname[32], obname[32]; - - splitIDname(basis->id.name+2, basisname, &basisnr); + + BLI_split_name_num(basisname, &basisnr, basis->id.name+2); totelem= 0; /* XXX recursion check, see scene.c, just too simple code this next_object() */ @@ -415,7 +415,7 @@ Object *find_basis_mball(Scene *scene, Object *basis) else ml= mb->elems.first; } else{ - splitIDname(ob->id.name+2, obname, &obnr); + BLI_split_name_num(obname, &obnr, ob->id.name+2); /* object ob has to be in same "group" ... it means, that it has to have * same base of its name */ @@ -1572,7 +1572,7 @@ float init_meta(Scene *scene, Object *ob) /* return totsize */ invert_m4_m4(obinv, ob->obmat); a= 0; - splitIDname(ob->id.name+2, obname, &obnr); + BLI_split_name_num(obname, &obnr, ob->id.name+2); /* make main array */ next_object(&sce_iter, 0, 0, 0); @@ -1593,7 +1593,7 @@ float init_meta(Scene *scene, Object *ob) /* return totsize */ char name[32]; int nr; - splitIDname(bob->id.name+2, name, &nr); + BLI_split_name_num(name, &nr, bob->id.name+2); if( strcmp(obname, name)==0 ) { mb= bob->data; diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c index 67c3e746a63..6c8eb69703f 100644 --- a/source/blender/blenkernel/intern/nla.c +++ b/source/blender/blenkernel/intern/nla.c @@ -1260,27 +1260,21 @@ void BKE_nlastrip_validate_name (AnimData *adt, NlaStrip *strip) * - in an extreme case, it might not be able to find a name, but then everything else in Blender would fail too :) */ if (BLI_ghash_haskey(gh, strip->name)) { - char tempname[128]; - int number = 1; - char *dot; - - /* Strip off the suffix */ - dot = strrchr(strip->name, '.'); - if (dot) *dot=0; - - /* Try different possibilities */ - for (number = 1; number <= 999; number++) { - /* assemble alternative name */ - BLI_snprintf(tempname, 128, "%s.%03d", strip->name, number); - - /* if hash doesn't have this, set it */ - if (BLI_ghash_haskey(gh, tempname) == 0) { - BLI_strncpy(strip->name, tempname, sizeof(strip->name)); - break; + /* note: this block is used in other places, when changing logic apply to all others, search this message */ + char tempname[sizeof(strip->name)]; + char left[sizeof(strip->name)]; + int number; + int len= BLI_split_name_num(left, &number, strip->name); + do { /* nested while loop looks bad but likely it wont run most times */ + while(BLI_snprintf(tempname, sizeof(tempname), "%s.%03d", left, number) >= sizeof(tempname)) { + if(len > 0) left[--len]= '\0'; /* word too long */ + else number= 0; /* reset, must be a massive number */ } - } - } + } while(number++, BLI_ghash_haskey(gh, tempname)); + BLI_strncpy(strip->name, tempname, sizeof(strip->name)); + } + /* free the hash... */ BLI_ghash_free(gh, NULL, NULL); } |