remove unused includes
[blender.git] / source / blender / editors / armature / poselib.c
index c332a297e57617b5d6593b82bae576f23584cb71..756dee2494be7f358becd2a2727831d391c77e89 100644 (file)
@@ -15,7 +15,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  *
  * The Original Code is Copyright (C) 2007, Blender Foundation
  * This is a new part of Blender
 
 #include "MEM_guardedalloc.h"
 
-#include "BLI_arithb.h"
+#include "BLI_math.h"
 #include "BLI_blenlib.h"
 #include "BLI_dynstr.h"
 #include "BLI_dlrbTree.h"
 
-#include "DNA_listBase.h"
 #include "DNA_anim_types.h"
-#include "DNA_action_types.h"
 #include "DNA_armature_types.h"
-#include "DNA_curve_types.h"
-#include "DNA_ipo_types.h"
 #include "DNA_object_types.h"
-#include "DNA_object_force.h"
 #include "DNA_scene_types.h"
-#include "DNA_userdef_types.h"
 
 #include "BKE_animsys.h"
 #include "BKE_action.h"
 #include "BKE_armature.h"
 #include "BKE_depsgraph.h"
-#include "BKE_modifier.h"
-#include "BKE_object.h"
 
-#include "BKE_global.h"
 #include "BKE_context.h"
 #include "BKE_report.h"
-#include "BKE_utildefines.h"
-
-#include "PIL_time.h"                  /* sleep                                */
 
 #include "RNA_access.h"
 #include "RNA_define.h"
-#include "RNA_types.h"
+#include "RNA_enum_types.h"
 
 #include "WM_api.h"
 #include "WM_types.h"
@@ -85,9 +73,6 @@
 
 /* ******* XXX ********** */
 
-static void BIF_undo_push() {}
-static void error() {}
-
 static void action_set_activemarker() {}
 
 /* ************************************************************* */
@@ -223,7 +208,7 @@ void poselib_validate_act (bAction *act)
        
        /* validate action and poselib */
        if (act == NULL)  {
-               error("No Action to validate");
+               //error("No Action to validate");
                return;
        }
        
@@ -235,6 +220,7 @@ void poselib_validate_act (bAction *act)
        /* for each key, make sure there is a correspnding pose */
        for (ak= keys.first; ak; ak= ak->next) {
                /* check if any pose matches this */
+               // TODO: don't go looking through the list like this every time...
                for (marker= act->markers.first; marker; marker= marker->next) {
                        if (IS_EQ(marker->frame, ak->cfra)) {
                                marker->flag = -1;
@@ -272,7 +258,7 @@ void poselib_validate_act (bAction *act)
        /* free temp memory */
        BLI_freelistN((ListBase *)&keys);
        
-       BIF_undo_push("PoseLib Validate Action");
+       //BIF_undo_push("PoseLib Validate Action");
 }
 
 /* ************************************************************* */
@@ -288,6 +274,9 @@ static void poselib_add_menu_invoke__replacemenu (bContext *C, uiLayout *layout,
        bAction *act= ob->poselib;
        TimeMarker *marker;
        
+       /* set the operator execution context correctly */
+       uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT);
+       
        /* add each marker to this menu */
        for (marker= act->markers.first; marker; marker= marker->next)
                uiItemIntO(layout, marker->name, ICON_ARMATURE_DATA, "POSELIB_OT_pose_add", "frame", marker->frame);
@@ -336,14 +325,10 @@ static int poselib_add_exec (bContext *C, wmOperator *op)
        bAction *act = poselib_validate(ob);
        bArmature *arm= (ob) ? ob->data : NULL;
        bPose *pose= (ob) ? ob->pose : NULL;
-       bPoseChannel *pchan;
        TimeMarker *marker;
        int frame= RNA_int_get(op->ptr, "frame");
        char name[64];
        
-       bCommonKeySrc cks;
-       ListBase dsources = {&cks, &cks};
-       
        /* sanity check (invoke should have checked this anyway) */
        if (ELEM3(NULL, ob, arm, pose)) 
                return OPERATOR_CANCELLED;
@@ -371,27 +356,14 @@ static int poselib_add_exec (bContext *C, wmOperator *op)
        }
        
        /* validate name */
-       BLI_uniquename(&act->markers, marker, "Pose", '.', offsetof(TimeMarker, name), 64);
-       
-       /* init common-key-source for use by KeyingSets */
-       memset(&cks, 0, sizeof(bCommonKeySrc));
-       cks.id= &ob->id;
-       
-       /* loop through selected posechannels, keying their pose to the action */
-       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)) {
-                               /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */
-                               cks.pchan= pchan;
-                               
-                               /* KeyingSet to use depends on rotation mode (but that's handled by the templates code)  */
-                               if (poselib_ks_locrotscale == NULL)
-                                       poselib_ks_locrotscale= ANIM_builtin_keyingset_get_named(NULL, "LocRotScale");
-                               modify_keyframes(C, &dsources, act, poselib_ks_locrotscale, MODIFYKEY_MODE_INSERT, (float)frame);
-                       }
-               }
-       }
+       BLI_uniquename(&act->markers, marker, "Pose", '.', offsetof(TimeMarker, name), sizeof(marker->name));
+       
+       /* KeyingSet to use depends on rotation mode (but that's handled by the templates code)  */
+       if (poselib_ks_locrotscale == NULL)
+               poselib_ks_locrotscale= ANIM_builtin_keyingset_get_named(NULL, "LocRotScale");
+               
+       /* make the keyingset use context info to determine where to add keyframes */
+       ANIM_apply_keyingset(C, NULL, act, poselib_ks_locrotscale, MODIFYKEY_MODE_INSERT, (float)frame);
        
        /* store new 'active' pose number */
        act->active_marker= BLI_countlist(&act->markers);
@@ -400,7 +372,6 @@ static int poselib_add_exec (bContext *C, wmOperator *op)
        return OPERATOR_FINISHED;
 }
 
-
 void POSELIB_OT_pose_add (wmOperatorType *ot)
 {
        /* identifiers */
@@ -423,35 +394,37 @@ void POSELIB_OT_pose_add (wmOperatorType *ot)
 
 /* ----- */
 
-static int poselib_stored_pose_menu_invoke (bContext *C, wmOperator *op, wmEvent *evt)
+static EnumPropertyItem *poselib_stored_pose_itemf(bContext *C, PointerRNA *ptr, int *free)
 {
        Object *ob= CTX_data_active_object(C);
        bAction *act= (ob) ? ob->poselib : NULL;
        TimeMarker *marker;
-       uiPopupMenu *pup;
-       uiLayout *layout;
-       int i;
-       
-       /* sanity check */
-       if (ELEM(NULL, ob, act)) 
-               return OPERATOR_CANCELLED;
-       
-       /* start building */
-       pup= uiPupMenuBegin(C, op->type->name, 0);
-       layout= uiPupMenuLayout(pup);
-       uiLayoutSetOperatorContext(layout, WM_OP_EXEC_DEFAULT);
-       
-       /* add each marker to this menu */
-       for (marker=act->markers.first, i=0; marker; marker= marker->next, i++)
-               uiItemIntO(layout, marker->name, ICON_ARMATURE_DATA, op->idname, "index", i);
-       
-       uiPupMenuEnd(C, pup);
+       EnumPropertyItem *item= NULL, item_tmp;
+       int totitem= 0;
+       int i= 0;
+
+       if (C==NULL) {
+               return DummyRNA_DEFAULT_items;
+       }
+
+       memset(&item_tmp, 0, sizeof(item_tmp));
        
-       /* this operator is only for a menu, not used further */
-       return OPERATOR_CANCELLED;
-}
+       /* check that the action exists */
+       if (act) {
+               /* add each marker to the list */
+               for (marker=act->markers.first, i=0; marker; marker= marker->next, i++) {
+                       item_tmp.identifier= item_tmp.name= marker->name;
+                       item_tmp.icon= ICON_ARMATURE_DATA;
+                       item_tmp.value= i;
+                       RNA_enum_item_add(&item, &totitem, &item_tmp);
+               }
+       }
 
+       RNA_enum_item_end(&item, &totitem);
+       *free= 1;
 
+       return item;
+}
 
 static int poselib_remove_exec (bContext *C, wmOperator *op)
 {
@@ -467,9 +440,10 @@ static int poselib_remove_exec (bContext *C, wmOperator *op)
        }
        
        /* get index (and pointer) of pose to remove */
-       marker= BLI_findlink(&act->markers, RNA_int_get(op->ptr, "index"));
+       marker= BLI_findlink(&act->markers, RNA_int_get(op->ptr, "pose"));
        if (marker == NULL) {
                BKE_report(op->reports, RPT_ERROR, "Invalid index for Pose");
+               return OPERATOR_CANCELLED;
        }
        
        /* remove relevant keyframes */
@@ -500,13 +474,15 @@ static int poselib_remove_exec (bContext *C, wmOperator *op)
 
 void POSELIB_OT_pose_remove (wmOperatorType *ot)
 {
+       PropertyRNA *prop;
+       
        /* identifiers */
        ot->name= "PoseLib Remove Pose";
        ot->idname= "POSELIB_OT_pose_remove";
        ot->description= "Remove nth pose from the active Pose Library";
        
        /* api callbacks */
-       ot->invoke= poselib_stored_pose_menu_invoke;
+       ot->invoke= WM_menu_invoke;
        ot->exec= poselib_remove_exec;
        ot->poll= ED_operator_posemode;
        
@@ -514,10 +490,38 @@ void POSELIB_OT_pose_remove (wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
        
        /* properties */
-       RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "The index of the pose to remove", 0, INT_MAX);
+       prop= RNA_def_enum(ot->srna, "pose", DummyRNA_DEFAULT_items, 0, "Pose", "The pose to remove");
+       RNA_def_enum_funcs(prop, poselib_stored_pose_itemf);
+       ot->prop= prop;
 }
 
-
+static int poselib_rename_invoke (bContext *C, wmOperator *op, wmEvent *evt)
+{
+       Object *ob= CTX_data_active_object(C);
+       bAction *act= (ob) ? ob->poselib : NULL;
+       TimeMarker *marker;
+       
+       /* check if valid poselib */
+       if (act == NULL) {
+               BKE_report(op->reports, RPT_ERROR, "Object doesn't have PoseLib data");
+               return OPERATOR_CANCELLED;
+       }
+       
+       /* get index (and pointer) of pose to remove */
+       marker= BLI_findlink(&act->markers, act->active_marker-1);
+       if (marker == NULL) {
+               BKE_report(op->reports, RPT_ERROR, "Invalid index for Pose");
+               return OPERATOR_CANCELLED;
+       }
+       else {
+               /* use the existing name of the marker as the name, and use the active marker as the one to rename */
+               RNA_enum_set(op->ptr, "pose", act->active_marker-1);
+               RNA_string_set(op->ptr, "name", marker->name);
+       }
+       
+       /* part to sync with other similar operators... */
+       return WM_operator_props_popup(C, op, evt);
+}
 
 static int poselib_rename_exec (bContext *C, wmOperator *op)
 {
@@ -533,9 +537,10 @@ static int poselib_rename_exec (bContext *C, wmOperator *op)
        }
        
        /* get index (and pointer) of pose to remove */
-       marker= BLI_findlink(&act->markers, RNA_int_get(op->ptr, "index"));
+       marker= BLI_findlink(&act->markers, RNA_int_get(op->ptr, "pose"));
        if (marker == NULL) {
                BKE_report(op->reports, RPT_ERROR, "Invalid index for Pose");
+               return OPERATOR_CANCELLED;
        }
        
        /* get new name */
@@ -543,7 +548,7 @@ static int poselib_rename_exec (bContext *C, wmOperator *op)
        
        /* copy name and validate it */
        BLI_strncpy(marker->name, newname, sizeof(marker->name));
-       BLI_uniquename(&act->markers, marker, "Pose", '.', offsetof(TimeMarker, name), 64);
+       BLI_uniquename(&act->markers, marker, "Pose", '.', offsetof(TimeMarker, name), sizeof(marker->name));
        
        /* done */
        return OPERATOR_FINISHED;
@@ -551,13 +556,18 @@ static int poselib_rename_exec (bContext *C, wmOperator *op)
 
 void POSELIB_OT_pose_rename (wmOperatorType *ot)
 {
+       PropertyRNA *prop;
+       static EnumPropertyItem prop_poses_dummy_types[] = {
+               {0, NULL, 0, NULL, NULL}
+       };
+       
        /* identifiers */
        ot->name= "PoseLib Rename Pose";
        ot->idname= "POSELIB_OT_pose_rename";
        ot->description= "Rename nth pose from the active Pose Library";
        
        /* api callbacks */
-       ot->invoke= poselib_stored_pose_menu_invoke;
+       ot->invoke= poselib_rename_invoke;
        ot->exec= poselib_rename_exec;
        ot->poll= ED_operator_posemode;
        
@@ -565,7 +575,8 @@ void POSELIB_OT_pose_rename (wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
        
        /* properties */
-       RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "The index of the pose to remove", 0, INT_MAX);
+       prop= RNA_def_enum(ot->srna, "pose", prop_poses_dummy_types, 0, "Pose", "The pose to rename");
+               RNA_def_enum_funcs(prop, poselib_stored_pose_itemf);
        RNA_def_string(ot->srna, "name", "RenamedPose", 64, "New Pose Name", "New name for pose");
 }
 
@@ -586,18 +597,18 @@ typedef struct tPoseLib_PreviewData {
        bAction *act;                   /* poselib to use */
        TimeMarker *marker;             /* 'active' pose */
        
-       short state;                    /* state of main loop */
-       short redraw;                   /* redraw/update settings during main loop */
-       short flag;                             /* flags for various settings */
-       
        int selcount;                   /* number of selected elements to work on */
        int totcount;                   /* total number of elements to work on */
        
-       char headerstr[200];    /* Info-text to print in header */
+       short state;                    /* state of main loop */
+       short redraw;                   /* redraw/update settings during main loop */
+       short flag;                             /* flags for various settings */
        
+       short search_cursor;    /* position of cursor in searchstr (cursor occurs before the item at the nominated index) */
        char searchstr[64];             /* (Part of) Name to search for to filter poses that get shown */
        char searchold[64];             /* Previously set searchstr (from last loop run), so that we can detected when to rebuild searchp */
-       short search_cursor;    /* position of cursor in searchstr (cursor occurs before the item at the nominated index) */
+       
+       char headerstr[200];    /* Info-text to print in header */
 } tPoseLib_PreviewData;
 
 /* defines for tPoseLib_PreviewData->state values */
@@ -689,8 +700,8 @@ static void poselib_apply_pose (tPoseLib_PreviewData *pld)
        bAction *act= pld->act;
        bActionGroup *agrp;
        
-       BeztEditData bed;
-       BeztEditFunc group_ok_cb;
+       KeyframeEditData ked;
+       KeyframeEditFunc group_ok_cb;
        int frame= 1;
        
        /* get the frame */
@@ -702,15 +713,15 @@ static void poselib_apply_pose (tPoseLib_PreviewData *pld)
        
        /* init settings for testing groups for keyframes */
        group_ok_cb= ANIM_editkeyframes_ok(BEZT_OK_FRAMERANGE);
-       memset(&bed, 0, sizeof(BeztEditData)); 
-       bed.f1= ((float)frame) - 0.5f;
-       bed.f2= ((float)frame) + 0.5f;
+       memset(&ked, 0, sizeof(KeyframeEditData)); 
+       ked.f1= ((float)frame) - 0.5f;
+       ked.f2= ((float)frame) + 0.5f;
        
        
        /* start applying - only those channels which have a key at this point in time! */
        for (agrp= act->groups.first; agrp; agrp= agrp->next) {
                /* check if group has any keyframes */
-               if (ANIM_animchanneldata_keys_bezier_loop(&bed, agrp, ALE_GROUP, NULL, group_ok_cb, NULL, 0)) {
+               if (ANIM_animchanneldata_keyframes_loop(&ked, agrp, ALE_GROUP, NULL, group_ok_cb, NULL, 0)) {
                        /* has keyframe on this frame, so try to get a PoseChannel with this name */
                        pchan= get_pose_channel(pose, agrp->name);
                        
@@ -724,7 +735,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;
@@ -745,13 +756,6 @@ static void poselib_keytag_pose (bContext *C, Scene *scene, tPoseLib_PreviewData
        bAction *act= pld->act;
        bActionGroup *agrp;
        
-       bCommonKeySrc cks;
-       ListBase dsources = {&cks, &cks};
-       
-       /* init common-key-source for use by KeyingSets */
-       memset(&cks, 0, sizeof(bCommonKeySrc));
-       cks.id= &pld->ob->id;
-       
        /* start tagging/keying */
        for (agrp= act->groups.first; agrp; agrp= agrp->next) {
                /* only for selected action channels */
@@ -759,17 +763,30 @@ static void poselib_keytag_pose (bContext *C, Scene *scene, tPoseLib_PreviewData
                        pchan= get_pose_channel(pose, agrp->name);
                        
                        if (pchan) {
-                               // TODO: use a standard autokeying function in future (to allow autokeying-editkeys to work)
-                               if (IS_AUTOKEY_MODE(scene, NORMAL)) {
-                                       /* Set keys on pose
-                                        *      - KeyingSet to use depends on rotation mode 
-                                        *      (but that's handled by the templates code)  
+                               if (autokeyframe_cfra_can_key(scene, &pld->ob->id)) {
+                                       ListBase dsources = {NULL, NULL};
+                                       KeyingSet *ks = NULL;
+                                       
+                                       /* get KeyingSet to use 
+                                        *      - use the active KeyingSet if defined (and user wants to use it for all autokeying), 
+                                        *        or otherwise key transforms only
                                         */
-                                       // TODO: for getting the KeyingSet used, we should really check which channels were affected
                                        if (poselib_ks_locrotscale == NULL)
                                                poselib_ks_locrotscale= ANIM_builtin_keyingset_get_named(NULL, "LocRotScale");
+                                        
+                                       if (IS_AUTOKEY_FLAG(ONLYKEYINGSET) && (scene->active_keyingset))
+                                               ks = ANIM_scene_get_active_keyingset(scene);
+                                       else 
+                                               ks = ANIM_builtin_keyingset_get_named(NULL, "LocRotScale");
                                        
-                                       modify_keyframes(C, &dsources, NULL, poselib_ks_locrotscale, MODIFYKEY_MODE_INSERT, (float)CFRA);
+                                       /* now insert the keyframe(s) using the Keying Set
+                                        *      1) add datasource override for the PoseChannel
+                                        *      2) insert keyframes
+                                        *      3) free the extra info 
+                                        */
+                                       ANIM_relative_keyingset_add_source(&dsources, &pld->ob->id, &RNA_PoseBone, pchan); 
+                                       ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA);
+                                       BLI_freelistN(&dsources);
                                        
                                        /* clear any unkeyed tags */
                                        if (pchan->bone)
@@ -780,10 +797,12 @@ static void poselib_keytag_pose (bContext *C, Scene *scene, tPoseLib_PreviewData
                                        if (pchan->bone)
                                                pchan->bone->flag |= BONE_UNKEYED;
                                }
-               
                        }
                }
        }
+       
+       /* send notifiers for this */
+       WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|NA_EDITED, NULL);
 }
 
 /* Apply the relevant changes to the pose */
@@ -831,7 +850,7 @@ static void poselib_preview_apply (bContext *C, wmOperator *op)
                        /* get search-string */
                        index= pld->search_cursor;
                        
-                       if (IN_RANGE(index, 0, 64)) {
+                       if (index >= 0 && index <= 64) {
                                memcpy(&tempstr[0], &pld->searchstr[0], index);
                                tempstr[index]= '|';
                                memcpy(&tempstr[index+1], &pld->searchstr[index], 64-index);
@@ -856,7 +875,7 @@ static void poselib_preview_apply (bContext *C, wmOperator *op)
        }
        
        /* request drawing of view + clear redraw flag */
-       WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM|ND_POSE, pld->ob);
+       WM_event_add_notifier(C, NC_OBJECT|ND_POSE, pld->ob);
        pld->redraw= PL_PREVIEW_NOREDRAW;
 }
 
@@ -1258,7 +1277,8 @@ static void poselib_preview_init_data (bContext *C, wmOperator *op)
                if (pld->act->markers.first) {
                        /* just use first one then... */
                        pld->marker= pld->act->markers.first;
-                       if (pose_index > -2) printf("PoseLib had no active pose\n");
+                       if (pose_index > -2) 
+                               BKE_report(op->reports, RPT_WARNING, "PoseLib had no active pose");
                }
                else {
                        BKE_report(op->reports, RPT_ERROR, "PoseLib has no poses to preview/apply");
@@ -1411,7 +1431,7 @@ static int poselib_preview_invoke(bContext *C, wmOperator *op, wmEvent *event)
        poselib_preview_apply(C, op);
        
        /* add temp handler if we're running as a modal operator */
-       WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+       WM_event_add_modal_handler(C, op);
 
        return OPERATOR_RUNNING_MODAL;
 }
@@ -1464,5 +1484,8 @@ void POSELIB_OT_browse_interactive (wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
        
        /* properties */        
-       RNA_def_int(ot->srna, "pose_index", -1, -2, INT_MAX, "Pose", "Index of the pose to apply (-2 for no change to pose, -1 for poselib active pose)", 0, INT_MAX);
+               // TODO: make the pose_index into a proper enum instead of a cryptic int...
+       ot->prop= RNA_def_int(ot->srna, "pose_index", -1, -2, INT_MAX, "Pose", "Index of the pose to apply (-2 for no change to pose, -1 for poselib active pose)", 0, INT_MAX);
+               // XXX: percentage vs factor?
+       RNA_def_float_factor(ot->srna, "blend_factor", 1.0f, 0.0f, 1.0f, "Blend Factor", "Amount that the pose is applied on top of the existing poses", 0.0f, 1.0f);
 }