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