== Action/Pose Groups - Keyframing Integration ==
authorJoshua Leung <aligorith@gmail.com>
Mon, 21 Jan 2008 11:26:24 +0000 (11:26 +0000)
committerJoshua Leung <aligorith@gmail.com>
Mon, 21 Jan 2008 11:26:24 +0000 (11:26 +0000)
Now, when inserting keyframes (either IKEY or AutoKeying), if an ActionChannel has been newly created, it will get assigned to an Action-Group with the same name as the Bone-Group that the bone it represents belongs to.

source/blender/include/BIF_editaction.h
source/blender/src/buttons_editing.c
source/blender/src/editaction.c
source/blender/src/editipo.c
source/blender/src/poseobject.c

index b3e402daa3005b546322692081f5541a8196446b..2f105dccf72950d7dbd22097d290b2b99228635d 100644 (file)
@@ -108,6 +108,7 @@ enum {
 struct bAction;
 struct bActionChannel;
 struct bActionGroup;
+struct bPose;
 struct bPoseChannel;
 struct Object;
 struct Ipo;
@@ -142,8 +143,7 @@ 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 unique_name_actiongroup(struct ListBase *lb, struct bActionGroup *agrp);
-// <--- add some func to add group for action-channel based on corresponding pchan's grouping 
+void verify_pchan2achan_grouping(struct bAction *act, struct bPose *pose, char name[]); 
 void action_groups_group(short add_group);
 void action_groups_ungroup(void);
 
index 3be7bd6cd529fc82ade49faa15c5f36fa0318b04..6bcb4319d2a9028becf755db24fff475df407594 100644 (file)
@@ -3853,6 +3853,8 @@ void do_armbuts(unsigned short event)
                        }
                }
                break;
+               
+       // TODO: make these pose-group options proper tools in poseobject.c
        case B_POSEGRP_RECALC:
                allqueue(REDRAWVIEW3D, 0);
                allqueue(REDRAWBUTSEDIT, 0);
@@ -3879,6 +3881,7 @@ void do_armbuts(unsigned short event)
                        bPose *pose= ob->pose;
                        bActionGroup *grp= NULL;
                        
+                       // FIXME: make sure all that referenced it get reset 
                        grp= BLI_findlink(&pose->agroups, pose->active_group-1);
                        if (grp) {
                                BLI_freelinkN(&pose->agroups, grp);
@@ -4330,7 +4333,7 @@ static char *build_posegroups_menustr(bPose *pose)
        
        /* add title first (and the "none" entry) */
        BLI_dynstr_append(pupds, "Pose Group%t|");
-       BLI_dynstr_append(pupds, "BG: [None]%x0");
+       BLI_dynstr_append(pupds, "BG: [None]%x0|");
        
        /* loop through markers, adding them */
        for (agrp= pose->agroups.first, i=1; agrp; agrp=agrp->next, i++) {
@@ -4386,7 +4389,7 @@ static void editing_panel_pose_bones(Object *ob, bArmature *arm)
                        
                        /* Bone custom drawing */
                        menustr= build_posegroups_menustr(ob->pose);
-                       uiDefButS(block, MENU,REDRAWVIEW3D, menustr, 107,by,105,19, &pchan->agrp_index, 0.0, 0.0, 0.0, 0.0, "Change the Pose Group this Bone belongs to");
+                       uiDefButS(block, MENU,REDRAWVIEW3D, menustr, 107,by,105,19, &pchan->agrp_index, 0, 0.0, 0.0, 0.0, "Change the Pose Group this Bone belongs to");
                        MEM_freeN(menustr);
                        
                        ob_arm_bone_pchan_lock(ob, arm, curBone, pchan);
index cb436e8bff167d4a385df2df68e82cc2f9709b88..3d97cac3164395c4a70ae4d8586ea2e1fe680480 100644 (file)
@@ -812,6 +812,17 @@ static void action_groups_addachan (bAction *act, bActionGroup *agrp, bActionCha
        if (ELEM3(NULL, act, agrp, achan))
                return;
        
+       /* if no channels, just add to two lists at the same time */
+       if (act->chanbase.first == NULL) {
+               achan->next = achan->prev = NULL;
+               
+               agrp->channels.first = agrp->channels.last = achan;
+               act->chanbase.first = act->chanbase.last = achan;
+               
+               achan->grp= agrp;
+               return;
+       }
+       
        /* try to find a channel to slot this in before/after */
        for (chan= act->chanbase.first; chan; chan= chan->next) {
                /* if channel has no group, then we have ungrouped channels, which should always occur after groups */
@@ -1025,6 +1036,59 @@ void action_groups_ungroup (void)
        allqueue(REDRAWACTION, 0);
 }
 
+/* This function is used when inserting keyframes for pose-channels. It assigns the
+ * action-channel with the nominated name to a group with the same name as that of 
+ * the pose-channel with the nominated name.
+ *
+ * Note: this function calls validate_action_channel if action channel doesn't exist 
+ */
+void verify_pchan2achan_grouping (bAction *act, bPose *pose, char name[])
+{
+       bActionChannel *achan;
+       bPoseChannel *pchan;
+       
+       /* sanity checks */
+       if (ELEM3(NULL, act, pose, name))
+               return;
+       if (name[0] == 0)
+               return;
+               
+       /* try to get the channels */
+       pchan= get_pose_channel(pose, name);
+       if (pchan == NULL) return;
+       achan= verify_action_channel(act, name);
+       
+       /* check if pchan has a group */
+       if ((pchan->agrp_index) && (achan->grp == NULL)) {
+               bActionGroup *agrp, *grp=NULL;
+               
+               /* get group to try to be like */
+               agrp= (bActionGroup *)BLI_findlink(&pose->agroups, (pchan->agrp_index - 1));
+               if (agrp == NULL) {
+                       error("PoseChannel has invalid group!");
+                       return;
+               }
+               
+               /* try to find a group which is similar to the one we want (or add one) */
+               for (grp= act->groups.first; grp; grp= grp->next) {
+                       if (!strcmp(grp->name, agrp->name))
+                               break;
+               }
+               if (grp == NULL) {
+                       grp= MEM_callocN(sizeof(bActionGroup), "bActionGroup");
+                       
+                       grp->flag |= (AGRP_ACTIVE|AGRP_SELECTED|AGRP_EXPANDED);
+                       sprintf(grp->name, agrp->name);
+                       
+                       BLI_addtail(&act->groups, grp);
+               }
+               
+               /* make sure this channel is definitely not connected to anything before adding to group */
+               action_groups_removeachan(act, achan);
+               action_groups_addachan(act, grp, achan);
+       }
+}
+
 /* **************************************************** */
 /* TRANSFORM TOOLS */
 
index 612d9f59b9252e3fe9a7346da2af66a48731bf43..c8e1ae4a3cda7f987fbe7085d17d69d5a45b13ab 100644 (file)
@@ -1802,6 +1802,10 @@ Ipo *verify_ipo(ID *from, short blocktype, char *actname, char *constname, char
                achan= verify_action_channel(ob->action, actname);
                
                if(achan) {
+                       /* automatically assign achan to act-group based on pchan's grouping */
+                       if (blocktype == ID_PO)
+                       verify_pchan2achan_grouping(ob->action, ob->pose, actname);
+                       
                        /* constraint exception */
                        if(blocktype==ID_CO) {
                                bConstraintChannel *conchan= verify_constraint_channel(&achan->constraintChannels, constname);
index cdcb86af23927092e48bff856175ed66f0a5fd93..1a085e19be31ac88c2ecb43c06f7a8ae3423c697 100644 (file)
@@ -909,6 +909,15 @@ void pose_adds_vgroups(Object *meshobj, int heatweights)
 
 /* ********************************************** */
 
+/* adds a new pose-group */
+// TODO... 
+void pose_add_posegroup ()
+{
+
+}
+
+/* ********************************************** */
+
 /* context active object */
 void pose_flip_names(void)
 {