== Action Editor - Action Groups finishing touches ==
* Added a new tool "Synchronise with Armature" (found under Channels->Grouping), which synchronises the grouping of action-channels and the grouping of their relevant bones. This only works when the active object is an armature, and the action isn't pinned. All of the action's action-channels are removed from their groups, and are added back into groups according to the current grouping of their corresponding bones. A bit of testing for weird cases is needed. * Group colours are now not drawn if the group originally was using the 'default' colour-set.
This commit is contained in:
@@ -141,7 +141,8 @@ void paste_actdata(void);
|
||||
/* Group/Channel Operations */
|
||||
struct bActionGroup *get_active_actiongroup(struct bAction *act);
|
||||
void set_active_actiongroup(struct bAction *act, struct bActionGroup *agrp, short select);
|
||||
void verify_pchan2achan_grouping(struct bAction *act, struct bPose *pose, char name[]);
|
||||
void verify_pchan2achan_grouping(struct bAction *act, struct bPose *pose, char name[]);
|
||||
void sync_pchan2achan_grouping(void);
|
||||
void action_groups_group(short add_group);
|
||||
void action_groups_ungroup(void);
|
||||
|
||||
|
||||
@@ -635,9 +635,11 @@ static void draw_channel_names(void)
|
||||
else {
|
||||
/* for normal channels
|
||||
* - use 3 shades of color group/standard colour for 3 indention level
|
||||
* - use standard colour if enabled
|
||||
* - only use group colors if allowed to, and if actually feasible
|
||||
*/
|
||||
if ((G.saction->flag & SACTION_DRAWGCOLORS) && (grp)) {
|
||||
if ( (G.saction->flag & SACTION_DRAWGCOLORS) &&
|
||||
(grp) && (grp->customCol) )
|
||||
{
|
||||
char cp[3];
|
||||
|
||||
if (indent == 2) {
|
||||
|
||||
@@ -1178,6 +1178,7 @@ void verify_pchan2achan_grouping (bAction *act, bPose *pose, char name[])
|
||||
}
|
||||
}
|
||||
}
|
||||
grp->customCol= agrp->customCol;
|
||||
|
||||
BLI_addtail(&act->groups, grp);
|
||||
}
|
||||
@@ -1188,6 +1189,50 @@ void verify_pchan2achan_grouping (bAction *act, bPose *pose, char name[])
|
||||
}
|
||||
}
|
||||
|
||||
/* This function is used when the user specifically requests to sync changes of pchans + bone groups
|
||||
* to achans + action groups. All achans are detached from their groups, and all groups are destroyed.
|
||||
* They are then recreated when the achans are reassigned to groups.
|
||||
*
|
||||
* Note: This doesn't preserve hand-created groups, and will operate on ALL action-channels regardless of
|
||||
* whether they were selected or active. More specific filtering can be added later.
|
||||
*/
|
||||
void sync_pchan2achan_grouping ()
|
||||
{
|
||||
void *data;
|
||||
short datatype;
|
||||
bAction *act;
|
||||
bActionChannel *achan, *next, *last;
|
||||
bPose *pose;
|
||||
|
||||
/* determine what type of data we are operating on */
|
||||
data = get_action_context(&datatype);
|
||||
if ((datatype != ACTCONT_ACTION) || (data==NULL)) return;
|
||||
if ((G.saction->pin) || (OBACT==NULL) || (OBACT->type != OB_ARMATURE)) {
|
||||
error("Action doesn't belong to active armature");
|
||||
return;
|
||||
}
|
||||
|
||||
/* get data */
|
||||
act= (bAction *)data;
|
||||
pose= OBACT->pose;
|
||||
|
||||
/* remove achan->group links, then delete all groups */
|
||||
for (achan= act->chanbase.first; achan; achan= achan->next)
|
||||
achan->grp = NULL;
|
||||
BLI_freelistN(&act->groups);
|
||||
|
||||
/* loop through all achans, reassigning them to groups (colours are resyncronised) */
|
||||
last= act->chanbase.last;
|
||||
for (achan= act->chanbase.first; achan && achan!=last; achan= next) {
|
||||
next= achan->next;
|
||||
verify_pchan2achan_grouping(act, pose, achan->name);
|
||||
}
|
||||
|
||||
/* undo and redraw */
|
||||
BIF_undo_push("Sync Armature-Data and Action");
|
||||
allqueue(REDRAWACTION, 0);
|
||||
}
|
||||
|
||||
/* **************************************************** */
|
||||
/* TRANSFORM TOOLS */
|
||||
|
||||
|
||||
@@ -136,7 +136,8 @@ enum {
|
||||
enum {
|
||||
ACTMENU_CHANNELS_GROUP_ADD_TOACTIVE = 0,
|
||||
ACTMENU_CHANNELS_GROUP_ADD_TONEW,
|
||||
ACTMENU_CHANNELS_GROUP_REMOVE
|
||||
ACTMENU_CHANNELS_GROUP_REMOVE,
|
||||
ACTMENU_CHANNELS_GROUP_SYNCPOSE
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -762,6 +763,9 @@ static void do_action_channelmenu_groupmenu(void *arg, int event)
|
||||
case ACTMENU_CHANNELS_GROUP_REMOVE:
|
||||
action_groups_ungroup();
|
||||
break;
|
||||
case ACTMENU_CHANNELS_GROUP_SYNCPOSE: /* Syncronise Pose-data and Action-data */
|
||||
sync_pchan2achan_grouping();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -782,7 +786,7 @@ static uiBlock *action_channelmenu_groupmenu(void *arg_unused)
|
||||
"Add to New Group|Ctrl Shift G", 0, yco-=20,
|
||||
menuwidth, 19, NULL, 0.0, 0.0, 0,
|
||||
ACTMENU_CHANNELS_GROUP_ADD_TONEW, "");
|
||||
|
||||
|
||||
uiDefBut(block, SEPR, 0, "", 0, yco-=6,
|
||||
menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
|
||||
|
||||
@@ -790,6 +794,14 @@ static uiBlock *action_channelmenu_groupmenu(void *arg_unused)
|
||||
"Remove From Group|Alt G", 0, yco-=20,
|
||||
menuwidth, 19, NULL, 0.0, 0.0, 0,
|
||||
ACTMENU_CHANNELS_GROUP_REMOVE, "");
|
||||
|
||||
uiDefBut(block, SEPR, 0, "", 0, yco-=6,
|
||||
menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
|
||||
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
|
||||
"Synchronise with Armature", 0, yco-=20,
|
||||
menuwidth, 19, NULL, 0.0, 0.0, 0,
|
||||
ACTMENU_CHANNELS_GROUP_SYNCPOSE, "");
|
||||
|
||||
uiBlockSetDirection(block, UI_RIGHT);
|
||||
uiTextBoundsBlock(block, 60);
|
||||
|
||||
Reference in New Issue
Block a user