== Automatic Bone Extension Adder ==
authorJoshua Leung <aligorith@gmail.com>
Mon, 28 Jan 2008 00:53:54 +0000 (00:53 +0000)
committerJoshua Leung <aligorith@gmail.com>
Mon, 28 Jan 2008 00:53:54 +0000 (00:53 +0000)
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)

source/blender/blenkernel/BKE_armature.h
source/blender/blenkernel/intern/armature.c
source/blender/include/BIF_editarmature.h
source/blender/include/BIF_poseobject.h
source/blender/src/editarmature.c
source/blender/src/editobject.c
source/blender/src/poseobject.c
source/blender/src/space.c

index fb527051a0d76771c64a39d3ade6bdda61a459da..2c573faeb873a8f220fed847e123de4d560c95bb 100644 (file)
@@ -78,7 +78,9 @@ void unlink_armature(struct bArmature *arm);
 void free_armature(struct bArmature *arm);
 void make_local_armature(struct bArmature *arm);
 struct bArmature *copy_armature(struct bArmature *arm);
+
 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 Bone *get_named_bone (struct bArmature *arm, const char *name);
index f4da821e3eae046d96f5516db763d5faf90f8252..62315412abad2f6dcd7624e71c164b586d08a552 100644 (file)
@@ -30,6 +30,8 @@
 #include <math.h>
 #include <string.h>
 #include <stdio.h>
+#include <float.h>
+
 #include "MEM_guardedalloc.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);
 }
 
+/* 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 ******************* */
 
index 8cf63a005cb92a47ab35b90009e16738baaa3eb3..cc34cb58ae394c963a99428419ab2e6fd79db155 100644 (file)
@@ -128,6 +128,7 @@ int         bone_looper(struct Object *ob, struct Bone *bone, void *data,
 void   undo_push_armature(char *name);
 void   armature_bone_rename(struct bArmature *arm, char *oldname, char *newname);
 void   armature_flip_names(void);
+void   armature_autoside_names(short axis);
 EditBone *armature_bone_get_mirrored(EditBone *ebo);
 void   transform_armature_mirror_update(void);
 
index f356c9d664cb9a06d385ca6b98807f19ca5f1024..3aa4413e9f94ca39564dc58bc00c3a7d5a3c45a1 100644 (file)
@@ -73,6 +73,7 @@ void pose_recalculate_paths(struct Object *ob);
 void pose_clear_paths(struct Object *ob);
 
 void pose_flip_names(void);
+void pose_autoside_names(short axis);
 void pose_activate_flipped_bone(void);
 void pose_movetolayer(void);
 void pose_relax(void);
index 45711bc1cfaaf17a923ecb281c891862fc5f6ddc..763d974406497632ce0c9090bc4f2a848088c0b3 100644 (file)
@@ -3603,13 +3603,37 @@ void armature_flip_names(void)
        allqueue(REDRAWVIEW3D, 0);
        allqueue(REDRAWBUTSEDIT, 0);
        allqueue(REDRAWBUTSOBJECT, 0);
-       allqueue (REDRAWACTION, 0);
+       allqueue(REDRAWACTION, 0);
        allqueue(REDRAWOOPS, 0);
        BIF_undo_push("Flip names");
+}
+
+/* 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 */
+/* context: editmode armature */
 EditBone *armature_bone_get_mirrored(EditBone *ebo)
 {
        EditBone *eboflip= NULL;
index 4e90fbac5acd12758b930ffe4d9683a5f344ca11..ac631cf2a5ca4ec4bcb7cd650273b260583e670f 100644 (file)
@@ -2548,7 +2548,7 @@ void special_editmenu(void)
                DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
        }
        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)
                        subdivide_armature(1);
                if(nr==2) {
@@ -2558,6 +2558,9 @@ void special_editmenu(void)
                }
                else if(nr==3)
                        armature_flip_names();
+               else if(ELEM3(nr, 4, 5, 6)) {
+                       armature_autoside_names(nr-4);
+               }
        }
        else if(G.obedit->type==OB_LATTICE) {
                static float weight= 1.0f;
index 42640465e1201e5234673cdc5af76b7d0bd008d1..e187530d25f9dd380c0bf15c969b9e7690582036 100644 (file)
@@ -490,7 +490,7 @@ void pose_special_editmenu(void)
        if(!ob && !ob->pose) 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) {
                pose_select_constraint_target();
        }
@@ -511,6 +511,9 @@ void pose_special_editmenu(void)
        else if(nr==6) {
                pose_relax();
        }
+       else if(ELEM3(nr, 7, 8, 9)) {
+               pose_autoside_names(nr-7);
+       }
 }
 
 void pose_add_IK(void)
@@ -1154,7 +1157,39 @@ void pose_flip_names(void)
        allqueue (REDRAWACTION, 0);
        allqueue(REDRAWOOPS, 0);
        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 */
index b1d274d670e9c2f92d2972a30df4128e42283dd0..e90c2e99d0af5d4051375e4382feb92aa13a160d 100644 (file)
@@ -3155,6 +3155,9 @@ static void info_user_theme_colsets_buts(uiBlock *block, short y1, short y2, sho
        
        /* 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");
+       
+       /* 'Debug' Tools */
+       // TODO... dump current colours
 }
 
 static void info_user_themebuts(uiBlock *block, short y1, short y2, short y3, short y4)