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

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to