[Bf-blender-cvs] [881e05f] master: Armature select-hierarchy now uses connected bones

Campbell Barton noreply at git.blender.org
Thu Mar 19 15:41:14 CET 2015


Commit: 881e05fc54058bc04b217817808315b2f9691c2a
Author: Campbell Barton
Date:   Fri Mar 20 01:37:29 2015 +1100
Branches: master
https://developer.blender.org/rB881e05fc54058bc04b217817808315b2f9691c2a

Armature select-hierarchy now uses connected bones

Traverse down connected child bones (when available)

Also remove redundant bone loops.

===================================================================

M	source/blender/editors/armature/armature_select.c
M	source/blender/editors/armature/pose_select.c

===================================================================

diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c
index 581dd00..5061ba9 100644
--- a/source/blender/editors/armature/armature_select.c
+++ b/source/blender/editors/armature/armature_select.c
@@ -962,75 +962,78 @@ void ARMATURE_OT_select_similar(wmOperatorType *ot)
 
 /* ********************* select hierarchy operator ************** */
 
-/* Get the first available child of an editbone */
-static EditBone *editbone_get_child(bArmature *arm, EditBone *pabone, short use_visibility)
-{
-	EditBone *curbone, *chbone = NULL;
-	
-	for (curbone = arm->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;
-}
-
 static int armature_select_hierarchy_exec(bContext *C, wmOperator *op)
 {
 	Object *obedit = CTX_data_edit_object(C);
 	Object *ob;
 	bArmature *arm;
-	EditBone *curbone, *pabone, *chbone;
+	EditBone *ebone_active;
 	int direction = RNA_enum_get(op->ptr, "direction");
 	const bool add_to_sel = RNA_boolean_get(op->ptr, "extend");
+	bool changed = false;
 	
 	ob = obedit;
 	arm = (bArmature *)ob->data;
-	
-	for (curbone = arm->edbo->first; curbone; curbone = curbone->next) {
-		/* only work on bone if it is visible and its selection can change */
-		if (EBONE_SELECTABLE(arm, curbone)) {
-			if (curbone == arm->act_edbone) {
-				if (direction == BONE_SELECT_PARENT) {
-					if (curbone->parent == NULL) continue;
-					else pabone = curbone->parent;
-					
-					if (EBONE_VISIBLE(arm, pabone)) {
-						pabone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
-						arm->act_edbone = pabone;
-						if (pabone->parent) pabone->parent->flag |= BONE_TIPSEL;
-						
-						if (!add_to_sel) curbone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
-						break;
-					}
-					
+
+	 ebone_active = arm->act_edbone;
+	if (ebone_active == NULL) {
+		return OPERATOR_CANCELLED;
+	}
+
+	if (direction == BONE_SELECT_PARENT) {
+		if (ebone_active->parent) {
+			EditBone *ebone_parent;
+
+			ebone_parent = ebone_active->parent;
+
+			if (EBONE_SELECTABLE(arm, ebone_parent)) {
+				arm->act_edbone = ebone_parent;
+
+				if (!add_to_sel) {
+					ED_armature_ebone_select_set(ebone_active, false);
 				}
-				else { // BONE_SELECT_CHILD
-					chbone = editbone_get_child(arm, curbone, 1);
-					if (chbone == NULL) continue;
-					
-					if (EBONE_SELECTABLE(arm, chbone)) {
-						chbone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
-						arm->act_edbone = chbone;
-						
-						if (!add_to_sel) {
-							curbone->flag &= ~(BONE_SELECTED | BONE_ROOTSEL);
-							if (curbone->parent) curbone->parent->flag &= ~BONE_TIPSEL;
+				ED_armature_ebone_select_set(ebone_parent, true);
+
+				changed = true;
+			}
+		}
+
+	}
+	else {  /* BONE_SELECT_CHILD */
+		EditBone *ebone_iter, *ebone_child = NULL;
+		int pass;
+
+		/* first pass, only connected bones (the logical direct child) */
+		for (pass = 0; pass < 2 && (ebone_child == NULL); pass++) {
+			for (ebone_iter = arm->edbo->first; ebone_iter; ebone_iter = ebone_iter->next) {
+				/* possible we have multiple children, some invisible */
+				if (EBONE_SELECTABLE(arm, ebone_iter)) {
+					if (ebone_iter->parent == ebone_active) {
+						if ((pass == 1) || (ebone_iter->flag & BONE_CONNECTED)) {
+							ebone_child = ebone_iter;
+							break;
 						}
-						break;
 					}
 				}
 			}
 		}
+
+		if (ebone_child) {
+			arm->act_edbone = ebone_child;
+
+			if (!add_to_sel) {
+				ED_armature_ebone_select_set(ebone_active, false);
+			}
+			ED_armature_ebone_select_set(ebone_child, true);
+
+			changed = true;
+		}
 	}
 	
+	if (changed == false) {
+		return OPERATOR_CANCELLED;
+	}
+
 	ED_armature_sync_selection(arm->edbo);
 	
 	WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c
index 5d5a9bf..a4a21a0 100644
--- a/source/blender/editors/armature/pose_select.c
+++ b/source/blender/editors/armature/pose_select.c
@@ -518,71 +518,67 @@ static int pose_select_hierarchy_exec(bContext *C, wmOperator *op)
 {
 	Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
 	bArmature *arm = ob->data;
-	Bone *curbone, *pabone, *chbone;
+	bPoseChannel *pchan_act;
 	int direction = RNA_enum_get(op->ptr, "direction");
 	const bool add_to_sel = RNA_boolean_get(op->ptr, "extend");
-	bool found = false;
+	bool changed = false;
 	
-	CTX_DATA_BEGIN (C, bPoseChannel *, pchan, visible_pose_bones)
-	{
-		curbone = pchan->bone;
-		
-		if ((curbone->flag & BONE_UNSELECTABLE) == 0) {
-			if (curbone == arm->act_bone) {
-				if (direction == BONE_SELECT_PARENT) {
-					if (pchan->parent == NULL) continue;
-					else pabone = pchan->parent->bone;
-					
-					if (PBONE_SELECTABLE(arm, pabone)) {
-						if (!add_to_sel) curbone->flag &= ~BONE_SELECTED;
-						pabone->flag |= BONE_SELECTED;
-						arm->act_bone = pabone;
-						
-						found = 1;
-						break;
-					}
+	pchan_act = BKE_pose_channel_active(ob);
+	if (pchan_act == NULL) {
+		return OPERATOR_CANCELLED;
+	}
+
+	if (direction == BONE_SELECT_PARENT) {
+		if (pchan_act->parent) {
+			Bone *bone_parent;
+			bone_parent = pchan_act->parent->bone;
+
+			if (PBONE_SELECTABLE(arm, bone_parent)) {
+				if (!add_to_sel) {
+					pchan_act->bone->flag &= ~BONE_SELECTED;
 				}
-				else { /* direction == BONE_SELECT_CHILD */
-					/* the child member is only assigned to connected bones, see [#30340] */
-#if 0
-					if (pchan->child == NULL) continue;
-					else chbone = pchan->child->bone;
-#else
-					/* instead. find _any_ visible child bone, using the first one is a little arbitrary  - campbell */
-					chbone = pchan->child ? pchan->child->bone : NULL;
-					if (chbone == NULL) {
-						bPoseChannel *pchan_child;
-
-						for (pchan_child = ob->pose->chanbase.first; pchan_child; pchan_child = pchan_child->next) {
-							/* possible we have multiple children, some invisible */
-							if (PBONE_SELECTABLE(arm, pchan_child->bone)) {
-								if (pchan_child->parent == pchan) {
-									chbone = pchan_child->bone;
-									break;
-								}
-							}
-						}
-					}
+				bone_parent->flag |= BONE_SELECTED;
+				arm->act_bone = bone_parent;
 
-					if (chbone == NULL) continue;
-#endif
-					
-					if (PBONE_SELECTABLE(arm, chbone)) {
-						if (!add_to_sel) curbone->flag &= ~BONE_SELECTED;
-						chbone->flag |= BONE_SELECTED;
-						arm->act_bone = chbone;
-						
-						found = 1;
-						break;
+				changed = true;
+			}
+		}
+	}
+	else { /* direction == BONE_SELECT_CHILD */
+		bPoseChannel *pchan_iter;
+		Bone *bone_child = NULL;
+		int pass;
+
+		/* first pass, only connected bones (the logical direct child) */
+		for (pass = 0; pass < 2 && (bone_child == NULL); pass++) {
+			for (pchan_iter = ob->pose->chanbase.first; pchan_iter; pchan_iter = pchan_iter->next) {
+				/* possible we have multiple children, some invisible */
+				if (PBONE_SELECTABLE(arm, pchan_iter->bone)) {
+					if (pchan_iter->parent == pchan_act) {
+						if ((pass == 1) || (pchan_iter->bone->flag & BONE_CONNECTED)) {
+							bone_child = pchan_iter->bone;
+							break;
+						}
 					}
 				}
 			}
 		}
+
+		if (bone_child) {
+			arm->act_bone = bone_child;
+
+			if (!add_to_sel) {
+				pchan_act->bone->flag &= ~BONE_SELECTED;
+			}
+			bone_child->flag |= BONE_SELECTED;
+
+			changed = true;
+		}
 	}
-	CTX_DATA_END;
 
-	if (found == 0)
+	if (changed == false) {
 		return OPERATOR_CANCELLED;
+	}
 	
 	/* updates */
 	WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);




More information about the Bf-blender-cvs mailing list