[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [23658] trunk/blender/source/blender: Bone Selections: Ability to set bones as unselectable

Joshua Leung aligorith at gmail.com
Tue Oct 6 13:33:58 CEST 2009


Revision: 23658
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=23658
Author:   aligorith
Date:     2009-10-06 13:33:58 +0200 (Tue, 06 Oct 2009)

Log Message:
-----------
Bone Selections: Ability to set bones as unselectable

In the Outliner, it is now possible to toggle per bone the selectability of the bone in the viewport, as for Objects using the restriction columns. This can also be set using the RNA-api.

I've tested all commonly used tools IMO, but there may still be a few which I've missed. Please report those cases.

PS. For some reason, the define was already there, but not connected up to anything. Can't remember why anymore, but here it is...

Modified Paths:
--------------
    trunk/blender/source/blender/editors/armature/editarmature.c
    trunk/blender/source/blender/editors/armature/poseobject.c
    trunk/blender/source/blender/editors/object/object_select.c
    trunk/blender/source/blender/editors/space_outliner/outliner.c
    trunk/blender/source/blender/makesrna/intern/rna_armature.c

Modified: trunk/blender/source/blender/editors/armature/editarmature.c
===================================================================
--- trunk/blender/source/blender/editors/armature/editarmature.c	2009-10-06 11:21:57 UTC (rev 23657)
+++ trunk/blender/source/blender/editors/armature/editarmature.c	2009-10-06 11:33:58 UTC (rev 23658)
@@ -110,17 +110,20 @@
 	EditBone *ebo;
 	
 	for (ebo=edbo->first; ebo; ebo= ebo->next) {
-		if ((ebo->flag & BONE_CONNECTED) && (ebo->parent)) {
-			if (ebo->parent->flag & BONE_TIPSEL)
-				ebo->flag |= BONE_ROOTSEL;
+		/* if bone is not selectable, we shouldn't alter this setting... */
+		if ((ebo->flag & BONE_UNSELECTABLE) == 0) {
+			if ((ebo->flag & BONE_CONNECTED) && (ebo->parent)) {
+				if (ebo->parent->flag & BONE_TIPSEL)
+					ebo->flag |= BONE_ROOTSEL;
+				else
+					ebo->flag &= ~BONE_ROOTSEL;
+			}
+			
+			if ((ebo->flag & BONE_TIPSEL) && (ebo->flag & BONE_ROOTSEL))
+				ebo->flag |= BONE_SELECTED;
 			else
-				ebo->flag &= ~BONE_ROOTSEL;
+				ebo->flag &= ~BONE_SELECTED;
 		}
-		
-		if ((ebo->flag & BONE_TIPSEL) && (ebo->flag & BONE_ROOTSEL))
-			ebo->flag |= BONE_SELECTED;
-		else
-			ebo->flag &= ~BONE_SELECTED;
 	}				
 }
 
@@ -1127,7 +1130,7 @@
 					/* no singular posemode, so check for correct object */
 					if(base->selcol == (hitresult & 0xFFFF)) {
 						bone = get_indexed_bone(base->object, hitresult);
-
+						
 						if (findunsel)
 							sel = (bone->flag & BONE_SELECTED);
 						else
@@ -1347,45 +1350,42 @@
 /* **************** Posemode stuff ********************** */
 
 
-static void selectconnected_posebonechildren (Object *ob, Bone *bone)
+static void selectconnected_posebonechildren (Object *ob, Bone *bone, int extend)
 {
 	Bone *curBone;
-	int shift= 0; // XXX
 	
-	if (!(bone->flag & BONE_CONNECTED))
+	/* stop when unconnected child is encontered, or when unselectable bone is encountered */
+	if (!(bone->flag & BONE_CONNECTED) || (bone->flag & BONE_UNSELECTABLE))
 		return;
 	
 		// XXX old cruft! use notifiers instead
 	//select_actionchannel_by_name (ob->action, bone->name, !(shift));
 	
-	if (shift)
+	if (extend)
 		bone->flag &= ~BONE_SELECTED;
 	else
 		bone->flag |= BONE_SELECTED;
 	
-	for (curBone=bone->childbase.first; curBone; curBone=curBone->next){
-		selectconnected_posebonechildren (ob, curBone);
-	}
+	for (curBone=bone->childbase.first; curBone; curBone=curBone->next)
+		selectconnected_posebonechildren(ob, curBone, extend);
 }
 
 /* within active object context */
 /* previously known as "selectconnected_posearmature" */
 static int pose_select_connected_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {  
+	ARegion *ar= CTX_wm_region(C);
+	Object *ob= CTX_data_edit_object(C);
 	Bone *bone, *curBone, *next= NULL;
-	int shift= 0; // XXX in pose mode, Shift+L is bound to another command
-				  // named "PoseLib Add Current Pose"
+	int extend= RNA_boolean_get(op->ptr, "extend");
 	int x, y;
-	ARegion *ar;
-	Object *ob= CTX_data_edit_object(C);
-	ar= CTX_wm_region(C);
-
+	
 	x= event->x - ar->winrct.xmin;
 	y= event->y - ar->winrct.ymin;
 
 	view3d_operator_needs_opengl(C);
 	
-	if (shift)
+	if (extend)
 		bone= get_nearest_bone(C, 0, x, y);
 	else
 		bone= get_nearest_bone(C, 1, x, y);
@@ -1395,26 +1395,29 @@
 	
 	/* Select parents */
 	for (curBone=bone; curBone; curBone=next){
-			// XXX old cruft! use notifiers instead
-		//select_actionchannel_by_name (ob->action, curBone->name, !(shift));
-		if (shift)
-			curBone->flag &= ~BONE_SELECTED;
+		/* ignore bone if cannot be selected */
+		if ((curBone->flag & BONE_UNSELECTABLE) == 0) { 
+				// XXX old cruft! use notifiers instead
+			//select_actionchannel_by_name (ob->action, curBone->name, !(shift));
+			
+			if (extend)
+				curBone->flag &= ~BONE_SELECTED;
+			else
+				curBone->flag |= BONE_SELECTED;
+			
+			if (curBone->flag & BONE_CONNECTED)
+				next=curBone->parent;
+			else
+				next=NULL;
+		}
 		else
-			curBone->flag |= BONE_SELECTED;
-		
-		if (curBone->flag & BONE_CONNECTED)
-			next=curBone->parent;
-		else
-			next=NULL;
+			next= NULL;
 	}
 	
 	/* Select children */
-	for (curBone=bone->childbase.first; curBone; curBone=next){
-		selectconnected_posebonechildren (ob, curBone);
-	}
+	for (curBone=bone->childbase.first; curBone; curBone=next)
+		selectconnected_posebonechildren(ob, curBone, extend);
 	
-	// XXX this only counted the number of pose channels selected
-	//countall(); // flushes selection!
 	WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, ob);
 
 	return OPERATOR_FINISHED;
@@ -1435,6 +1438,7 @@
 	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 	
 	/* props */	
+	RNA_def_boolean(ot->srna, "extend", FALSE, "Extend", "Extend selection instead of deselecting everything first.");
 }
 
 /* **************** END Posemode stuff ********************** */
@@ -1446,7 +1450,7 @@
 {
 	bArmature *arm;
 	EditBone *bone, *curBone, *next;
-	int shift= 0; // XXX
+	int extend= RNA_boolean_get(op->ptr, "extend");
 	int x, y;
 	ARegion *ar;
 	Object *obedit= CTX_data_edit_object(C);
@@ -1458,7 +1462,7 @@
 
 	view3d_operator_needs_opengl(C);
 
-	if (shift)
+	if (extend)
 		bone= get_nearest_bone(C, 0, x, y);
 	else
 		bone= get_nearest_bone(C, 1, x, y);
@@ -1467,14 +1471,16 @@
 		return OPERATOR_CANCELLED;
 
 	/* Select parents */
-	for (curBone=bone; curBone; curBone=next){
-		if (shift){
-			curBone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
+	for (curBone=bone; curBone; curBone=next) {
+		if ((curBone->flag & BONE_UNSELECTABLE) == 0) {
+			if (extend) {
+				curBone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
+			}
+			else{
+				curBone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
+			}
 		}
-		else{
-			curBone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
-		}
-
+		
 		if (curBone->flag & BONE_CONNECTED)
 			next=curBone->parent;
 		else
@@ -1482,19 +1488,19 @@
 	}
 
 	/* Select children */
-	while (bone){
-		for (curBone=arm->edbo->first; curBone; curBone=next){
+	while (bone) {
+		for (curBone=arm->edbo->first; curBone; curBone=next) {
 			next = curBone->next;
-			if (curBone->parent == bone){
-				if (curBone->flag & BONE_CONNECTED){
-					if (shift)
+			if ((curBone->parent == bone) && (curBone->flag & BONE_UNSELECTABLE)==0) {
+				if (curBone->flag & BONE_CONNECTED) {
+					if (extend)
 						curBone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
 					else
 						curBone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
 					bone=curBone;
 					break;
 				}
-				else{ 
+				else { 
 					bone=NULL;
 					break;
 				}
@@ -1502,15 +1508,12 @@
 		}
 		if (!curBone)
 			bone=NULL;
-
 	}
-
+	
 	ED_armature_sync_selection(arm->edbo);
-
-	/* BIF_undo_push("Select connected"); */
-
+	
 	WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, obedit);
-
+	
 	return OPERATOR_FINISHED;
 }
 
@@ -1527,6 +1530,9 @@
 	
 	/* flags */
 	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+	
+	/* properties s*/
+	RNA_def_boolean(ot->srna, "extend", FALSE, "Extend", "Extend selection instead of deselecting everything first.");
 }
 
 /* does bones and points */
@@ -3966,9 +3972,12 @@
 {
 	/*	Set the flags */
 	CTX_DATA_BEGIN(C, EditBone *, ebone, visible_bones) {
-		/* select bone */
-		ebone->flag ^= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
-		ebone->flag &= ~BONE_ACTIVE;
+		/* ignore bone if selection can't change */
+		if ((ebone->flag & BONE_UNSELECTABLE) == 0) {
+			/* select bone */
+			ebone->flag ^= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
+			ebone->flag &= ~BONE_ACTIVE;
+		}
 	}
 	CTX_DATA_END;	
 
@@ -3979,7 +3988,6 @@
 
 void ARMATURE_OT_select_inverse(wmOperatorType *ot)
 {
-	
 	/* identifiers */
 	ot->name= "Select Inverse";
 	ot->idname= "ARMATURE_OT_select_inverse";
@@ -4002,16 +4010,19 @@
 	
 	/*	Set the flags */
 	CTX_DATA_BEGIN(C, EditBone *, ebone, visible_bones) {
-		if (sel==1) {
-			/* select bone */
-			ebone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
-			if(ebone->parent)
-				ebone->parent->flag |= (BONE_TIPSEL);
+		/* ignore bone if selection can't change */
+		if ((ebone->flag & BONE_UNSELECTABLE) == 0) {
+			if (sel==1) {
+				/* select bone */
+				ebone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
+				if(ebone->parent)
+					ebone->parent->flag |= (BONE_TIPSEL);
+			}
+			else {
+				/* deselect bone */
+				ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL | BONE_ACTIVE);
+			}
 		}
-		else {
-			/* deselect bone */
-			ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL | BONE_ACTIVE);
-		}
 	}
 	CTX_DATA_END;	
 
@@ -4051,7 +4062,8 @@
 	arm= (bArmature *)ob->data;
 	
 	for (curbone= arm->edbo->first; curbone; curbone= curbone->next) {
-		if (EBONE_VISIBLE(arm, curbone)) {
+		/* only work on bone if it is visible and its selection can change */
+		if (EBONE_VISIBLE(arm, curbone) && (curbone->flag & BONE_UNSELECTABLE)==0) {
 			if (curbone->flag & (BONE_ACTIVE)) {
 				if (direction == BONE_SELECT_PARENT) {
 					if (curbone->parent == NULL) continue;
@@ -4071,7 +4083,7 @@
 					chbone = editbone_get_child(arm, curbone, 1);
 					if (chbone == NULL) continue;
 					
-					if (EBONE_VISIBLE(arm, chbone)) {
+					if (EBONE_VISIBLE(arm, chbone) && (chbone->flag & BONE_UNSELECTABLE)==0) {
 						chbone->flag |= (BONE_ACTIVE|BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
 						
 						if (!add_to_sel) {
@@ -4301,8 +4313,9 @@
 	if (!ob || !ob->pose) return 0;
 
 	nearBone= get_bone_from_selectbuffer(scene, base, buffer, hits, 1);
-
-	if (nearBone) {
+	
+	/* if the bone cannot be affected, don't do anything */
+	if ((nearBone) && !(nearBone->flag & BONE_UNSELECTABLE)) {
 		bArmature *arm= ob->data;
 		
 		/* since we do unified select, we don't shift+select a bone if the armature object was not active yet */
@@ -4381,7 +4394,8 @@
 	
 	/*	Set the flags accordingly	*/
 	for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
-		if ((pchan->bone->layer & arm->layer) && !(pchan->bone->flag & BONE_HIDDEN_P)) {
+		/* ignore the pchan if it isn't visible or if its selection cannot be changed */
+		if ((pchan->bone->layer & arm->layer) && !(pchan->bone->flag & (BONE_HIDDEN_P|BONE_UNSELECTABLE))) {
 			if (test==3) {
 				pchan->bone->flag ^= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
 				pchan->bone->flag &= ~BONE_ACTIVE;
@@ -4960,8 +4974,10 @@
 	
 	/*	Set the flags */
 	CTX_DATA_BEGIN(C, bPoseChannel *, pchan, visible_pchans) {
-		pchan->bone->flag ^= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
-		pchan->bone->flag &= ~BONE_ACTIVE;
+		if ((pchan->bone->flag & BONE_UNSELECTABLE) == 0) {
+			pchan->bone->flag ^= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list