Revision: 15944
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15944
Author:   broken
Date:     2008-08-04 13:47:17 +0200 (Mon, 04 Aug 2008)

Log Message:
-----------
* Armature hierarchy selection tools
These are for use in pose mode or armature edit mode, to let you quickly 
traverse up and down a chain of bones. 
It's quite useful for bones that are in hard-to-click places.

The tools are:
*Select parent/child ( [ and ] )
selects the parent or child of the active bone, deselecting the original active 
bone

* Extend select parent/child (shift [ and shift ] )
selects the parent or child of the active bone, adding to the selection

Thanks to Joshua for reviewing this so promptly!

PS. I'd like to use these [ and ] keys more widely in blender as consistent 
'select next / previous' tools. I can imagine it being very useful for a lot of 
things like keyframes, nodes, mesh edges, etc.

Modified Paths:
--------------
    trunk/blender/source/blender/include/BIF_editarmature.h
    trunk/blender/source/blender/include/BIF_poseobject.h
    trunk/blender/source/blender/src/editarmature.c
    trunk/blender/source/blender/src/header_view3d.c
    trunk/blender/source/blender/src/poseobject.c
    trunk/blender/source/blender/src/space.c

Modified: trunk/blender/source/blender/include/BIF_editarmature.h
===================================================================
--- trunk/blender/source/blender/include/BIF_editarmature.h     2008-08-04 
08:39:10 UTC (rev 15943)
+++ trunk/blender/source/blender/include/BIF_editarmature.h     2008-08-04 
11:47:17 UTC (rev 15944)
@@ -108,7 +108,8 @@
 void   remake_editArmature(void);
 void   selectconnected_armature(void);
 void   selectconnected_posearmature(void);
-void   select_bone_parent(void);
+void   armature_select_hierarchy(short direction, short add_to_sel);
+
 void   setflag_armature(short mode);
 void    unique_editbone_name (struct ListBase *ebones, char *name);
 
@@ -143,6 +144,10 @@
 
 #define BONESEL_NOSEL  0x80000000      /* Indicates a negative number */
 
+/* used in bone_select_hierachy() */
+#define BONE_SELECT_PARENT     0
+#define BONE_SELECT_CHILD      1
+
 #endif
 
 

Modified: trunk/blender/source/blender/include/BIF_poseobject.h
===================================================================
--- trunk/blender/source/blender/include/BIF_poseobject.h       2008-08-04 
08:39:10 UTC (rev 15943)
+++ trunk/blender/source/blender/include/BIF_poseobject.h       2008-08-04 
11:47:17 UTC (rev 15944)
@@ -65,6 +65,8 @@
 void pose_remove_from_posegroups(void);
 void pgroup_operation_with_menu(void);
 
+void pose_select_hierarchy(short direction, short add_to_sel);
+
 void pose_select_grouped(short nr);
 void pose_select_grouped_menu(void);
 

Modified: trunk/blender/source/blender/src/editarmature.c
===================================================================
--- trunk/blender/source/blender/src/editarmature.c     2008-08-04 08:39:10 UTC 
(rev 15943)
+++ trunk/blender/source/blender/src/editarmature.c     2008-08-04 11:47:17 UTC 
(rev 15944)
@@ -1033,87 +1033,6 @@
        return NULL;
 }
 
-/* used by posemode and editmode */
-void select_bone_parent (void)
-{
-       Object *ob;
-       bArmature *arm; 
-       
-       /* get data */
-       if (G.obedit)
-               ob= G.obedit;
-       else if (OBACT)
-               ob= OBACT;
-       else
-               return;
-       arm= (bArmature *)ob->data;
-       
-       /* determine which mode armature is in */
-       if ((!G.obedit) && (ob->flag & OB_POSEMODE)) {
-               /* deal with pose channels */
-               /* channels are sorted on dependency, so the loop below won't 
result in a flood-select */
-               bPoseChannel *pchan=NULL;
-               
-               for (pchan= ob->pose->chanbase.first; pchan; pchan= 
pchan->next) {
-                       /* check if bone in original selection */
-                       if (pchan->bone->flag & BONE_SELECTED) {
-                               bPoseChannel *chanpar= pchan->parent;
-                               
-                               /* check if any parent */
-                               if ((chanpar) && ((chanpar->bone->flag & 
BONE_SELECTED)==0)) {
-                                       chanpar->bone->flag |= BONE_SELECTED;
-                                       select_actionchannel_by_name 
(ob->action, pchan->name, 1);
-                               }
-                       }
-               }
-       }
-       else if (G.obedit) {
-               /* deal with editbones */
-               EditBone *curbone, *parbone, *parpar;
-               
-               /* prevent floods */
-               for (curbone= G.edbo.first; curbone; curbone= curbone->next)
-                       curbone->temp= NULL;
-               
-               for (curbone= G.edbo.first; curbone; curbone= curbone->next) {
-                       /* check if bone selected */
-                       if ((curbone->flag & BONE_SELECTED) && 
curbone->temp==NULL) {
-                               parbone= curbone->parent;
-                               
-                               /* check if any parent */
-                               if ((parbone) && ((parbone->flag & 
BONE_SELECTED)==0)) {
-                                       /* select the parent bone */
-                                       parbone->flag |= 
(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
-                                       
-                                       /* check if parent has parent */
-                                       parpar= parbone->parent;
-                                       
-                                       if ((parpar) && (parbone->flag & 
BONE_CONNECTED)) {
-                                               parpar->flag |= BONE_TIPSEL;
-                                       }
-                                       /* tag this bone to not flood selection 
*/
-                                       parbone->temp= parbone;
-                               }
-                       }
-               }
-               
-               /* to be sure... */
-               for (curbone= G.edbo.first; curbone; curbone= curbone->next)
-                       curbone->temp= NULL;
-               
-       }
-       
-       /* undo + redraw pushes */
-       countall(); // flushes selection!
-
-       allqueue (REDRAWVIEW3D, 0);
-       allqueue (REDRAWBUTSEDIT, 0);
-       allqueue(REDRAWBUTSOBJECT, 0);
-       allqueue(REDRAWOOPS, 0);
-       
-       BIF_undo_push("Select Parent");
-}
-
 /* helper for setflag_sel_bone() */
 static void bone_setflag (int *bone, int flag, short mode)
 {
@@ -1139,6 +1058,89 @@
        }
 }
 
+/* Get the first available child of an editbone */
+static EditBone *editbone_get_child(EditBone *pabone, short use_visibility)
+{
+       Object *ob;
+       bArmature *arm;
+       EditBone *curbone, *chbone=NULL;
+       
+       if (!G.obedit) return NULL;
+       else ob= G.obedit;
+       arm= (bArmature *)ob->data;
+
+       for (curbone= G.edbo.first; curbone; curbone= curbone->next) {
+               if (curbone->parent == pabone) {
+                       if (use_visibility) {
+                               if ((arm->layer & curbone->layer) && 
!(pabone->flag & BONE_HIDDEN_A))
+                                       chbone = curbone;
+                       }
+                       else
+                               chbone = curbone;
+               }
+       }
+       
+       return chbone;
+}
+
+void armature_select_hierarchy(short direction, short add_to_sel)
+{
+       Object *ob;
+       bArmature *arm;
+       EditBone *curbone, *pabone, *chbone;
+
+       if (!G.obedit) return;
+       else ob= G.obedit;
+       arm= (bArmature *)ob->data;
+       
+       for (curbone= G.edbo.first; curbone; curbone= curbone->next) {
+               if (arm->layer & curbone->layer) {
+                       if (curbone->flag & (BONE_ACTIVE)) {
+                               if (direction == BONE_SELECT_PARENT) {
+                                       if (curbone->parent == NULL) continue;
+                                       else pabone = curbone->parent;
+                                       
+                                       if ((arm->layer & pabone->layer) && 
!(pabone->flag & BONE_HIDDEN_A)) {
+                                               pabone->flag |= 
(BONE_ACTIVE|BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
+                                               if (pabone->parent)     
pabone->parent->flag |= BONE_TIPSEL;
+                                               
+                                               if (!add_to_sel) curbone->flag 
&= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
+                                               curbone->flag &= ~BONE_ACTIVE;
+                                               break;
+                                       }
+                                       
+                               } else { // BONE_SELECT_CHILD
+                                       chbone = editbone_get_child(curbone, 1);
+                                       if (chbone == NULL) continue;
+                                       
+                                       if ((arm->layer & chbone->layer) && 
!(chbone->flag & BONE_HIDDEN_A)) {
+                                               chbone->flag |= 
(BONE_ACTIVE|BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
+                                               
+                                               if (!add_to_sel) {
+                                                       curbone->flag &= 
~(BONE_SELECTED|BONE_ROOTSEL);
+                                                       if (curbone->parent) 
curbone->parent->flag &= ~BONE_TIPSEL;
+                                               }
+                                               curbone->flag &= ~BONE_ACTIVE;
+                                               break;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       countall(); // flushes selection!
+       
+       allqueue (REDRAWVIEW3D, 0);
+       allqueue (REDRAWBUTSEDIT, 0);
+       allqueue (REDRAWBUTSOBJECT, 0);
+       allqueue (REDRAWOOPS, 0);
+       
+       if (direction==BONE_SELECT_PARENT)
+               BIF_undo_push("Select edit bone parent");
+       if (direction==BONE_SELECT_CHILD)
+               BIF_undo_push("Select edit bone child");
+}
+
 /* used by posemode and editmode */
 void setflag_armature (short mode)
 {

Modified: trunk/blender/source/blender/src/header_view3d.c
===================================================================
--- trunk/blender/source/blender/src/header_view3d.c    2008-08-04 08:39:10 UTC 
(rev 15943)
+++ trunk/blender/source/blender/src/header_view3d.c    2008-08-04 11:47:17 UTC 
(rev 15944)
@@ -1325,12 +1325,21 @@
                case 2: /* Select/Deselect all */
                        deselectall_armature(1, 1);
                        break;
-               case 3: /* Select Parent(s) */  
-                       select_bone_parent();
-                       break;
-               case 4: /* Swap Select All */
+               case 3: /* Swap Select All */
                        deselectall_armature(3, 1);
                        break;
+               case 4: /* Select parent */
+                       armature_select_hierarchy(BONE_SELECT_PARENT, 0);
+                       break;
+               case 5: /* Select child */
+                       armature_select_hierarchy(BONE_SELECT_CHILD, 0);
+                       break;
+               case 6: /* Extend Select parent */
+                       armature_select_hierarchy(BONE_SELECT_PARENT, 1);
+                       break;
+               case 7: /* Extend Select child */
+                       armature_select_hierarchy(BONE_SELECT_CHILD, 1);
+                       break;
        }
        allqueue(REDRAWVIEW3D, 0);
 }
@@ -1348,11 +1357,18 @@
        uiDefBut(block, SEPR, 0, "",                            0, yco-=6, 
menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
        
        uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select/Deselect All|A",  
                        0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Inverse|Ctrl I",         
        0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
        
-       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Swap Select All|Ctrl I", 
                0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
+       uiDefBut(block, SEPR, 0, "",                            0, yco-=6, 
menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
        
-       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select Parent(s)|P",     
                                0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 
3, "");
-
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select Parent|[",        
                                0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 
4, "");
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select Child|]",         
                        0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
+       
+       uiDefBut(block, SEPR, 0, "",                            0, yco-=6, 
menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+       
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Extend Select 
Parent|Shift [",                                   0, yco-=20, menuwidth, 19, 
NULL, 0.0, 0.0, 1, 6, "");
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Extend Select 
Child|Shift ]",                                    0, yco-=20, menuwidth, 19, 
NULL, 0.0, 0.0, 1, 7, "");
+       
        if(curarea->headertype==HEADERTOP) {
                uiBlockSetDirection(block, UI_DOWN);
        }
@@ -1379,12 +1395,21 @@
        case 3: /* Select Target(s) of Constraint(s) */
                pose_select_constraint_target();
                break;
-       case 4: /* Select Bone's Parent */
-               select_bone_parent();
-               break;
        case 5: /* Swap Select All */
                deselectall_posearmature(OBACT, 3, 1);
                break;
+       case 6: /* Select parent */
+               pose_select_hierarchy(BONE_SELECT_PARENT, 0);
+               break;
+       case 7: /* Select child */
+               pose_select_hierarchy(BONE_SELECT_CHILD, 0);
+               break;
+       case 8: /* Extend Select parent */
+               pose_select_hierarchy(BONE_SELECT_PARENT, 1);
+               break;
+       case 9: /* Extend Select child */
+               pose_select_hierarchy(BONE_SELECT_CHILD, 1);
+               break;
        }
        allqueue(REDRAWVIEW3D, 0);
 }
@@ -1404,8 +1429,17 @@
        uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select/Deselect All|A",  
                        0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
        uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Swap Select All|Ctrl I", 
                        0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
        uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select Constraint 
Target|W",                     0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, 
"");
-       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select Parent(s)|P",     
                                0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 
4, "");
-
+       
+       uiDefBut(block, SEPR, 0, "",                            0, yco-=6, 
menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+       
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select Parent|[",        
                                0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 
6, "");
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select Child|]",         
                        0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
+       

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to