New; Wkey in Armature Editmode. Has option for flipping names too.

(And moved flip_name to armature kernel)
This commit is contained in:
2005-08-13 19:41:45 +00:00
parent 184e4fdaae
commit 109950ada4
6 changed files with 161 additions and 132 deletions

View File

@@ -72,6 +72,7 @@ void unlink_armature(struct bArmature *arm);
void free_armature(struct bArmature *arm); void free_armature(struct bArmature *arm);
void make_local_armature(struct bArmature *arm); void make_local_armature(struct bArmature *arm);
struct bArmature *copy_armature(struct bArmature *arm); struct bArmature *copy_armature(struct bArmature *arm);
void bone_flip_name (char *name);
void calc_armature_deform (struct Object *ob, float *co, int index); void calc_armature_deform (struct Object *ob, float *co, int index);

View File

@@ -25,6 +25,7 @@
* ***** END GPL/BL DUAL LICENSE BLOCK ***** * ***** END GPL/BL DUAL LICENSE BLOCK *****
*/ */
#include <ctype.h>
#include <stdlib.h> #include <stdlib.h>
#include <math.h> #include <math.h>
#include <string.h> #include <string.h>
@@ -241,6 +242,133 @@ Bone *get_named_bone (bArmature *arm, const char *name)
return bone; return bone;
} }
static char *strcasestr_(register char *s, register char *find)
{
register char c, sc;
register size_t len;
if ((c = *find++) != 0) {
c= tolower(c);
len = strlen(find);
do {
do {
if ((sc = *s++) == 0)
return (NULL);
sc= tolower(sc);
} while (sc != c);
} while (BLI_strncasecmp(s, find, len) != 0);
s--;
}
return ((char *) s);
}
#define IS_SEPARATOR(a) (a=='.' || a==' ' || a=='-' || a=='_')
/* finds the best possible flipped name, removing number extensions. For renaming; check for unique names afterwards */
void bone_flip_name (char *name)
{
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 *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 occurrance
if (index && isdigit(index[1]) ) { // doesnt handle case bone.1abc2 correct..., whatever!
*index= 0;
len= strlen(name);
}
}
strcpy (prefix, name);
/* 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 = 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 = 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);
}
}
}
sprintf (name, "%s%s%s", prefix, replace, suffix);
}
/* ************* B-Bone support ******************* */ /* ************* B-Bone support ******************* */
#define MAX_BBONE_SUBDIV 32 #define MAX_BBONE_SUBDIV 32
@@ -515,7 +643,6 @@ void calc_armature_deform (Object *ob, float *co, int index)
void armature_deform_verts(Object *armOb, Object *target, float (*vertexCos)[3], int numVerts) void armature_deform_verts(Object *armOb, Object *target, float (*vertexCos)[3], int numVerts)
{ {
bArmature *arm = armOb->data;
bPoseChannel **defnrToPC = NULL; bPoseChannel **defnrToPC = NULL;
MDeformVert *dverts; MDeformVert *dverts;
float obinv[4][4], premat[4][4], postmat[4][4]; float obinv[4][4], premat[4][4], postmat[4][4];

View File

@@ -124,6 +124,7 @@ int ik_chain_looper(Object *ob, struct Bone *bone, void *data,
void undo_push_armature(char *name); void undo_push_armature(char *name);
void armature_bone_rename(struct bArmature *arm, char *oldname, char *newname); void armature_bone_rename(struct bArmature *arm, char *oldname, char *newname);
void armature_flip_names(void);
#define BONESEL_ROOT 0x10000000 #define BONESEL_ROOT 0x10000000

View File

@@ -2356,5 +2356,26 @@ void armature_bone_rename(bArmature *arm, char *oldnamep, char *newnamep)
} }
} }
/* context editmode object */
void armature_flip_names(void)
{
EditBone *ebone;
char newname[32];
for (ebone = G.edbo.first; ebone; ebone=ebone->next) {
if(ebone->flag & BONE_SELECTED) {
BLI_strncpy(newname, ebone->name, sizeof(newname));
bone_flip_name(newname);
armature_bone_rename(G.obedit->data, ebone->name, newname);
}
}
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWBUTSEDIT, 0);
allqueue(REDRAWBUTSOBJECT, 0);
allqueue (REDRAWACTION, 0);
allqueue(REDRAWOOPS, 0);
BIF_undo_push("Flip names");
}

View File

@@ -2129,6 +2129,12 @@ void special_editmenu(void)
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
} }
else if(G.obedit->type==OB_ARMATURE) {
nr= pupmenu("Specials%t|Flip Left-Right Names%x1");
if(nr==1) {
armature_flip_names();
}
}
countall(); countall();
allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWVIEW3D, 0);

View File

@@ -26,7 +26,6 @@
* support for animation modes - Reevan McKay * support for animation modes - Reevan McKay
*/ */
#include <ctype.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -190,7 +189,7 @@ void pose_special_editmenu(void)
if(!ob && !ob->pose) return; if(!ob && !ob->pose) return;
if(ob==G.obedit || (ob->flag & OB_POSEMODE)==0) return; if(ob==G.obedit || (ob->flag & OB_POSEMODE)==0) return;
nr= pupmenu("Specials%t|Select Constraint Target%x1|Flip Left-Right Names"); nr= pupmenu("Specials%t|Select Constraint Target%x1|Flip Left-Right Names%x2");
if(nr==1) { if(nr==1) {
pose_select_constraint_target(); pose_select_constraint_target();
} }
@@ -441,132 +440,6 @@ void copy_posebuf (void)
} }
static char *strcasestr_(register char *s, register char *find)
{
register char c, sc;
register size_t len;
if ((c = *find++) != 0) {
c= tolower(c);
len = strlen(find);
do {
do {
if ((sc = *s++) == 0)
return (NULL);
sc= tolower(sc);
} while (sc != c);
} while (BLI_strncasecmp(s, find, len) != 0);
s--;
}
return ((char *) s);
}
#define IS_SEPARATOR(a) (a=='.' || a==' ' || a=='-' || a=='_')
/* finds the best possible flipped name, removing number extensions. For renaming; check for unique names afterwards */
static void flip_name (char *name)
{
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 *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 occurrance
if (index && isdigit(index[1]) ) { // doesnt handle case bone.1abc2 correct..., whatever!
*index= 0;
len= strlen(name);
}
}
strcpy (prefix, name);
/* 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 = 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 = 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);
}
}
}
sprintf (name, "%s%s%s", prefix, replace, suffix);
}
void paste_posebuf (int flip) void paste_posebuf (int flip)
{ {
Object *ob= OBACT; Object *ob= OBACT;
@@ -589,7 +462,7 @@ void paste_posebuf (int flip)
if (chan->flag & POSE_KEY) { if (chan->flag & POSE_KEY) {
BLI_strncpy(name, chan->name, sizeof(name)); BLI_strncpy(name, chan->name, sizeof(name));
if (flip) if (flip)
flip_name (name); bone_flip_name (name);
/* only copy when channel exists, poses are not meant to add random channels to anymore */ /* only copy when channel exists, poses are not meant to add random channels to anymore */
pchan= get_pose_channel(ob->pose, name); pchan= get_pose_channel(ob->pose, name);
@@ -671,7 +544,7 @@ void pose_flip_names(void)
for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
if(pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) { if(pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) {
BLI_strncpy(newname, pchan->name, sizeof(newname)); BLI_strncpy(newname, pchan->name, sizeof(newname));
flip_name(newname); bone_flip_name(newname);
armature_bone_rename(ob->data, pchan->name, newname); armature_bone_rename(ob->data, pchan->name, newname);
} }
} }