Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2010-11-01 10:19:41 +0300
committerCampbell Barton <ideasman42@gmail.com>2010-11-01 10:19:41 +0300
commitdaa4feaaeae4312eb23f66b948b668a7e9dc1959 (patch)
treedabd2bedd213f9fdfbfc31e6710b2913707dfa1f /source/blender/blenkernel/intern
parent8bbcef4c7a377045f6b93580efda93eb4adf800d (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.c93
-rw-r--r--source/blender/blenkernel/intern/deform.c68
-rw-r--r--source/blender/blenkernel/intern/library.c33
-rw-r--r--source/blender/blenkernel/intern/mball.c18
-rw-r--r--source/blender/blenkernel/intern/nla.c32
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);
}