use armature active bone as a pointer rather then a flag for each bone that needs...
authorCampbell Barton <ideasman42@gmail.com>
Mon, 9 Nov 2009 21:03:54 +0000 (21:03 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Mon, 9 Nov 2009 21:03:54 +0000 (21:03 +0000)
- rna vars arm.bones.active & rna.edit_bones.active
- needed special undo support.
- readfile.c loads.
- duplicate and copy_armature support.
- keep the draw flag, renamed to BONE_DRAW_ACTIVE, only use for openGL drawing.

Note: it may be better to allow active/unselected as with objects.

23 files changed:
source/blender/blenkernel/intern/action.c
source/blender/blenkernel/intern/armature.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/editors/armature/armature_intern.h
source/blender/editors/armature/editarmature.c
source/blender/editors/armature/editarmature_retarget.c
source/blender/editors/armature/poselib.c
source/blender/editors/armature/poseobject.c
source/blender/editors/include/ED_armature.h
source/blender/editors/screen/screen_context.c
source/blender/editors/sculpt_paint/paint_vertex.c
source/blender/editors/space_buttons/buttons_context.c
source/blender/editors/space_outliner/outliner.c
source/blender/editors/space_view3d/drawarmature.c
source/blender/editors/space_view3d/view3d_buttons.c
source/blender/editors/space_view3d/view3d_draw.c
source/blender/editors/space_view3d/view3d_select.c
source/blender/editors/transform/transform_manipulator.c
source/blender/makesdna/DNA_armature_types.h
source/blender/makesrna/intern/rna_armature.c
source/gameengine/Converter/BL_ArmatureChannel.cpp
source/gameengine/Converter/BL_BlenderDataConversion.cpp

index 2dec76d1b6b86bf358e3f3826fe2c0022136588f..2505a3a70ac45008fada90008648a2acd04f2032 100644 (file)
@@ -471,7 +471,7 @@ bPoseChannel *get_active_posechannel (Object *ob)
        
        /* find active */
        for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
-               if ((pchan->bone) && (pchan->bone->flag & BONE_ACTIVE) && (pchan->bone->layer & arm->layer))
+               if ((pchan->bone) && (pchan->bone == arm->act_bone) && (pchan->bone->layer & arm->layer))
                        return pchan;
        }
        
index f178553d796c20372e6b11bce063a88a74985c6f..b0153a1fca37a8de5ac8926cce570c2d76e66ce6 100644 (file)
@@ -169,10 +169,13 @@ void make_local_armature(bArmature *arm)
        }
 }
 
-static void    copy_bonechildren (Bone* newBone, Bone* oldBone)
+static void    copy_bonechildren (Bone* newBone, Bone* oldBone, Bone* actBone, Bone **newActBone)
 {
        Bone    *curBone, *newChildBone;
        
+       if(oldBone == actBone)
+               *newActBone= newBone;
+
        /*      Copy this bone's list*/
        BLI_duplicatelist(&newBone->childbase, &oldBone->childbase);
        
@@ -180,7 +183,7 @@ static void copy_bonechildren (Bone* newBone, Bone* oldBone)
        newChildBone=newBone->childbase.first;
        for (curBone=oldBone->childbase.first;curBone;curBone=curBone->next){
                newChildBone->parent=newBone;
-               copy_bonechildren(newChildBone,curBone);
+               copy_bonechildren(newChildBone, curBone, actBone, newActBone);
                newChildBone=newChildBone->next;
        }
 }
@@ -189,6 +192,7 @@ bArmature *copy_armature(bArmature *arm)
 {
        bArmature *newArm;
        Bone            *oldBone, *newBone;
+       Bone            *newActBone= NULL;
        
        newArm= copy_libblock (arm);
        BLI_duplicatelist(&newArm->bonebase, &arm->bonebase);
@@ -197,10 +201,11 @@ bArmature *copy_armature(bArmature *arm)
        newBone=newArm->bonebase.first;
        for (oldBone=arm->bonebase.first;oldBone;oldBone=oldBone->next){
                newBone->parent=NULL;
-               copy_bonechildren (newBone, oldBone);
+               copy_bonechildren (newBone, oldBone, arm->act_bone, &newActBone);
                newBone=newBone->next;
        };
        
+       newArm->act_bone= newActBone;
        return newArm;
 }
 
index 00f7cbd9eebfbe99c99e4b345b294ed6f49aed10..e1a13b65efa02918a6da9e378855a3b04b353953 100644 (file)
@@ -2333,7 +2333,7 @@ static void lib_link_pose(FileData *fd, Object *ob, bPose *pose)
                        rebuild= 1;
                else if(ob->id.lib==NULL && arm->id.lib) {
                        /* local pose selection copied to armature, bit hackish */
-                       pchan->bone->flag &= ~(BONE_SELECTED|BONE_ACTIVE);
+                       pchan->bone->flag &= ~BONE_SELECTED;
                        pchan->bone->flag |= pchan->selectflag;
                }
        }
@@ -2388,6 +2388,9 @@ static void direct_link_armature(FileData *fd, bArmature *arm)
                direct_link_bones(fd, bone);
                bone=bone->next;
        }
+
+       arm->act_bone= newdataadr(fd, arm->act_bone);
+       arm->act_edbone= NULL;
 }
 
 /* ************ READ CAMERA ***************** */
index 8ec12496e5928fcf3c413068de961bb6a8dc64de..b2147221f9fd11a23527d059c7e059db0d6d2c08 100644 (file)
@@ -1114,7 +1114,7 @@ static void write_pose(WriteData *wd, bPose *pose)
                
                /* prevent crashes with autosave, when a bone duplicated in editmode has not yet been assigned to its posechannel */
                if (chan->bone) 
-                       chan->selectflag= chan->bone->flag & (BONE_SELECTED|BONE_ACTIVE); /* gets restored on read, for library armatures */
+                       chan->selectflag= chan->bone->flag & BONE_SELECTED; /* gets restored on read, for library armatures */
                
                writestruct(wd, DATA, "bPoseChannel", 1, chan);
        }
index d31a3bda3323d22c7c2fd822167658019560a066..012610bfd252d9ecb0145e24892e31d6fcf8c98a 100644 (file)
@@ -136,7 +136,7 @@ struct bArmature;
 struct EditBone;
 struct ListBase;
 
-void make_boneList(struct ListBase *edbo, struct ListBase *bones, struct EditBone *parent);
+EditBone *make_boneList(struct ListBase *edbo, struct ListBase *bones, struct EditBone *parent, struct Bone *actBone);
 struct EditBone *addEditBone(struct bArmature *arm, char *name);
 void BIF_sk_selectStroke(struct bContext *C, short mval[2], short extend);
 
index c5b01f1cab058beb5797c8f0f969a9dc91c390c6..6dad0b6e90f165d54341fd369bda830deab9cc22 100644 (file)
@@ -129,10 +129,30 @@ void ED_armature_sync_selection(ListBase *edbo)
        }                               
 }
 
+void ED_armature_validate_active(struct bArmature *arm)
+{
+       EditBone *ebone= arm->act_edbone;
+
+       if(ebone) { 
+               if(ebone->flag & BONE_HIDDEN_A || (ebone->flag & BONE_SELECTED)==0)
+                       arm->act_edbone= NULL;
+       }
+}
+
+void free_edit_bone(bArmature *arm, EditBone *bone)
+{
+       if(arm->act_edbone==bone)
+               arm->act_edbone= NULL;
+
+       BLI_freelinkN(arm->edbo, bone);
+}
+
 /* converts Bones to EditBone list, used for tools as well */
-void make_boneList(ListBase *edbo, ListBase *bones, EditBone *parent)
+EditBone *make_boneList(ListBase *edbo, ListBase *bones, EditBone *parent, Bone *actBone)
 {
        EditBone        *eBone;
+       EditBone        *eBoneAct= NULL;
+       EditBone        *eBoneTest= NULL;
        Bone            *curBone;
        float delta[3];
        float premat[3][3];
@@ -194,9 +214,17 @@ void make_boneList(ListBase *edbo, ListBase *bones, EditBone *parent)
                BLI_addtail(edbo, eBone);
                
                /*      Add children if necessary */
-               if (curBone->childbase.first) 
-                       make_boneList(edbo, &curBone->childbase, eBone);
+               if (curBone->childbase.first) {
+                       eBoneTest= make_boneList(edbo, &curBone->childbase, eBone, actBone);
+                       if(eBoneTest)
+                               eBoneAct= eBoneTest;
+               }
+
+               if(curBone==actBone)
+                       eBoneAct= eBone;
        }
+
+       return eBoneAct;
 }
 
 /* nasty stuff for converting roll in editbones into bones */
@@ -270,7 +298,7 @@ void ED_armature_from_edit(Object *obedit)
                                        fBone->parent= eBone->parent;
                        }
                        printf("Warning: removed zero sized bone: %s\n", eBone->name);
-                       BLI_freelinkN(arm->edbo, eBone);
+                       free_edit_bone(arm, eBone);
                }
        }
        
@@ -283,8 +311,12 @@ void ED_armature_from_edit(Object *obedit)
                memcpy(newBone->head, eBone->head, sizeof(float)*3);
                memcpy(newBone->tail, eBone->tail, sizeof(float)*3);
                newBone->flag= eBone->flag;
-               if (eBone->flag & BONE_ACTIVE) 
+
+               if (eBone == arm->act_edbone) {
                        newBone->flag |= BONE_SELECTED; /* important, editbones can be active with only 1 point selected */
+                       arm->act_edbone= NULL;
+                       arm->act_bone= newBone;
+               }
                newBone->roll = 0.0f;
                
                newBone->weight = eBone->weight;
@@ -997,7 +1029,7 @@ static void separate_armature_bones (Scene *scene, Object *ob, short sel)
                        free_constraints(&pchan->constraints);
                        
                        /* get rid of unneeded bone */
-                       BLI_freelinkN(arm->edbo, curbone);
+                       free_edit_bone(arm, curbone);
                        BLI_freelinkN(&ob->pose->chanbase, pchan);
                }
        }
@@ -1633,19 +1665,20 @@ static EditBone *get_nearest_editbonepoint (ViewContext *vc, short mval[2], List
        return NULL;
 }
 
-static void delete_bone(ListBase *edbo, EditBone* exBone)
+/* warning, wont clear the active bone */
+static void delete_bone(bArmature *arm, EditBone* exBone)
 {
        EditBone *curBone;
        
        /* Find any bones that refer to this bone */
-       for (curBone=edbo->first;curBone;curBone=curBone->next) {
+       for (curBone=arm->edbo->first; curBone; curBone=curBone->next) {
                if (curBone->parent==exBone) {
                        curBone->parent=exBone->parent;
                        curBone->flag &= ~BONE_CONNECTED;
                }
        }
-       
-       BLI_freelinkN(edbo, exBone);
+
+       free_edit_bone(arm, exBone);
 }
 
 /* context: editmode armature */
@@ -1742,8 +1775,10 @@ static int armature_delete_selected_exec(bContext *C, wmOperator *op)
        for (curBone=arm->edbo->first;curBone;curBone=next) {
                next=curBone->next;
                if (arm->layer & curBone->layer) {
-                       if (curBone->flag & BONE_SELECTED)
-                               delete_bone(arm->edbo, curBone);
+                       if (curBone->flag & BONE_SELECTED) {
+                               if(curBone==arm->act_edbone) arm->act_edbone= NULL;
+                               delete_bone(arm, curBone);
+                       }
                }
        }
        
@@ -1795,30 +1830,33 @@ void ED_armature_deselectall(Object *obedit, int toggle, int doundo)
        }
        else sel= toggle;
        
-       /*      Set the flags */
-       for (eBone=arm->edbo->first;eBone;eBone=eBone->next) {
-               if (sel==3) {
-                       /* invert selection of bone */
-                       if ((arm->layer & eBone->layer) && (eBone->flag & BONE_HIDDEN_A)==0) {
-                               eBone->flag ^= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
-                               eBone->flag &= ~BONE_ACTIVE;
+       if(sel==2) {
+               arm->act_edbone= NULL;
+       } else {
+               /*      Set the flags */
+               for (eBone=arm->edbo->first;eBone;eBone=eBone->next) {
+                       if (sel==3) {
+                               /* invert selection of bone */
+                               if ((arm->layer & eBone->layer) && (eBone->flag & BONE_HIDDEN_A)==0) {
+                                       eBone->flag ^= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
+                                       if(arm->act_edbone==eBone)
+                                               arm->act_edbone= NULL;
+                               }
                        }
-               }
-               else if (sel==1) {
-                       /* select bone */
-                       if(arm->layer & eBone->layer && (eBone->flag & BONE_HIDDEN_A)==0) {
-                               eBone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
-                               if(eBone->parent)
-                                       eBone->parent->flag |= (BONE_TIPSEL);
+                       else if (sel==1) {
+                               /* select bone */
+                               if(arm->layer & eBone->layer && (eBone->flag & BONE_HIDDEN_A)==0) {
+                                       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);
+                               if(arm->act_edbone==eBone)
+                                       arm->act_edbone= NULL;
                        }
-               }
-               else if (sel==2) {
-                       /* clear active flag */
-                       eBone->flag &= ~(BONE_ACTIVE);
-               }
-               else {
-                       /* deselect bone */
-                       eBone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL | BONE_ACTIVE);
                }
        }
        
@@ -1836,7 +1874,7 @@ void mouse_armature(bContext *C, short mval[2], int extend)
        Object *obedit= CTX_data_edit_object(C);
        bArmature *arm= obedit->data;
        ViewContext vc;
-       EditBone *nearBone = NULL, *ebone;
+       EditBone *nearBone = NULL;
        int     selmask;
 
        view3d_set_viewcontext(C, &vc);
@@ -1898,8 +1936,7 @@ void mouse_armature(bContext *C, short mval[2], int extend)
                
                if(nearBone) {
                        /* then now check for active status */
-                       for (ebone=arm->edbo->first;ebone;ebone=ebone->next) ebone->flag &= ~BONE_ACTIVE;
-                       if(nearBone->flag & BONE_SELECTED) nearBone->flag |= BONE_ACTIVE;
+                       if(nearBone->flag & BONE_SELECTED) arm->act_edbone= nearBone;
                }
                
                WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, vc.obedit);
@@ -1945,7 +1982,8 @@ void ED_armature_to_edit(Object *ob)
        
        ED_armature_edit_free(ob);
        arm->edbo= MEM_callocN(sizeof(ListBase), "edbo armature");
-       make_boneList(arm->edbo, &arm->bonebase,NULL);
+       arm->act_edbone= make_boneList(arm->edbo, &arm->bonebase, NULL, arm->act_bone);
+       arm->act_bone= NULL;
 
 //     BIF_freeTemplates(); /* force template update when entering editmode */
 }
@@ -2103,68 +2141,84 @@ void ARMATURE_OT_calculate_roll(wmOperatorType *ot)
 
 /* **************** undo for armatures ************** */
 
-static void undoBones_to_editBones(void *lbuv, void *lbev)
+typedef struct UndoArmature {
+       EditBone *act_edbone;
+       ListBase lb;
+} UndoArmature;
+
+static void undoBones_to_editBones(void *uarmv, void *armv)
 {
-       ListBase *lbu= lbuv;
-       ListBase *edbo= lbev;
+       UndoArmature *uarm= uarmv;
+       bArmature *arm= armv;
        EditBone *ebo, *newebo;
        
-       BLI_freelistN(edbo);
+       BLI_freelistN(arm->edbo);
        
        /* copy  */
-       for(ebo= lbu->first; ebo; ebo= ebo->next) {
+       for(ebo= uarm->lb.first; ebo; ebo= ebo->next) {
                newebo= MEM_dupallocN(ebo);
                ebo->temp= newebo;
-               BLI_addtail(edbo, newebo);
+               BLI_addtail(arm->edbo, newebo);
        }
        
+       /* active bone */
+       if(uarm->act_edbone) {
+               ebo= uarm->act_edbone;
+               arm->act_edbone= ebo->temp;
+       }
+
        /* set pointers */
-       for(newebo= edbo->first; newebo; newebo= newebo->next) {
+       for(newebo= arm->edbo->first; newebo; newebo= newebo->next) {
                if(newebo->parent) newebo->parent= newebo->parent->temp;
        }
        /* be sure they dont hang ever */
-       for(newebo= edbo->first; newebo; newebo= newebo->next) {
+       for(newebo= arm->edbo->first; newebo; newebo= newebo->next) {
                newebo->temp= NULL;
        }
 }
 
-static void *editBones_to_undoBones(void *lbev)
+static void *editBones_to_undoBones(void *armv)
 {
-       ListBase *edbo= lbev;
-       ListBase *lb;
+       bArmature *arm= armv;
+       UndoArmature *uarm;
        EditBone *ebo, *newebo;
        
-       lb= MEM_callocN(sizeof(ListBase), "listbase undo");
+       uarm= MEM_callocN(sizeof(UndoArmature), "listbase undo");
        
        /* copy */
-       for(ebo= edbo->first; ebo; ebo= ebo->next) {
+       for(ebo= arm->edbo->first; ebo; ebo= ebo->next) {
                newebo= MEM_dupallocN(ebo);
                ebo->temp= newebo;
-               BLI_addtail(lb, newebo);
+               BLI_addtail(&uarm->lb, newebo);
        }
        
+       /* active bone */
+       if(arm->act_edbone) {
+               ebo= arm->act_edbone;
+               uarm->act_edbone= ebo->temp;
+       }
+
        /* set pointers */
-       for(newebo= lb->first; newebo; newebo= newebo->next) {
+       for(newebo= uarm->lb.first; newebo; newebo= newebo->next) {
                if(newebo->parent) newebo->parent= newebo->parent->temp;
        }
        
-       return lb;
+       return uarm;
 }
 
-static void free_undoBones(void *lbv)
+static void free_undoBones(void *uarmv)
 {
-       ListBase *lb= lbv;
+       UndoArmature *uarm= uarmv;
        
-       BLI_freelistN(lb);
-       MEM_freeN(lb);
+       BLI_freelistN(&uarm->lb);
+       MEM_freeN(uarm);
 }
 
 static void *get_armature_edit(bContext *C)
 {
        Object *obedit= CTX_data_edit_object(C);
        if(obedit && obedit->type==OB_ARMATURE) {
-               bArmature *arm= obedit->data;
-               return arm->edbo;
+               return obedit->data;
        }
        return NULL;
 }
@@ -2270,7 +2324,7 @@ static int armature_click_extrude_exec(bContext *C, wmOperator *op)
        /* find the active or selected bone */
        for (ebone = arm->edbo->first; ebone; ebone=ebone->next) {
                if (EBONE_VISIBLE(arm, ebone)) {
-                       if (ebone->flag & (BONE_ACTIVE|BONE_TIPSEL)) 
+                       if (ebone->flag & BONE_TIPSEL || arm->act_edbone == ebone)
                                break;
                }
        }
@@ -2278,7 +2332,7 @@ static int armature_click_extrude_exec(bContext *C, wmOperator *op)
        if (ebone==NULL) {
                for (ebone = arm->edbo->first; ebone; ebone=ebone->next) {
                        if (EBONE_VISIBLE(arm, ebone)) {
-                               if (ebone->flag & (BONE_ACTIVE|BONE_ROOTSEL)) 
+                               if (ebone->flag & BONE_ROOTSEL || arm->act_edbone == ebone)
                                        break;
                        }
                }
@@ -2305,7 +2359,7 @@ static int armature_click_extrude_exec(bContext *C, wmOperator *op)
                }
                
                newbone= add_editbone(obedit, ebone->name);
-               newbone->flag |= BONE_ACTIVE;
+               arm->act_edbone= newbone;
                
                if (to_root) {
                        VECCOPY(newbone->head, ebone->head);
@@ -2635,7 +2689,7 @@ static int armature_duplicate_selected_exec(bContext *C, wmOperator *op)
                                BLI_addtail(arm->edbo, eBone);
                                if (!firstDup)
                                        firstDup=eBone;
-                               
+
                                /* Lets duplicate the list of constraints that the
                                 * current bone has.
                                 */
@@ -2719,12 +2773,21 @@ static int armature_duplicate_selected_exec(bContext *C, wmOperator *op)
                }
        } 
        
+       /* correct the active bone */
+       if(arm->act_edbone) {
+               eBone= arm->act_edbone;
+               if(eBone->temp)
+                       arm->act_edbone= eBone->temp;
+       }
+
        /*      Deselect the old bones and select the new ones */
        for (curBone=arm->edbo->first; curBone && curBone!=firstDup; curBone=curBone->next) {
                if (EBONE_VISIBLE(arm, curBone))
-                       curBone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL | BONE_ACTIVE);
+                       curBone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
        }
 
+       ED_armature_validate_active(arm);
+
        WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, obedit);
        
        return OPERATOR_FINISHED;
@@ -3046,13 +3109,13 @@ static void bones_merge(Object *obedit, EditBone *start, EditBone *end, EditBone
         *      - tail = head/tail of end (default tail)
         *      - parent = parent of start
         */
-       if ((start->flag & BONE_TIPSEL) && !(start->flag & (BONE_SELECTED|BONE_ACTIVE))) {
+       if ((start->flag & BONE_TIPSEL) && ((start->flag & BONE_SELECTED) || start==arm->act_edbone)==0) {
                VECCOPY(head, start->tail);
        }
        else {
                VECCOPY(head, start->head);
        }
-       if ((end->flag & BONE_ROOTSEL) && !(end->flag & (BONE_SELECTED|BONE_ACTIVE))) {
+       if ((end->flag & BONE_ROOTSEL) && ((end->flag & BONE_SELECTED) || end==arm->act_edbone)==0) {
                VECCOPY(tail, end->head);
        }
        else {
@@ -3090,7 +3153,7 @@ static void bones_merge(Object *obedit, EditBone *start, EditBone *end, EditBone
        /* step 3: delete all bones between and including start and end */
        for (ebo= end; ebo; ebo= ebone) {
                ebone= (ebo == start) ? (NULL) : (ebo->parent);
-               BLI_freelinkN(arm->edbo, ebo);
+               free_edit_bone(arm, ebo);
        }
 }
 
@@ -3130,7 +3193,7 @@ static int armature_merge_exec (bContext *C, wmOperator *op)
                                /* check if visible + selected */
                                if ( EBONE_VISIBLE(arm, ebo) &&
                                         ((ebo->flag & BONE_CONNECTED) || (ebo->parent==NULL)) &&
-                                        (ebo->flag & (BONE_SELECTED|BONE_ACTIVE)) )
+                                        ((ebo->flag & BONE_SELECTED) || (ebo==arm->act_edbone)) )
                                {
                                        /* set either end or start (end gets priority, unless it is already set) */
                                        if (bend == NULL)  {
@@ -3205,17 +3268,20 @@ void hide_selected_armature_bones(Scene *scene)
        
        for (ebone = arm->edbo->first; ebone; ebone=ebone->next) {
                if (EBONE_VISIBLE(arm, ebone)) {
-                       if (ebone->flag & (BONE_SELECTED)) {
-                               ebone->flag &= ~(BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL|BONE_ACTIVE);
+                       if (ebone->flag & BONE_SELECTED) {
+                               ebone->flag &= ~(BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL);
                                ebone->flag |= BONE_HIDDEN_A;
                        }
                }
        }
+       ED_armature_validate_active(arm);
        ED_armature_sync_selection(arm->edbo);
        BIF_undo_push("Hide Bones");
 }
 
-void hide_unselected_armature_bones(Scene *scene)
+
+#if 0 // remove this?
+static void hide_unselected_armature_bones(Scene *scene)
 {
        Object *obedit= scene->obedit; // XXX get from context
        bArmature *arm= obedit->data;
@@ -3226,15 +3292,18 @@ void hide_unselected_armature_bones(Scene *scene)
                if (EBONE_VISIBLE(arm, ebone)) {
                        if (ebone->flag & (BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL));
                        else {
-                               ebone->flag &= ~BONE_ACTIVE;
                                ebone->flag |= BONE_HIDDEN_A;
                        }
                }
        }
+
+       ED_armature_validate_active(arm);
        ED_armature_sync_selection(arm->edbo);
        BIF_undo_push("Hide Unselected Bones");
 }
+#endif
 
+#if 0 // remove this?
 void show_all_armature_bones(Scene *scene)
 {
        Object *obedit= scene->obedit; // XXX get from context
@@ -3249,9 +3318,11 @@ void show_all_armature_bones(Scene *scene)
                        }
                }
        }
+       ED_armature_validate_active(arm);
        ED_armature_sync_selection(arm->edbo);
        BIF_undo_push("Reveal Bones");
 }
+#endif
 
 /* previously extrude_armature */
 /* context; editmode armature */
@@ -3301,7 +3372,7 @@ static int armature_extrude_exec(bContext *C, wmOperator *op)
                                                forked= 0;      // we extrude 2 different bones
                                                if (flipbone->flag & (BONE_TIPSEL|BONE_ROOTSEL|BONE_SELECTED))
                                                        /* don't want this bone to be selected... */
-                                                       flipbone->flag &= ~(BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL|BONE_ACTIVE);
+                                                       flipbone->flag &= ~(BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL);
                                        }
                                        if ((flipbone==NULL) && (forked))
                                                flipbone= ebone;
@@ -3373,14 +3444,17 @@ static int armature_extrude_exec(bContext *C, wmOperator *op)
                        }
                        
                        /* Deselect the old bone */
-                       ebone->flag &= ~(BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL|BONE_ACTIVE);
+                       ebone->flag &= ~(BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL);
                }               
        }
        /* if only one bone, make this one active */
-       if (totbone==1 && first) first->flag |= BONE_ACTIVE;
+       if (totbone==1 && first) arm->act_edbone= first;
 
        if (totbone==0) return OPERATOR_CANCELLED;
        
+       if(arm->act_edbone && (((EditBone *)arm->act_edbone)->flag & BONE_SELECTED)==0)
+               arm->act_edbone= NULL;
+
        /* Transform the endpoints */
        ED_armature_sync_selection(arm->edbo);
 
@@ -3965,7 +4039,6 @@ static int armature_select_inverse_exec(bContext *C, wmOperator *op)
                if ((ebone->flag & BONE_UNSELECTABLE) == 0) {
                        /* select bone */
                        ebone->flag ^= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
-                       ebone->flag &= ~BONE_ACTIVE;
                }
        }
        CTX_DATA_END;   
@@ -4009,7 +4082,7 @@ static int armature_de_select_all_exec(bContext *C, wmOperator *op)
                        }
                        else {
                                /* deselect bone */
-                               ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL | BONE_ACTIVE);
+                               ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
                        }
                }
        }
@@ -4053,17 +4126,17 @@ static int armature_select_hierarchy_exec(bContext *C, wmOperator *op)
        for (curbone= arm->edbo->first; curbone; curbone= curbone->next) {
                /* 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 (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_ACTIVE|BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
+                                               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);
-                                               curbone->flag &= ~BONE_ACTIVE;
                                                break;
                                        }
                                        
@@ -4073,13 +4146,13 @@ static int armature_select_hierarchy_exec(bContext *C, wmOperator *op)
                                        if (chbone == NULL) continue;
                                        
                                        if (EBONE_VISIBLE(arm, chbone) && (chbone->flag & BONE_UNSELECTABLE)==0) {
-                                               chbone->flag |= (BONE_ACTIVE|BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
+                                               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;
                                                }
-                                               curbone->flag &= ~BONE_ACTIVE;
                                                break;
                                        }
                                }
@@ -4256,14 +4329,6 @@ void ARMATURE_OT_align(wmOperatorType *ot)
 
 /* ***************** Pose tools ********************* */
 
-/* helper for function below */
-static int clear_active_flag(Object *ob, Bone *bone, void *data) 
-{
-       bone->flag &= ~BONE_ACTIVE;
-       return 0;
-}
-
-
 // XXX bone_looper is only to be used when we want to access settings (i.e. editability/visibility/selected) that context doesn't offer 
 static int bone_looper(Object *ob, Bone *bone, void *data,
                                int (*bone_func)(Object *, Bone *, void *)) 
@@ -4310,7 +4375,8 @@ int ED_do_pose_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, shor
                /* since we do unified select, we don't shift+select a bone if the armature object was not active yet */
                if (!(extend) || (base != scene->basact)) {
                        ED_pose_deselectall(ob, 0, 0);
-                       nearBone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL|BONE_ACTIVE);
+                       nearBone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
+                       arm->act_bone= nearBone;
                        
                                // XXX old cruft! use notifiers instead
                        //select_actionchannel_by_name(ob->action, nearBone->name, 1);
@@ -4318,21 +4384,19 @@ int ED_do_pose_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, shor
                else {
                        if (nearBone->flag & BONE_SELECTED) {
                                /* if not active, we make it active */
-                               if((nearBone->flag & BONE_ACTIVE)==0) {
-                                       bone_looper(ob, arm->bonebase.first, NULL, clear_active_flag);
-                                       nearBone->flag |= BONE_ACTIVE;
+                               if(nearBone != arm->act_bone) {
+                                       arm->act_bone= nearBone;
                                }
                                else {
-                                       nearBone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL|BONE_ACTIVE);
+                                       nearBone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
                                        
                                                // XXX old cruft! use notifiers instead
                                        //select_actionchannel_by_name(ob->action, nearBone->name, 0);
                                }
                        }
                        else {
-                               bone_looper(ob, arm->bonebase.first, NULL, clear_active_flag);
-                               
-                               nearBone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL|BONE_ACTIVE);
+                               nearBone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
+                               arm->act_bone= nearBone;
                                
                                        // XXX old cruft! use notifiers instead
                                //select_actionchannel_by_name(ob->action, nearBone->name, 1);
@@ -4341,7 +4405,7 @@ int ED_do_pose_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, shor
                
                /* in weightpaint we select the associated vertex group too */
                if (OBACT && OBACT->mode & OB_MODE_WEIGHT_PAINT) {
-                       if (nearBone->flag & BONE_ACTIVE) {
+                       if (nearBone == arm->act_bone) {
                                ED_vgroup_select_by_name(OBACT, nearBone->name);
                                DAG_id_flush_update(&OBACT->id, OB_RECALC_DATA);
                        }
@@ -4387,16 +4451,17 @@ void ED_pose_deselectall (Object *ob, int test, int doundo)
                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;
                        }
                        else {
-                               if (selectmode==0) pchan->bone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL|BONE_ACTIVE);
+                               if (selectmode==0) pchan->bone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
                                else if (selectmode==1) pchan->bone->flag |= BONE_SELECTED;
-                               else pchan->bone->flag &= ~BONE_ACTIVE;
                        }
                }
        }
        
+       if(arm->act_bone && (arm->act_bone->flag & BONE_SELECTED)==0)
+               arm->act_bone= NULL;
+
        //countall(); // XXX need an equivalent to this...
        
        if (doundo) {
@@ -4990,7 +5055,6 @@ static int pose_select_inverse_exec(bContext *C, wmOperator *op)
        CTX_DATA_BEGIN(C, bPoseChannel *, pchan, visible_pchans) {
                if ((pchan->bone->flag & BONE_UNSELECTABLE) == 0) {
                        pchan->bone->flag ^= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
-                       pchan->bone->flag &= ~BONE_ACTIVE;
                }
        }       
        CTX_DATA_END;
@@ -5026,12 +5090,13 @@ static int pose_de_select_all_exec(bContext *C, wmOperator *op)
        /*      Set the flags */
        CTX_DATA_BEGIN(C, bPoseChannel *, pchan, visible_pchans) {
                /* select pchan only if selectable, but deselect works always */
-               if (sel==0) 
-                       pchan->bone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL|BONE_ACTIVE);
+               if (sel==0) {
+                       pchan->bone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
+               }
                else if ((pchan->bone->flag & BONE_UNSELECTABLE)==0)
                        pchan->bone->flag |= BONE_SELECTED;
        }
-       CTX_DATA_END;   
+       CTX_DATA_END;
 
        WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, NULL);
        
@@ -5062,11 +5127,11 @@ static int pose_select_parent_exec(bContext *C, wmOperator *op)
        /*      Determine if there is an active bone */
        pchan=CTX_data_active_pchan(C);
        if (pchan) {
+               bArmature *arm= ob->data;
                parent=pchan->parent;
                if ((parent) && !(parent->bone->flag & (BONE_HIDDEN_P|BONE_UNSELECTABLE))) {
                        parent->bone->flag |= BONE_SELECTED;
-                       parent->bone->flag |= BONE_ACTIVE;
-                       pchan->bone->flag &= ~BONE_ACTIVE;
+                       arm->act_bone= parent->bone;
                }
                else {
                        return OPERATOR_CANCELLED;
@@ -5105,7 +5170,8 @@ static int hide_selected_pose_bone(Object *ob, Bone *bone, void *ptr)
        if (arm->layer & bone->layer) {
                if (bone->flag & BONE_SELECTED) {
                        bone->flag |= BONE_HIDDEN_P;
-                       bone->flag &= ~(BONE_SELECTED|BONE_ACTIVE);
+                       if(arm->act_bone==bone)
+                               arm->act_bone= NULL;
                }
        }
        return 0;
@@ -5117,9 +5183,10 @@ static int hide_unselected_pose_bone(Object *ob, Bone *bone, void *ptr)
        
        if (arm->layer & bone->layer) {
                // hrm... typo here?
-               if (~bone->flag & BONE_SELECTED) {
+               if ((bone->flag & BONE_SELECTED)==0) {
                        bone->flag |= BONE_HIDDEN_P;
-                       bone->flag &= ~BONE_ACTIVE;
+                       if(arm->act_bone==bone)
+                               arm->act_bone= NULL;
                }
        }
        return 0;
@@ -5576,7 +5643,8 @@ EditBone * subdivideByAngle(Scene *scene, Object *obedit, ReebArc *arc, ReebNode
                 * */
                if (parent == root)
                {
-                       delete_bone(arm->edbo, parent);
+                       if(parent==arm->act_edbone) arm->act_edbone= NULL;
+                       delete_bone(arm, parent);
                        parent = NULL;
                }
                
index 4d65059c4c6a3f8bdfdc452c005d85626a338d65..824e7be94d92b9054f479dc9e7c5083319b55760 100644 (file)
@@ -509,7 +509,7 @@ static RigControl *cloneControl(RigGraph *rg, RigGraph *src_rg, RigControl *src_
 
        renameTemplateBone(name, src_ctrl->bone->name, rg->editbones, side_string, num_string);
        ctrl->bone = duplicateEditBoneObjects(src_ctrl->bone, name, rg->editbones, src_rg->ob, rg->ob);
-       ctrl->bone->flag &= ~(BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL|BONE_ACTIVE);
+       ctrl->bone->flag &= ~(BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL);
        BLI_ghash_insert(ptr_hash, src_ctrl->bone, ctrl->bone);
        
        ctrl->link = src_ctrl->link;
@@ -554,7 +554,7 @@ static RigArc *cloneArc(RigGraph *rg, RigGraph *src_rg, RigArc *src_arc, GHash *
                        char name[32];
                        renameTemplateBone(name, src_edge->bone->name, rg->editbones, side_string, num_string);
                        edge->bone = duplicateEditBoneObjects(src_edge->bone, name, rg->editbones, src_rg->ob, rg->ob);
-                       edge->bone->flag &= ~(BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL|BONE_ACTIVE);
+                       edge->bone->flag &= ~(BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL);
                        BLI_ghash_insert(ptr_hash, src_edge->bone, edge->bone);
                }
 
@@ -1555,7 +1555,7 @@ RigGraph *RIG_graphFromArmature(const bContext *C, Object *ob, bArmature *arm)
        else
        {
                rg->editbones = MEM_callocN(sizeof(ListBase), "EditBones");
-               make_boneList(rg->editbones, &arm->bonebase, NULL);
+               make_boneList(rg->editbones, &arm->bonebase, NULL, NULL);
                rg->flag |= RIG_FREE_BONELIST;
        }
        
@@ -1607,7 +1607,7 @@ RigGraph *armatureSelectedToGraph(bContext *C, Object *ob, bArmature *arm)
        else
        {
                rg->editbones = MEM_callocN(sizeof(ListBase), "EditBones");
-               make_boneList(rg->editbones, &arm->bonebase, NULL);
+               make_boneList(rg->editbones, &arm->bonebase, NULL, NULL);
                rg->flag |= RIG_FREE_BONELIST;
        }
 
@@ -2947,6 +2947,8 @@ void BIF_retargetArc(bContext *C, ReebArc *earc, RigGraph *template_rigg)
        }
        RIG_freeRigGraph((BGraph*)rigg);
        
+       ED_armature_validate_active(armedit);
+
 //     XXX
 //     allqueue(REDRAWVIEW3D, 0);
 }
index f67c94eebc30c9b7e3157f2a07c6db518754598f..565a4782377ac70f2a2fc054e477c4a4c8767690 100644 (file)
@@ -382,7 +382,7 @@ static int poselib_add_exec (bContext *C, wmOperator *op)
        for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) {
                /* check if available */
                if ((pchan->bone) && (arm->layer & pchan->bone->layer)) {
-                       if (pchan->bone->flag & (BONE_SELECTED|BONE_ACTIVE)) {
+                       if (pchan->bone->flag & BONE_SELECTED || pchan->bone==arm->act_bone) {
                                /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */
                                cks.pchan= pchan;
                                
@@ -762,7 +762,7 @@ static void poselib_apply_pose (tPoseLib_PreviewData *pld)
                                }
                                else if (pchan->bone) {
                                        /* only ok if bone is visible and selected */
-                                       if ( (pchan->bone->flag & (BONE_SELECTED|BONE_ACTIVE)) &&
+                                       if ( (pchan->bone->flag & BONE_SELECTED || pchan->bone == arm->act_bone) &&
                                                 (pchan->bone->flag & BONE_HIDDEN_P)==0 &&
                                                 (pchan->bone->layer & arm->layer) )
                                                ok = 1;
index 696fa65b33a006e372aced1d2d61a709bcdcacbe..d7741c2a5efdb15121adf029c6ef4b88ab0d6182 100644 (file)
@@ -158,12 +158,12 @@ static short pose_has_protected_selected(Object *ob, short only_selected, short
        if (ob->proxy) {
                bPoseChannel *pchan;
                bArmature *arm= ob->data;
-               
+
                for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
                        if (pchan->bone && (pchan->bone->layer & arm->layer)) {
                                if (pchan->bone->layer & arm->layer_protected) {
-                                       if (only_selected && (pchan->bone->flag & BONE_ACTIVE));
-                                       else if (pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) 
+                                       if (only_selected && (pchan->bone == arm->act_bone));
+                                       else if (pchan->bone->flag & BONE_SELECTED || pchan->bone == arm->act_bone)
                                           break;
                                }
                        }
@@ -531,7 +531,7 @@ void pose_select_constraint_target(Scene *scene)
        
        for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
                if (arm->layer & pchan->bone->layer) {
-                       if (pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) {
+                       if (pchan->bone->flag & BONE_SELECTED || pchan->bone == arm->act_bone) {
                                for (con= pchan->constraints.first; con; con= con->next) {
                                        bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
                                        ListBase targets = {NULL, NULL};
@@ -570,7 +570,7 @@ static int pose_select_constraint_target_exec(bContext *C, wmOperator *op)
        
        for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
                if (arm->layer & pchan->bone->layer) {
-                       if (pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) {
+                       if (pchan->bone->flag & BONE_SELECTED || pchan->bone == arm->act_bone) {
                                for (con= pchan->constraints.first; con; con= con->next) {
                                        bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
                                        ListBase targets = {NULL, NULL};
@@ -635,7 +635,7 @@ static int pose_select_hierarchy_exec(bContext *C, wmOperator *op)
                curbone= pchan->bone;
                
                if ((arm->layer & curbone->layer) && (curbone->flag & BONE_UNSELECTABLE)==0) {
-                       if (curbone->flag & (BONE_ACTIVE)) {
+                       if (curbone == arm->act_bone) {
                                if (direction == BONE_SELECT_PARENT) {
                                
                                        if (pchan->parent == NULL) continue;
@@ -644,8 +644,8 @@ static int pose_select_hierarchy_exec(bContext *C, wmOperator *op)
                                        if ((arm->layer & pabone->layer) && !(pabone->flag & BONE_HIDDEN_P)) {
                                                
                                                if (!add_to_sel) curbone->flag &= ~BONE_SELECTED;
-                                               curbone->flag &= ~BONE_ACTIVE;
-                                               pabone->flag |= (BONE_ACTIVE|BONE_SELECTED);
+                                               pabone->flag |= BONE_SELECTED;
+                                               arm->act_bone= pabone;
                                                
                                                found= 1;
                                                break;
@@ -658,8 +658,8 @@ static int pose_select_hierarchy_exec(bContext *C, wmOperator *op)
                                        if ((arm->layer & chbone->layer) && !(chbone->flag & BONE_HIDDEN_P)) {
                                        
                                                if (!add_to_sel) curbone->flag &= ~BONE_SELECTED;
-                                               curbone->flag &= ~BONE_ACTIVE;
-                                               chbone->flag |= (BONE_ACTIVE|BONE_SELECTED);
+                                               chbone->flag |= BONE_SELECTED;
+                                               arm->act_bone= chbone;
                                                
                                                found= 1;
                                                break;
@@ -717,11 +717,7 @@ void pose_copy_menu(Scene *scene)
        if (ELEM(NULL, ob, ob->pose)) return;
        if ((ob==obedit) || (ob->mode & OB_MODE_POSE)==0) return;
        
-       /* find active */
-       for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
-               if (pchan->bone->flag & BONE_ACTIVE) 
-                       break;
-       }
+       pchan= get_active_posechannel(ob);
        
        if (pchan==NULL) return;
        pchanact= pchan;
@@ -1397,7 +1393,7 @@ static int pose_group_unassign_exec (bContext *C, wmOperator *op)
                /* ensure that PoseChannel is on visible layer and is not hidden in PoseMode */
                // NOTE: sync this view3d_context() in space_view3d.c
                if ((pchan->bone) && (arm->layer & pchan->bone->layer) && !(pchan->bone->flag & BONE_HIDDEN_P)) {
-                       if (pchan->bone->flag & (BONE_SELECTED|BONE_ACTIVE)) {
+                       if (pchan->bone->flag & BONE_SELECTED || pchan->bone == arm->act_bone) {
                                if (pchan->agrp_index) {
                                        pchan->agrp_index= 0;
                                        done= 1;
@@ -1444,7 +1440,7 @@ static short pose_select_same_group (Object *ob)
        /* loop in loop... bad and slow! */
        for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
                if (arm->layer & pchan->bone->layer) {
-                       if (pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) {
+                       if (pchan->bone->flag & BONE_SELECTED || pchan->bone == arm->act_bone) {
                                
                                /* only if group matches (and is not selected or current bone) */
                                for (chan= ob->pose->chanbase.first; chan; chan= chan->next) {
@@ -1476,7 +1472,7 @@ static short pose_select_same_layer (Object *ob)
        /* figure out what bones are selected */
        for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
                if (arm->layer & pchan->bone->layer) {
-                       if (pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) {
+                       if (pchan->bone->flag & BONE_SELECTED || pchan->bone == arm->act_bone) {
                                layers |= pchan->bone->layer;
                        }
                }
@@ -1637,25 +1633,21 @@ void pose_activate_flipped_bone(Scene *scene)
                ob= modifiers_isDeformedByArmature(ob);
        }
        if(ob && (ob->mode & OB_MODE_POSE)) {
-               bPoseChannel *pchan, *pchanf;
+               bPoseChannel *pchanf;
                
-               for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
-                       if(arm->layer & pchan->bone->layer) {
-                               if(pchan->bone->flag & BONE_ACTIVE)
-                                       break;
-                       }
-               }
-               if(pchan) {
+               if(arm->act_bone) {
                        char name[32];
                        
-                       BLI_strncpy(name, pchan->name, 32);
+                       BLI_strncpy(name, arm->act_bone->name, 32);
                        bone_flip_name(name, 1);        // 0 = do not strip off number extensions
                        
                        pchanf= get_pose_channel(ob->pose, name);
-                       if(pchanf && pchanf!=pchan) {
-                               pchan->bone->flag &= ~(BONE_SELECTED|BONE_ACTIVE);
-                               pchanf->bone->flag |= (BONE_SELECTED|BONE_ACTIVE);
-                       
+                       if(pchanf && pchanf->bone != arm->act_bone) {
+                               arm->act_bone->flag &= ~BONE_SELECTED;
+                               pchanf->bone->flag |= BONE_SELECTED;
+
+                               arm->act_bone= pchanf->bone;
+
                                /* in weightpaint we select the associated vertex group too */
                                if(ob->mode & OB_MODE_WEIGHT_PAINT) {
                                        ED_vgroup_select_by_name(OBACT, name);
index 5cc35d4ad77506c7fe155bd420b4de52c9b7dd5a..1836729e4193b517c71516509fc05610801e3ed6 100644 (file)
@@ -113,6 +113,7 @@ struct Bone *get_indexed_bone (struct Object *ob, int index);
 float ED_rollBoneToVector(EditBone *bone, float new_up_axis[3]);
 EditBone *ED_armature_bone_get_mirrored(struct ListBase *edbo, EditBone *ebo); // XXX this is needed for populating the context iterators
 void ED_armature_sync_selection(struct ListBase *edbo);
+void ED_armature_validate_active(struct bArmature *arm);
 
 void add_primitive_bone(struct Scene *scene, struct View3D *v3d, struct RegionView3D *rv3d);
 EditBone *addEditBone(struct bArmature *arm, char *name); /* used by COLLADA importer */
index 919cc3f0cfdf49683782bc0f114a1b21b0a02b1e..c02d86a567e11db2b926cd467e968d4fe51ac5d3 100644 (file)
@@ -215,7 +215,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
                        for (pchan= obact->pose->chanbase.first; pchan; pchan= pchan->next) {
                                /* ensure that PoseChannel is on visible layer and is not hidden in PoseMode */
                                if ((pchan->bone) && (arm->layer & pchan->bone->layer) && !(pchan->bone->flag & BONE_HIDDEN_P)) {
-                                       if (pchan->bone->flag & (BONE_SELECTED|BONE_ACTIVE)) 
+                                       if (pchan->bone->flag & BONE_SELECTED || pchan->bone == arm->act_bone)
                                                CTX_data_list_add(result, &obact->id, &RNA_PoseChannel, pchan);
                                }
                        }
@@ -224,21 +224,19 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
                }
        }
        else if(CTX_data_equals(member, "active_bone")) {
-               bArmature *arm= (obedit) ? obedit->data : NULL;
-               EditBone *ebone;
-               
-               if (arm && arm->edbo) {
-                       for (ebone= arm->edbo->first; ebone; ebone= ebone->next) {
-                               if (EBONE_VISIBLE(arm, ebone)) {
-                                       if (ebone->flag & BONE_ACTIVE) {
-                                               CTX_data_pointer_set(result, &arm->id, &RNA_EditBone, ebone);
-                                               
-                                               return 1;
-                                       }
-                               }
+               bArmature *arm= (obact) ? obact->data : NULL;
+               if(arm->edbo) {
+                       if(arm->act_edbone) {
+                               CTX_data_pointer_set(result, &arm->id, &RNA_EditBone, arm->act_edbone);
+                               return 1;
+                       }
+               }
+               else {
+                       if(arm->act_bone) {
+                               CTX_data_pointer_set(result, &arm->id, &RNA_Bone, arm->act_bone);
+                               return 1;
                        }
                }
-               
        }
        else if(CTX_data_equals(member, "active_pchan")) {
                bPoseChannel *pchan;
index 408f4862b6f284efdfc53a25227e5d3a3cf21e1a..2045397f3c9b9aad7925b96c075fdf2ab95e9ca7 100644 (file)
@@ -1104,12 +1104,10 @@ static int set_wpaint(bContext *C, wmOperator *op)              /* toggle */
                /* verify if active weight group is also active bone */
                par= modifiers_isDeformedByArmature(ob);
                if(par && (par->mode & OB_MODE_POSE)) {
-                       bPoseChannel *pchan;
-                       for(pchan= par->pose->chanbase.first; pchan; pchan= pchan->next)
-                               if(pchan->bone->flag & BONE_ACTIVE)
-                                       break;
-                               if(pchan)
-                                       ED_vgroup_select_by_name(ob, pchan->name);
+                       bArmature *arm= ob->data;
+
+                       if(arm->act_bone)
+                               ED_vgroup_select_by_name(ob, arm->act_bone->name);
                }
        }
        else {
index 026498f17af1c841543618a3801163398860c3cd..47055851e033dd9ce792d37d0f3b7c3793f712e6 100644 (file)
@@ -243,26 +243,9 @@ static int buttons_context_path_material(ButsContextPath *path)
        return 0;
 }
 
-static Bone *find_active_bone(Bone *bone)
-{
-       Bone *active;
-
-       for(; bone; bone=bone->next) {
-               if(bone->flag & BONE_ACTIVE)
-                       return bone;
-
-               active= find_active_bone(bone->childbase.first);
-               if(active)
-                       return active;
-       }
-
-       return NULL;
-}
-
 static int buttons_context_path_bone(ButsContextPath *path)
 {
        bArmature *arm;
-       Bone *bone;
        EditBone *edbo;
 
        /* if we have an armature, get the active bone */
@@ -270,19 +253,16 @@ static int buttons_context_path_bone(ButsContextPath *path)
                arm= path->ptr[path->len-1].data;
 
                if(arm->edbo) {
-                       for(edbo=arm->edbo->first; edbo; edbo=edbo->next) {
-                               if(edbo->flag & BONE_ACTIVE) {
-                                       RNA_pointer_create(&arm->id, &RNA_EditBone, edbo, &path->ptr[path->len]);
-                                       path->len++;
-                                       return 1;
-                               }
+                       if(arm->act_edbone) {
+                               edbo= arm->act_edbone;
+                               RNA_pointer_create(&arm->id, &RNA_EditBone, edbo, &path->ptr[path->len]);
+                               path->len++;
+                               return 1;
                        }
                }
                else {
-                       bone= find_active_bone(arm->bonebase.first);
-
-                       if(bone) {
-                               RNA_pointer_create(&arm->id, &RNA_Bone, bone, &path->ptr[path->len]);
+                       if(arm->act_bone) {
+                               RNA_pointer_create(&arm->id, &RNA_Bone, arm->act_bone, &path->ptr[path->len]);
                                path->len++;
                                return 1;
                        }
index bc203a9c80b0a147e6210a23bacb88925c2cf781..39eecd7d2de8526833226071c41d6b9466e81fe5 100644 (file)
@@ -2025,6 +2025,7 @@ static int tree_element_active_posegroup(bContext *C, Scene *scene, TreeElement
 static int tree_element_active_posechannel(bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *tselem, int set)
 {
        Object *ob= (Object *)tselem->id;
+       bArmature *arm= ob->data;
        bPoseChannel *pchan= te->directdata;
        
        if(set) {
@@ -2033,10 +2034,14 @@ static int tree_element_active_posechannel(bContext *C, Scene *scene, TreeElemen
                        if(set==2) ED_pose_deselectall(ob, 2, 0);       // 2 = clear active tag
                        else ED_pose_deselectall(ob, 0, 0);     // 0 = deselect 
                        
-                       if(set==2 && (pchan->bone->flag & BONE_SELECTED))
-                               pchan->bone->flag &= ~(BONE_SELECTED|BONE_ACTIVE);
-                       else
-                               pchan->bone->flag |= BONE_SELECTED|BONE_ACTIVE;
+                       if(set==2 && (pchan->bone->flag & BONE_SELECTED)) {
+                               pchan->bone->flag &= ~BONE_SELECTED;
+                               if(arm->act_bone==pchan->bone)
+                                       arm->act_bone= NULL;
+                       } else {
+                               pchan->bone->flag |= BONE_SELECTED;
+                               arm->act_bone= pchan->bone;
+                       }
                        
                        WM_event_add_notifier(C, NC_OBJECT|ND_BONE_ACTIVE, ob);
 
@@ -2060,10 +2065,14 @@ static int tree_element_active_bone(bContext *C, Scene *scene, TreeElement *te,
                        if(set==2) ED_pose_deselectall(OBACT, 2, 0);    // 2 is clear active tag
                        else ED_pose_deselectall(OBACT, 0, 0);
                        
-                       if(set==2 && (bone->flag & BONE_SELECTED))
-                               bone->flag &= ~(BONE_SELECTED|BONE_ACTIVE);
-                       else
-                               bone->flag |= BONE_SELECTED|BONE_ACTIVE;
+                       if(set==2 && (bone->flag & BONE_SELECTED)) {
+                               bone->flag &= ~BONE_SELECTED;
+                               if(arm->act_bone==bone)
+                                       arm->act_bone= NULL;
+                       } else {
+                               bone->flag |= BONE_SELECTED;
+                               arm->act_bone= bone;
+                       }
                        
                        WM_event_add_notifier(C, NC_OBJECT|ND_BONE_ACTIVE, OBACT);
                }
@@ -2086,11 +2095,13 @@ static int tree_element_active_ebone(bContext *C, Scene *scene, TreeElement *te,
        
        if(set) {
                if(!(ebone->flag & BONE_HIDDEN_A)) {
-                       
+                       bArmature *arm= scene->obedit->data;
                        if(set==2) ED_armature_deselectall(scene->obedit, 2, 0);        // only clear active tag
                        else ED_armature_deselectall(scene->obedit, 0, 0);      // deselect
 
-                       ebone->flag |= BONE_SELECTED|BONE_ROOTSEL|BONE_TIPSEL|BONE_ACTIVE;
+                       ebone->flag |= BONE_SELECTED|BONE_ROOTSEL|BONE_TIPSEL;
+                       arm->act_edbone= ebone;
+
                        // flush to parent?
                        if(ebone->parent && (ebone->flag & BONE_CONNECTED)) ebone->parent->flag |= BONE_TIPSEL;
                        
index 656d7061d48fb0df111ccbd10ab30e0a9979a8c6..230bacf4f7fe34dcab47ab9f5ccce05b5dfbe3d0 100644 (file)
@@ -166,7 +166,7 @@ static short set_pchan_glColor (short colCode, int armflag, int boneflag, int co
                if (bcolor) {
                        char cp[3];
                        
-                       if (boneflag & BONE_ACTIVE) {
+                       if (boneflag & BONE_DRAW_ACTIVE) {
                                VECCOPY(cp, bcolor->active);
                        }
                        else if (boneflag & BONE_SELECTED) {
@@ -181,7 +181,7 @@ static short set_pchan_glColor (short colCode, int armflag, int boneflag, int co
                        glColor3ub(cp[0], cp[1], cp[2]);
                }
                else {
-                       if (boneflag & BONE_ACTIVE) UI_ThemeColorShade(TH_BONE_POSE, 40);
+                       if (boneflag & BONE_DRAW_ACTIVE) UI_ThemeColorShade(TH_BONE_POSE, 40);
                        else if (boneflag & BONE_SELECTED) UI_ThemeColor(TH_BONE_POSE);
                        else UI_ThemeColor(TH_WIRE);
                }
@@ -225,7 +225,7 @@ static short set_pchan_glColor (short colCode, int armflag, int boneflag, int co
                if (bcolor) {
                        char cp[3];
                        
-                       if (boneflag & BONE_ACTIVE) {
+                       if (boneflag & BONE_DRAW_ACTIVE) {
                                VECCOPY(cp, bcolor->active);
                        }
                        else if (boneflag & BONE_SELECTED) {
@@ -238,7 +238,7 @@ static short set_pchan_glColor (short colCode, int armflag, int boneflag, int co
                        glColor3ub(cp[0], cp[1], cp[2]);
                }
                else {
-                       if (boneflag & BONE_ACTIVE) UI_ThemeColorShade(TH_BONE_POSE, 40);
+                       if (boneflag & BONE_DRAW_ACTIVE) UI_ThemeColorShade(TH_BONE_POSE, 40);
                        else if (boneflag & BONE_SELECTED) UI_ThemeColor(TH_BONE_POSE);
                        else UI_ThemeColor(TH_BONE_SOLID);
                }
@@ -251,7 +251,7 @@ static short set_pchan_glColor (short colCode, int armflag, int boneflag, int co
                if (bcolor) {
                        char cp[3];
                        
-                       if (boneflag & BONE_ACTIVE) {
+                       if (boneflag & BONE_DRAW_ACTIVE) {
                                VECCOPY(cp, bcolor->active);
                                cp_shade_color3ub(cp, 10);
                        }
@@ -267,7 +267,7 @@ static short set_pchan_glColor (short colCode, int armflag, int boneflag, int co
                        glColor3ub(cp[0], cp[1], cp[2]);
                }
                else {
-                       if (boneflag & BONE_ACTIVE) UI_ThemeColorShade(TH_BONE_POSE, 10);
+                       if (boneflag & BONE_DRAW_ACTIVE) UI_ThemeColorShade(TH_BONE_POSE, 10);
                        else if (boneflag & BONE_SELECTED) UI_ThemeColorShade(TH_BONE_POSE, -30);
                        else UI_ThemeColorShade(TH_BONE_SOLID, -30);
                }
@@ -1151,7 +1151,7 @@ static void draw_b_bone(int dt, int armflag, int boneflag, int constflag, unsign
        }
        else if (armflag & ARM_EDITMODE) {
                if (dt==OB_WIRE) {
-                       if (boneflag & BONE_ACTIVE) UI_ThemeColor(TH_EDGE_SELECT);
+                       if (boneflag & BONE_DRAW_ACTIVE) UI_ThemeColor(TH_EDGE_SELECT);
                        else if (boneflag & BONE_SELECTED) UI_ThemeColorShade(TH_EDGE_SELECT, -20);
                        else UI_ThemeColor(TH_WIRE);
                }
@@ -1236,7 +1236,7 @@ static void draw_bone(int dt, int armflag, int boneflag, int constflag, unsigned
        if (dt <= OB_WIRE) {
                /* colors */
                if (armflag & ARM_EDITMODE) {
-                       if (boneflag & BONE_ACTIVE) UI_ThemeColor(TH_EDGE_SELECT);
+                       if (boneflag & BONE_DRAW_ACTIVE) UI_ThemeColor(TH_EDGE_SELECT);
                        else if (boneflag & BONE_SELECTED) UI_ThemeColorShade(TH_EDGE_SELECT, -20);
                        else UI_ThemeColor(TH_WIRE);
                }
@@ -1629,7 +1629,10 @@ static void draw_pose_channels(Scene *scene, View3D *v3d, ARegion *ar, Base *bas
                                        flag= bone->flag;
                                        if ( (bone->parent) && (bone->parent->flag & (BONE_HIDDEN_P|BONE_HIDDEN_PG)) )
                                                flag &= ~BONE_CONNECTED;
-                                               
+
+                                       if(bone==arm->act_bone)
+                                               flag |= BONE_DRAW_ACTIVE;
+
                                        /* set color-set to use */
                                        set_pchan_colorset(ob, pchan);
                                        
index 2edccacff7a18e4fc64ef3e8de2554d366fc9415..608a22ea5295dfb46e4a929bff1678a6a9915377 100644 (file)
@@ -575,22 +575,15 @@ static void v3d_transform_butsR(uiLayout *layout, PointerRNA *ptr)
 static void v3d_posearmature_buts(uiLayout *layout, View3D *v3d, Object *ob, float lim)
 {
 //     uiBlock *block= uiLayoutGetBlock(layout);
-       bArmature *arm;
+//     bArmature *arm;
        bPoseChannel *pchan;
-       Bone *bone= NULL;
 //     TransformProperties *tfp= v3d->properties_storage;
        PointerRNA pchanptr;
        uiLayout *col;
 //     uiLayout *row;
 
-       arm = ob->data;
-       if (!arm || !ob->pose) return;
+       pchan= get_active_posechannel(ob);
 
-       for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
-               bone = pchan->bone;
-               if(bone && (bone->flag & BONE_ACTIVE) && (bone->layer & arm->layer))
-                       break;
-       }
 //     row= uiLayoutRow(layout, 0);
        
        if (!pchan)     {
@@ -691,14 +684,9 @@ static void v3d_editarmature_buts(uiLayout *layout, View3D *v3d, Object *ob, flo
        uiLayout *col;
        PointerRNA eboneptr;
        
-       ebone= arm->edbo->first;
+       ebone= arm->act_edbone;
 
-       for (ebone = arm->edbo->first; ebone; ebone=ebone->next){
-               if ((ebone->flag & BONE_ACTIVE) && (ebone->layer & arm->layer))
-                       break;
-       }
-
-       if (!ebone)
+       if (!ebone || (ebone->layer & arm->layer)==0)
                return;
        
 //     row= uiLayoutRow(layout, 0);
@@ -821,19 +809,10 @@ static void do_view3d_region_buttons(bContext *C, void *arg, int event)
 
        case B_ARMATUREPANEL3:  // rotate button on channel
                {
-                       bArmature *arm;
                        bPoseChannel *pchan;
-                       Bone *bone;
                        float eul[3];
                        
-                       arm = ob->data;
-                       if (!arm || !ob->pose) return;
-                               
-                       for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
-                               bone = pchan->bone;
-                               if(bone && (bone->flag & BONE_ACTIVE) && (bone->layer & arm->layer))
-                                       break;
-                       }
+                       pchan= get_active_posechannel(ob);
                        if (!pchan) return;
                        
                        /* make a copy to eul[3], to allow TAB on buttons to work */
index 247800c30771681a05134f48a320032a035e9e16..2879dc3ed226bb25e79abb79b1b8a62fcac16a04 100644 (file)
@@ -791,21 +791,17 @@ static void draw_selected_name(Scene *scene, Object *ob, View3D *v3d)
                        
                        /* show name of active bone too (if possible) */
                        if(arm->edbo) {
-                               EditBone *ebo;
-                               for (ebo=arm->edbo->first; ebo; ebo=ebo->next){
-                                       if ((ebo->flag & BONE_ACTIVE) && (ebo->layer & arm->layer)) {
-                                               name= ebo->name;
-                                               break;
-                                       }
-                               }
+
+                               if(arm->act_edbone)
+                                       name= ((EditBone *)arm->act_edbone)->name;
+
                        }
-                       else if(ob->pose && (ob->mode & OB_MODE_POSE)) {
-                               bPoseChannel *pchan;
-                               for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
-                                       if((pchan->bone->flag & BONE_ACTIVE) && (pchan->bone->layer & arm->layer)) {
-                                               name= pchan->name;
-                                               break;
-                                       }
+                       else if(ob->mode & OB_MODE_POSE) {
+                               if(arm->act_bone) {
+
+                                       if(arm->act_bone->layer & arm->layer)
+                                               name= arm->act_bone->name;
+
                                }
                        }
                        if(name && markern)
index f0425974f294ad925960e5138992ed909f3aa3ef..2505110d766a401493c90a7291f8900e2581ad7a 100644 (file)
@@ -357,7 +357,14 @@ static void do_lasso_select_pose(ViewContext *vc, short mcords[][2], short moves
                
                if(lasso_inside_edge(mcords, moves, sco1[0], sco1[1], sco2[0], sco2[1])) {
                        if(select) pchan->bone->flag |= BONE_SELECTED;
-                       else pchan->bone->flag &= ~(BONE_ACTIVE|BONE_SELECTED);
+                       else pchan->bone->flag &= ~BONE_SELECTED;
+               }
+       }
+       
+       {
+               bArmature *arm= ob->data;
+               if((arm->act_bone->flag & BONE_SELECTED)==0) {
+                       arm->act_bone= NULL;
                }
        }
 }
@@ -638,9 +645,11 @@ static void do_lasso_select_armature(ViewContext *vc, short mcords[][2], short m
                /* if one of points selected, we skip the bone itself */
                if(didpoint==0 && lasso_inside_edge(mcords, moves, sco1[0], sco1[1], sco2[0], sco2[1])) {
                        if(select) ebone->flag |= BONE_TIPSEL|BONE_ROOTSEL|BONE_SELECTED;
-                       else ebone->flag &= ~(BONE_ACTIVE|BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
+                       else ebone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
                }
        }
+
+       ED_armature_validate_active(arm);
 }
 
 static void do_lasso_select_facemode(ViewContext *vc, short mcords[][2], short moves, short select)
@@ -1534,8 +1543,12 @@ static int view3d_borderselect_exec(bContext *C, wmOperator *op)
 // XXX                                                                 select_actionchannel_by_name(base->object->action, bone->name, 1);
                                                                }
                                                                else {
-                                                                       bone->flag &= ~(BONE_ACTIVE|BONE_SELECTED);
+                                                                       bArmature *arm= base->object->data;
+                                                                       bone->flag &= ~BONE_SELECTED;
 // XXX                                                                 select_actionchannel_by_name(base->object->action, bone->name, 0);
+                                                                       if(arm->act_bone==bone)
+                                                                               arm->act_bone= NULL;
+                                                                       
                                                                }
                                                        }
                                                }
@@ -1868,9 +1881,11 @@ static void armature_circle_select(ViewContext *vc, int selecting, short *mval,
                        if (selecting) 
                                ebone->flag |= BONE_TIPSEL|BONE_ROOTSEL|BONE_SELECTED;
                        else 
-                               ebone->flag &= ~(BONE_ACTIVE|BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL); 
+                               ebone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
                }
        }
+
+       ED_armature_validate_active(arm);
 }
 
 /** Callbacks for circle selection in Editmode */
index 0f4848d91208775feb8b9ab0f066daa5460b893e..86e83715da428cd52f910b072f5c47420cddf937 100644 (file)
@@ -55,6 +55,7 @@
 
 #include "RNA_access.h"
 
+#include "BKE_action.h"
 #include "BKE_armature.h"
 #include "BKE_context.h"
 #include "BKE_global.h"
@@ -185,18 +186,9 @@ void gimbal_axis(Object *ob, float gmat[][3])
 {
        if(ob->mode & OB_MODE_POSE)
        {
-               bPoseChannel *pchan= NULL;
+               bPoseChannel *pchan= get_active_posechannel(ob);
 
-               /* use channels to get stats */
-               for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
-                       if (pchan->bone && pchan->bone->flag & BONE_ACTIVE) {
-                               if(test_rotmode_euler(pchan->rotmode)) {
-                                       break;
-                               }
-                       }
-               }
-
-               if(pchan) {
+               if(pchan && test_rotmode_euler(pchan->rotmode)) {
                        float mat[3][3], tmat[3][3], obmat[3][3];
 
                        EulToGimbalAxis(mat, pchan->eul, pchan->rotmode);
index d3e611178fec477b3b64b48cee9cbce1caac9258..7dd90a3cf138cd4dc26c41b4bac76bd526212d2a 100644 (file)
@@ -78,6 +78,9 @@ typedef struct bArmature {
        ListBase        chainbase;
        ListBase        *edbo;                                  /* editbone listbase, we use pointer so we can check state */
        
+       Bone            *act_bone;
+       void            *act_edbone;
+
        void            *sketch;                                /* sketch struct for etch-a-ton */
        
        int                     flag;
@@ -154,7 +157,7 @@ typedef enum eBone_Flag {
        /* 32 used to be quatrot, was always set in files, do not reuse unless you clear it always */   
        BONE_HIDDEN_P                           = (1<<6),       /* hidden Bones when drawing PoseChannels */    
        BONE_DONE                                       = (1<<7),       /* For detecting cyclic dependancies */
-       BONE_ACTIVE                                     = (1<<8),       /* active is on mouse clicks only */
+       BONE_DRAW_ACTIVE                        = (1<<8),       /* active is on mouse clicks only - deprecated, ONLY USE FOR DRAWING */
        BONE_HINGE                                      = (1<<9),       /* No parent rotation or scale */
        BONE_HIDDEN_A                           = (1<<10),      /* hidden Bones when drawing Armature Editmode */
        BONE_MULT_VG_ENV                        = (1<<11),      /* multiplies vgroup with envelope */
index 96dde18626053e2b4983ea66e2bd7bc915ed0935..7d88745779d2f4efac8bf9fd9814f9dd0334e0ea 100644 (file)
@@ -56,6 +56,44 @@ static void rna_Armature_update_data(bContext *C, PointerRNA *ptr)
        //WM_event_add_notifier(C, NC_OBJECT|ND_POSE, NULL);
 }
 
+
+static void rna_Armature_act_bone_set(PointerRNA *ptr, PointerRNA value)
+{
+       bArmature *arm= (bArmature*)ptr->data;
+
+       if(value.id.data==NULL && value.data==NULL) {
+               arm->act_bone= NULL;
+       }
+       else {
+               if(value.id.data != arm) {
+                       /* raise an error! */
+               }
+               else {
+                       arm->act_bone= value.data;
+                       arm->act_bone->flag |= BONE_SELECTED;
+               }
+       }
+}
+
+static void rna_Armature_act_edit_bone_set(PointerRNA *ptr, PointerRNA value)
+{
+       bArmature *arm= (bArmature*)ptr->data;
+
+       if(value.id.data==NULL && value.data==NULL) {
+               arm->act_edbone= NULL;
+       }
+       else {
+               if(value.id.data != arm) {
+                       /* raise an error! */
+               }
+               else {
+                       arm->act_edbone= value.data;
+                       ((EditBone *)arm->act_edbone)->flag |= BONE_SELECTED;
+               }
+       }
+}
+
+
 static void rna_Armature_redraw_data(bContext *C, PointerRNA *ptr)
 {
        ID *id= ptr->id.data;
@@ -371,11 +409,6 @@ static void rna_def_bone_common(StructRNA *srna, int editbone)
        RNA_def_property_ui_text(prop, "Connected", "When bone has a parent, bone's head is struck to the parent's tail.");
        RNA_def_property_update(prop, 0, "rna_Armature_update_data");
        
-       prop= RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE);
-       RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_ACTIVE);
-       RNA_def_property_ui_text(prop, "Active", "Bone was the last bone clicked on (most operations are applied to only this bone)");
-       RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
-       
        prop= RNA_def_property(srna, "hinge", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", BONE_HINGE);
        RNA_def_property_ui_text(prop, "Inherit Rotation", "Bone doesn't inherit rotation or scale from parent bone.");
@@ -593,7 +626,7 @@ static void rna_def_edit_bone(BlenderRNA *brna)
 static void rna_def_armature(BlenderRNA *brna)
 {
        StructRNA *srna;
-       PropertyRNA *prop;
+       PropertyRNA *prop, *prop_act;
        
        static EnumPropertyItem prop_drawtype_items[] = {
                {ARM_OCTA, "OCTAHEDRAL", 0, "Octahedral", "Display bones as octahedral shape (default)."},
@@ -634,11 +667,34 @@ static void rna_def_armature(BlenderRNA *brna)
        RNA_def_property_struct_type(prop, "Bone");
        RNA_def_property_ui_text(prop, "Bones", "");
 
+       { /* Collection active property */
+               prop_act= RNA_def_property(srna, "bones_active", PROP_POINTER, PROP_NONE);
+               RNA_def_property_struct_type(prop_act, "Bone");
+               RNA_def_property_pointer_sdna(prop_act, NULL, "act_bone");
+               RNA_def_property_flag(prop_act, PROP_EDITABLE);
+               RNA_def_property_ui_text(prop_act, "Active Bone", "Armatures active bone.");
+               RNA_def_property_pointer_funcs(prop_act, NULL, "rna_Armature_act_bone_set", NULL);
+
+               /* todo, redraw */
+               RNA_def_property_collection_active(prop, prop_act);
+       }
+
        prop= RNA_def_property(srna, "edit_bones", PROP_COLLECTION, PROP_NONE);
        RNA_def_property_collection_sdna(prop, NULL, "edbo", NULL);
        RNA_def_property_struct_type(prop, "EditBone");
        RNA_def_property_ui_text(prop, "Edit Bones", "");
        
+       { /* Collection active property */
+               prop_act= RNA_def_property(srna, "edit_bones_active", PROP_POINTER, PROP_NONE);
+               RNA_def_property_struct_type(prop_act, "EditBone");
+               RNA_def_property_pointer_sdna(prop_act, NULL, "act_edbone");
+               RNA_def_property_flag(prop_act, PROP_EDITABLE);
+               RNA_def_property_ui_text(prop_act, "Active EditBone", "Armatures active edit bone.");
+               //RNA_def_property_update(prop_act, 0, "rna_Armature_act_editbone_update");
+               RNA_def_property_pointer_funcs(prop_act, NULL, "rna_Armature_act_edit_bone_set", NULL);
+               RNA_def_property_collection_active(prop, prop_act);
+       }
+
        /* Enum values */
 //     prop= RNA_def_property(srna, "rest_position", PROP_BOOLEAN, PROP_NONE);
 //     RNA_def_property_boolean_sdna(prop, NULL, "flag", ARM_RESTPOS);
index 9a9161b080f81d931a3b309d3d1cbd03125f50ad..71e91735b24b1161543627826af7e5f2f440978b 100644 (file)
@@ -180,10 +180,10 @@ int BL_ArmatureChannel::py_attr_setattr(void *self_v, const struct KX_PYATTRIBUT
        bPoseChannel* channel = self->m_posechannel;
        int attr_order = attrdef-Attributes;
 
-       int ival;
-       double dval;
-       char* sval;
-       KX_GameObject *oval;
+//     int ival;
+//     double dval;
+//     char* sval;
+//     KX_GameObject *oval;
 
        if (!channel) {
                PyErr_SetString(PyExc_AttributeError, "channel is NULL");
index db32f18f63b77e8836544522a1071e64ea33f3b7..2b3838d4dfe6e48daa5ca3a6844b93e912a9f0e1 100644 (file)
@@ -1818,7 +1818,7 @@ bPoseChannel *get_active_posechannel2 (Object *ob)
        
        /* find active */
        for(pchan= (bPoseChannel *)ob->pose->chanbase.first; pchan; pchan= pchan->next) {
-               if(pchan->bone && (pchan->bone->flag & BONE_ACTIVE) && (pchan->bone->layer & arm->layer))
+               if(pchan->bone && (pchan->bone == arm->act_bone) && (pchan->bone->layer & arm->layer))
                        return pchan;
        }