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.
This commit is contained in:
Campbell Barton 2009-11-09 21:03:54 +00:00
parent 3e2766bc2e
commit 5935ef0049
23 changed files with 392 additions and 290 deletions

@ -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;
}

@ -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;
}

@ -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 ***************** */

@ -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);
}

@ -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);

@ -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;
}

@ -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);
}

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

@ -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);

@ -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 */

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

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

@ -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;
}

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

@ -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);

@ -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 */

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

@ -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 */

@ -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);

@ -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 */

@ -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);

@ -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");

@ -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;
}