diff options
author | Campbell Barton <ideasman42@gmail.com> | 2009-11-10 00:03:54 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2009-11-10 00:03:54 +0300 |
commit | 5935ef004935b27fc5795349aed32f87cf637049 (patch) | |
tree | f36022abb03938420606405e9afc841b14d4bd81 /source/blender/editors/armature | |
parent | 3e2766bc2ee7523ea68caedc5b11e9498ddcbbc1 (diff) |
use armature active bone as a pointer rather then a flag for each bone that needs looking up.
- 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.
Diffstat (limited to 'source/blender/editors/armature')
-rw-r--r-- | source/blender/editors/armature/armature_intern.h | 2 | ||||
-rw-r--r-- | source/blender/editors/armature/editarmature.c | 294 | ||||
-rw-r--r-- | source/blender/editors/armature/editarmature_retarget.c | 10 | ||||
-rw-r--r-- | source/blender/editors/armature/poselib.c | 4 | ||||
-rw-r--r-- | source/blender/editors/armature/poseobject.c | 54 |
5 files changed, 213 insertions, 151 deletions
diff --git a/source/blender/editors/armature/armature_intern.h b/source/blender/editors/armature/armature_intern.h index d31a3bda332..012610bfd25 100644 --- a/source/blender/editors/armature/armature_intern.h +++ b/source/blender/editors/armature/armature_intern.h @@ -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); diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index c5b01f1cab0..6dad0b6e90f 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -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; } diff --git a/source/blender/editors/armature/editarmature_retarget.c b/source/blender/editors/armature/editarmature_retarget.c index 4d65059c4c6..824e7be94d9 100644 --- a/source/blender/editors/armature/editarmature_retarget.c +++ b/source/blender/editors/armature/editarmature_retarget.c @@ -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); } diff --git a/source/blender/editors/armature/poselib.c b/source/blender/editors/armature/poselib.c index f67c94eebc3..565a4782377 100644 --- a/source/blender/editors/armature/poselib.c +++ b/source/blender/editors/armature/poselib.c @@ -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; diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c index 696fa65b33a..d7741c2a5ef 100644 --- a/source/blender/editors/armature/poseobject.c +++ b/source/blender/editors/armature/poseobject.c @@ -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); |