== Automatic Bone Extension Adder ==

Added three new tools to the WKEY menu for Armatures in EditMode/PoseMode. These add .* extensions to the names of selected bones based on their position in 3d-space on the axis considered by that tool.

The current naming schemes are based upon the extensions I normally apply. Some people may have slightly different preferences though.

There is one for:
* Left-Right names (along x-axis)
* Front-Back names (along y-axis)
* Top-Bottom names (along z-axis)
This commit is contained in:
Joshua Leung 2008-01-28 00:53:54 +00:00
parent b115bd677b
commit 354e6b9c18
8 changed files with 158 additions and 5 deletions

@ -78,7 +78,9 @@ 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, int strip_number); void bone_flip_name (char *name, int strip_number);
void bone_autoside_name (char *name, int strip_number, short axis, float head, float tail);
struct bArmature *get_armature (struct Object *ob); struct bArmature *get_armature (struct Object *ob);
struct Bone *get_named_bone (struct bArmature *arm, const char *name); struct Bone *get_named_bone (struct bArmature *arm, const char *name);

@ -30,6 +30,8 @@
#include <math.h> #include <math.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <float.h>
#include "MEM_guardedalloc.h" #include "MEM_guardedalloc.h"
#include "nla.h" #include "nla.h"
@ -354,6 +356,88 @@ void bone_flip_name (char *name, int strip_number)
sprintf (name, "%s%s%s%s", prefix, replace, suffix, number); sprintf (name, "%s%s%s%s", prefix, replace, suffix, number);
} }
/* Finds the best possible extension to the name on a particular axis. (For renaming, check for unique names afterwards)
* This assumes that bone names are at most 32 chars long!
* strip_number: removes number extensions (TODO: not used)
* axis: the axis to name on
* head/tail: the head/tail co-ordinate of the bone on the specified axis
*/
void bone_autoside_name (char *name, int strip_number, short axis, float head, float tail)
{
int len;
char basename[32]={""};
char extension[3]={""};
len= strlen(name);
if (len == 0) return;
strcpy(basename, name);
/* Figure out extension to append:
* - The extension to append is based upon the axis that we are working on.
* - If head happens to be on 0, then we must consider the tail position as well to decide
* which side the bone is on
* -> If tail is 0, then it's bone is considered to be on axis, so no extension should be added
* -> Otherwise, extension is added from perspective of object based on which side tail goes to
* - If head is non-zero, extension is added from perspective of object based on side head is on
*/
if (axis == 2) {
/* z-axis - vertical (top/bottom) */
if (IS_EQ(head, 0)) {
if (tail < 0)
strcpy(extension, ".Bot");
else if (tail > 0)
strcpy(extension, ".Top");
}
else {
if (head < 0)
strcpy(extension, ".Bot");
else
strcpy(extension, ".Top");
}
}
else if (axis == 1) {
/* y-axis - depth (front/back) */
if (IS_EQ(head, 0)) {
if (tail < 0)
strcpy(extension, ".Fr");
else if (tail > 0)
strcpy(extension, ".Bk");
}
else {
if (head < 0)
strcpy(extension, ".Fr");
else
strcpy(extension, ".Bk");
}
}
else {
/* x-axis - horizontal (left/right) */
if (IS_EQ(head, 0)) {
if (tail < 0)
strcpy(extension, ".R");
else if (tail > 0)
strcpy(extension, ".L");
}
else {
if (head < 0)
strcpy(extension, ".R");
else if (head > 0)
strcpy(extension, ".L");
}
}
/* Simple name truncation
* - truncate if there is an extension and it wouldn't be able to fit
* - otherwise, just append to end (TODO: this should really check if there was already a tag there, and remove it)
*/
if (extension[0]) {
if ((32 - len) < strlen(extension)) {
strncpy(name, basename, len-strlen(extension);
}
}
sprintf(name, "%s%s", basename, extension);
}
/* ************* B-Bone support ******************* */ /* ************* B-Bone support ******************* */

@ -128,6 +128,7 @@ int bone_looper(struct 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); void armature_flip_names(void);
void armature_autoside_names(short axis);
EditBone *armature_bone_get_mirrored(EditBone *ebo); EditBone *armature_bone_get_mirrored(EditBone *ebo);
void transform_armature_mirror_update(void); void transform_armature_mirror_update(void);

@ -73,6 +73,7 @@ void pose_recalculate_paths(struct Object *ob);
void pose_clear_paths(struct Object *ob); void pose_clear_paths(struct Object *ob);
void pose_flip_names(void); void pose_flip_names(void);
void pose_autoside_names(short axis);
void pose_activate_flipped_bone(void); void pose_activate_flipped_bone(void);
void pose_movetolayer(void); void pose_movetolayer(void);
void pose_relax(void); void pose_relax(void);

@ -3603,13 +3603,37 @@ void armature_flip_names(void)
allqueue(REDRAWVIEW3D, 0); allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWBUTSEDIT, 0); allqueue(REDRAWBUTSEDIT, 0);
allqueue(REDRAWBUTSOBJECT, 0); allqueue(REDRAWBUTSOBJECT, 0);
allqueue (REDRAWACTION, 0); allqueue(REDRAWACTION, 0);
allqueue(REDRAWOOPS, 0); allqueue(REDRAWOOPS, 0);
BIF_undo_push("Flip names"); BIF_undo_push("Flip names");
} }
/* context; editmode armature */ /* context: edtimode armature */
void armature_autoside_names(short axis)
{
bArmature *arm= G.obedit->data;
EditBone *ebone;
char newname[32];
for (ebone = G.edbo.first; ebone; ebone=ebone->next) {
if (arm->layer & ebone->layer) {
if (ebone->flag & BONE_SELECTED) {
BLI_strncpy(newname, ebone->name, sizeof(newname));
bone_autoside_name(newname, 1, axis, ebone->head[axis], ebone->tail[axis]);
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("Auto-side name");
}
/* context: editmode armature */
EditBone *armature_bone_get_mirrored(EditBone *ebo) EditBone *armature_bone_get_mirrored(EditBone *ebo)
{ {
EditBone *eboflip= NULL; EditBone *eboflip= NULL;

@ -2548,7 +2548,7 @@ 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) { else if(G.obedit->type==OB_ARMATURE) {
nr= pupmenu("Specials%t|Subdivide %x1|Subdivide Multi%x2|Flip Left-Right Names%x3"); nr= pupmenu("Specials%t|Subdivide %x1|Subdivide Multi%x2|Flip Left-Right Names%x3|%l|AutoName Left-Right%x4|AutoName Front-Back%x5|AutoName Top-Bottom%x6");
if(nr==1) if(nr==1)
subdivide_armature(1); subdivide_armature(1);
if(nr==2) { if(nr==2) {
@ -2558,6 +2558,9 @@ void special_editmenu(void)
} }
else if(nr==3) else if(nr==3)
armature_flip_names(); armature_flip_names();
else if(ELEM3(nr, 4, 5, 6)) {
armature_autoside_names(nr-4);
}
} }
else if(G.obedit->type==OB_LATTICE) { else if(G.obedit->type==OB_LATTICE) {
static float weight= 1.0f; static float weight= 1.0f;

@ -490,7 +490,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%x2|Calculate Paths%x3|Clear Paths%x4|Clear User Transform %x5|Relax Pose %x6"); nr= pupmenu("Specials%t|Select Constraint Target%x1|Flip Left-Right Names%x2|Calculate Paths%x3|Clear Paths%x4|Clear User Transform %x5|Relax Pose %x6|%l|AutoName Left-Right%x7|AutoName Front-Back%x8|AutoName Top-Bottom%x9");
if(nr==1) { if(nr==1) {
pose_select_constraint_target(); pose_select_constraint_target();
} }
@ -511,6 +511,9 @@ void pose_special_editmenu(void)
else if(nr==6) { else if(nr==6) {
pose_relax(); pose_relax();
} }
else if(ELEM3(nr, 7, 8, 9)) {
pose_autoside_names(nr-7);
}
} }
void pose_add_IK(void) void pose_add_IK(void)
@ -1154,7 +1157,39 @@ void pose_flip_names(void)
allqueue (REDRAWACTION, 0); allqueue (REDRAWACTION, 0);
allqueue(REDRAWOOPS, 0); allqueue(REDRAWOOPS, 0);
BIF_undo_push("Flip names"); BIF_undo_push("Flip names");
}
/* context active object */
void pose_autoside_names(short axis)
{
Object *ob= OBACT;
bArmature *arm= ob->data;
bPoseChannel *pchan;
char newname[32];
/* paranoia checks */
if (ELEM(NULL, ob, ob->pose)) return;
if (ob==G.obedit || (ob->flag & OB_POSEMODE)==0) return;
if (pose_has_protected_selected(ob, 0))
return;
for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
if(arm->layer & pchan->bone->layer) {
if(pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) {
BLI_strncpy(newname, pchan->name, sizeof(newname));
bone_autoside_name(newname, 1, axis, pchan->bone->head[axis], pchan->bone->tail[axis]);
armature_bone_rename(ob->data, pchan->name, newname);
}
}
}
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWBUTSEDIT, 0);
allqueue(REDRAWBUTSOBJECT, 0);
allqueue (REDRAWACTION, 0);
allqueue(REDRAWOOPS, 0);
BIF_undo_push("Flip names");
} }
/* context active object, or weightpainted object with armature in posemode */ /* context active object, or weightpainted object with armature in posemode */

@ -3155,6 +3155,9 @@ static void info_user_theme_colsets_buts(uiBlock *block, short y1, short y2, sho
/* Extra 'Options' */ /* Extra 'Options' */
uiDefButBitS(block, TOG, TH_WIRECOLOR_CONSTCOLS, B_UPDATE_THEME, "Use 'Constraint' Colouring", 885,y2,200,20, &col_set->flag, 0, 0, 0, 0, "Allow the use of colors indicating constraints/keyed status"); uiDefButBitS(block, TOG, TH_WIRECOLOR_CONSTCOLS, B_UPDATE_THEME, "Use 'Constraint' Colouring", 885,y2,200,20, &col_set->flag, 0, 0, 0, 0, "Allow the use of colors indicating constraints/keyed status");
/* 'Debug' Tools */
// TODO... dump current colours
} }
static void info_user_themebuts(uiBlock *block, short y1, short y2, short y3, short y4) static void info_user_themebuts(uiBlock *block, short y1, short y2, short y3, short y4)