[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [15944] trunk/blender/source/blender: * Armature hierarchy selection tools

Matt Ebb matt at mke3.net
Mon Aug 4 13:47:17 CEST 2008


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. @@




More information about the Bf-blender-cvs mailing list