Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2009-11-10 00:03:54 +0300
committerCampbell Barton <ideasman42@gmail.com>2009-11-10 00:03:54 +0300
commit5935ef004935b27fc5795349aed32f87cf637049 (patch)
treef36022abb03938420606405e9afc841b14d4bd81 /source/blender/editors/armature
parent3e2766bc2ee7523ea68caedc5b11e9498ddcbbc1 (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.h2
-rw-r--r--source/blender/editors/armature/editarmature.c294
-rw-r--r--source/blender/editors/armature/editarmature_retarget.c10
-rw-r--r--source/blender/editors/armature/poselib.c4
-rw-r--r--source/blender/editors/armature/poseobject.c54
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);