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:
authorJoshua Leung <aligorith@gmail.com>2009-04-01 02:36:13 +0400
committerJoshua Leung <aligorith@gmail.com>2009-04-01 02:36:13 +0400
commit3a28a7450596f46281431bd163b9a237eb481055 (patch)
tree54268464f1adc33111b7bb3afde1ce1c64bf5897 /source/blender
parent4861ddf350e776c09f319d6db7fb96634d952da6 (diff)
Animato - Support for 'BuiltIn' and 'Relative' Keying Sets
When inserting keyframes in the 3D-View (support will be extended to other editors in due course) using the IKEY hotkey, the menu which appears will now consist of 3 parts: * 'Active Keying Set' - this option allows you to use the user-defined KeyingSet which is active for the current scene (i.e. the one seen in the TimeLine/Outliner headers) * User defined Keying Sets - a list of all such available KeyingSets is included, and entries can be chosen from there * Built-In Keying Sets - see later... To achieve this, several changes needed to be made first: * Added support for 'relative' in addition to 'absolute' Keying Sets. Relative Keying Sets are Keying Sets which operate on data from the current context (i.e. a 'location' KeyingSet will add location keyframes for selected objects/bones/nodes as opposed to location keyframes for some particular object). The is a tentative 'templates' requirement system here, which still needs to be fully fleshed out. * Added support for builtin Keying Sets (i.e. 'Location', 'Rotation', 'Scaling', and 'LocRot' as a few initial demonstrations), which replaces the temporary Insert Keyframe operator for the 3D-View (IKEY). These are effectively relative Keying Set definitions which are included in Blender by default and stored in a list separate from user-defined ones. Volunteer help in defining a few more of these for other editors will be welcome soon. * Removed/replaced much of the crappy temporary Keyframing operator code, though a few tweaks could still be done.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/BKE_constraint.h4
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c4
-rw-r--r--source/blender/blenkernel/intern/constraint.c24
-rw-r--r--source/blender/blenkernel/intern/fcurve.c11
-rw-r--r--source/blender/editors/animation/anim_ops.c5
-rw-r--r--source/blender/editors/animation/keyframing.c941
-rw-r--r--source/blender/editors/include/ED_keyframing.h10
-rw-r--r--source/blender/editors/object/object_ops.c2
-rw-r--r--source/blender/editors/space_outliner/outliner.c2
-rw-r--r--source/blender/makesdna/DNA_scene_types.h2
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c3
11 files changed, 560 insertions, 448 deletions
diff --git a/source/blender/blenkernel/BKE_constraint.h b/source/blender/blenkernel/BKE_constraint.h
index 0d8c81a5a75..6e69906b71d 100644
--- a/source/blender/blenkernel/BKE_constraint.h
+++ b/source/blender/blenkernel/BKE_constraint.h
@@ -110,11 +110,13 @@ bConstraintTypeInfo *get_constraint_typeinfo(int type);
/* Constraint function prototypes */
void unique_constraint_name(struct bConstraint *con, struct ListBase *list);
-void free_constraints(struct ListBase *conlist);
+void free_constraints(struct ListBase *list);
void copy_constraints(struct ListBase *dst, struct ListBase *src);
void relink_constraints(struct ListBase *list);
void free_constraint_data(struct bConstraint *con);
+struct bConstraint *constraints_get_active(struct ListBase *list);
+
/* Constraints + Proxies function prototypes */
void extract_proxylocal_constraints(struct ListBase *dst, struct ListBase *src);
short proxylocked_constraints_owner(struct Object *ob, struct bPoseChannel *pchan);
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 0097b30b685..ee72c374b5a 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -4,6 +4,7 @@
#include <stdio.h>
#include <string.h>
+#include <stddef.h>
#include "MEM_guardedalloc.h"
@@ -238,6 +239,9 @@ KeyingSet *BKE_keyingset_add (ListBase *list, const char name[], short flag, sho
/* add KeyingSet to list */
BLI_addtail(list, ks);
+ /* make sure KeyingSet has a unique name (this helps with identification) */
+ BLI_uniquename(list, ks, "Keying Set", offsetof(KeyingSet, name), 64);
+
/* return new KeyingSet for further editing */
return ks;
}
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index b238116f0a1..ed8562847a9 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -3203,17 +3203,16 @@ void free_constraint_data (bConstraint *con)
}
/* Free all constraints from a constraint-stack */
-void free_constraints (ListBase *conlist)
+void free_constraints (ListBase *list)
{
bConstraint *con;
/* Free constraint data and also any extra data */
- for (con= conlist->first; con; con= con->next) {
+ for (con= list->first; con; con= con->next)
free_constraint_data(con);
- }
/* Free the whole list */
- BLI_freelistN(conlist);
+ BLI_freelistN(list);
}
/* Reassign links that constraints have to other data (called during file loading?) */
@@ -3266,6 +3265,23 @@ void copy_constraints (ListBase *dst, ListBase *src)
}
}
+/* finds the 'active' constraint in a constraint stack */
+bConstraint *constraints_get_active (ListBase *list)
+{
+ bConstraint *con;
+
+ /* search for the first constraint with the 'active' flag set */
+ if (list) {
+ for (con= list->first; con; con= con->next) {
+ if (con->flag & CONSTRAINT_ACTIVE)
+ return con;
+ }
+ }
+
+ /* no active constraint found */
+ return NULL;
+}
+
/* -------- Constraints and Proxies ------- */
/* Rescue all constraints tagged as being CONSTRAINT_PROXY_LOCAL (i.e. added to bone that's proxy-synced in this file) */
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index 2dfa1db171f..3fa9457d86e 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -177,7 +177,7 @@ void calc_fcurve_bounds (FCurve *fcu, float *xmin, float *xmax, float *ymin, flo
float xminv=999999999.0f, xmaxv=-999999999.0f;
float yminv=999999999.0f, ymaxv=-999999999.0f;
short foundvert=0;
- int i;
+ unsigned int i;
if (fcu->totvert) {
if (fcu->bezt) {
@@ -418,7 +418,7 @@ void calchandles_fcurve (FCurve *fcu)
void testhandles_fcurve (FCurve *fcu)
{
BezTriple *bezt;
- int a;
+ unsigned int a;
/* only beztriples have handles (bpoints don't though) */
if ELEM(NULL, fcu, fcu->bezt)
@@ -475,7 +475,7 @@ void sort_time_fcurve (FCurve *fcu)
/* currently, will only be needed when there are beztriples */
if (fcu->bezt) {
BezTriple *bezt;
- int a;
+ unsigned int a;
/* loop over ALL points to adjust position in array and recalculate handles */
for (a=0, bezt=fcu->bezt; a < fcu->totvert; a++, bezt++) {
@@ -509,7 +509,7 @@ void sort_time_fcurve (FCurve *fcu)
/* This function tests if any BezTriples are out of order, thus requiring a sort */
short test_time_fcurve (FCurve *fcu)
{
- int a;
+ unsigned int a;
/* sanity checks */
if (fcu == NULL)
@@ -895,7 +895,8 @@ static float fcurve_eval_keyframes (FCurve *fcu, BezTriple *bezts, float evaltim
{
BezTriple *bezt, *prevbezt, *lastbezt;
float v1[2], v2[2], v3[2], v4[2], opl[32], dx, fac;
- int a, b;
+ unsigned int a;
+ int b;
float cvalue = 0.0f;
/* get pointers */
diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c
index f8c7cc909ae..15a4babf90a 100644
--- a/source/blender/editors/animation/anim_ops.c
+++ b/source/blender/editors/animation/anim_ops.c
@@ -380,8 +380,9 @@ void ED_operatortypes_anim(void)
// XXX this is used all over... maybe for screen instead?
WM_operatortype_append(ANIM_OT_insert_keyframe);
WM_operatortype_append(ANIM_OT_delete_keyframe);
- WM_operatortype_append(ANIM_OT_insert_keyframe_old);
- WM_operatortype_append(ANIM_OT_delete_keyframe_old);
+ WM_operatortype_append(ANIM_OT_insert_keyframe_menu);
+ //WM_operatortype_append(ANIM_OT_delete_keyframe_menu);
+ WM_operatortype_append(ANIM_OT_delete_keyframe_old); // xxx remove?
WM_operatortype_append(ANIM_OT_keyingset_add_new);
WM_operatortype_append(ANIM_OT_keyingset_add_destination);
diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c
index b04eaa0c378..0206de12c82 100644
--- a/source/blender/editors/animation/keyframing.c
+++ b/source/blender/editors/animation/keyframing.c
@@ -61,10 +61,10 @@ typedef struct bCommonKeySrc {
/* general data/destination-source settings */
ID *id; /* id-block this comes from */
- char *rna_path; /* base path to use */ // xxx.... maybe we don't need this?
/* specific cases */
- bPoseChannel *pchan; /* only needed when doing recalcs... */
+ bPoseChannel *pchan;
+ bConstraint *con;
} bCommonKeySrc;
/* ******************************************* */
@@ -867,7 +867,7 @@ short deletekey (ID *id, const char group[], const char rna_path[], int array_in
}
/* ******************************************* */
-/* KEYINGSETS */
+/* KEYING SETS - EDITING API */
/* Operators ------------------------------------------- */
@@ -1042,15 +1042,8 @@ char *ANIM_build_keyingsets_menu (ListBase *list, short for_edit)
}
-
/* ******************************************* */
-/* KEYFRAME MODIFICATION */
-
-/* mode for commonkey_modifykey */
-enum {
- COMMONKEY_MODE_INSERT = 0,
- COMMONKEY_MODE_DELETE,
-} eCommonModifyKey_Modes;
+/* KEYING SETS - BUILTIN */
#if 0 // XXX old keyingsets code based on adrcodes... to be restored in due course
@@ -1570,229 +1563,319 @@ typedef enum eKS_Contexts {
} eKS_Contexts;
-/* ---------------- KeyingSet Tools ------------------- */
+#endif // XXX old keyingsets code based on adrcodes... to be restored in due course
+
+/* Macros for Declaring KeyingSets ------------------- */
+
+/* A note about this system for declaring built-in Keying Sets:
+ * One may ask, "What is the purpose of all of these macros and static arrays?" and
+ * "Why not call the KeyingSets API defined in BKE_animsys.h?". The answer is two-fold.
+ *
+ * 1) Firstly, we use static arrays of struct definitions instead of function calls, as
+ * it reduces the start-up overhead and allocated-memory footprint of Blender. If we called
+ * the KeyingSets API to build these sets, the overhead of checking for unique names, allocating
+ * memory for each and every path and KeyingSet, scattered around in RAM, all of which would increase
+ * the startup time (which is totally unacceptable) and could lead to fragmentation+slower access times.
+ * 2) Since we aren't using function calls, we need a nice way of defining these KeyingSets in a way which
+ * is easily readable and less prone to breakage from changes to the underlying struct definitions. Further,
+ * adding additional entries SHOULD NOT require custom code to be written to access these new entries/sets.
+ * Therefore, here we have a system with nice, human-readable statements via macros, and static arrays which
+ * are linked together using more special macros + struct definitions, allowing for such a generic + simple
+ * initialisation function (init_builtin_keyingsets()) compared with that of something like the Nodes system.
+ */
+
+/* Struct type for declaring builtin KeyingSets in as entries in static arrays*/
+typedef struct bBuiltinKeyingSet {
+ KeyingSet ks; /* the KeyingSet to build */
+ int tot; /* the total number of paths defined */
+ KS_Path paths[64]; /* the paths for the KeyingSet to use */
+} bBuiltinKeyingSet;
+
+ /* WARNING: the following macros must be kept in sync with the
+ * struct definitions in DNA_anim_types.h!
+ */
+
+/* macro for defining a builtin KeyingSet */
+#define BI_KS_DEFINE(name, keyingflag) \
+ {NULL, NULL, {NULL, NULL}, name, KEYINGSET_BUILTIN, keyingflag}
+
+/* macro to start defining paths for a builtin KeyingSet */
+#define BI_KS_PATHS_BEGIN(tot) \
+ tot, {
+
+/* macro to finish defining paths for a builtin KeyingSet */
+#define BI_KS_PATHS_END \
+ }
+
+/* macro for defining a builtin KeyingSet's path */
+#define BI_KSP_DEFINE(id_type, templates, prop_path, array_index, flag, groupflag) \
+ {NULL, NULL, NULL, "", id_type, templates, prop_path, array_index, flag, groupflag}
+
+/* ---- */
+
+/* Struct type for finding all the arrays of builtin KeyingSets */
+typedef struct bBuiltinKSContext {
+ bBuiltinKeyingSet *bks; /* array of KeyingSet definitions */
+ int tot; /* number of KeyingSets in this array */
+} bBuiltinKSContext;
+
+/* macro for defining builtin KeyingSet sets
+ * NOTE: all the arrays of sets must follow this naming convention!
+ */
+#define BKSC_TEMPLATE(ctx_name) {&def_builtin_keyingsets_##ctx_name[0], sizeof(def_builtin_keyingsets_##ctx_name)/sizeof(bBuiltinKeyingSet)}
+
+
+/* 3D-View Builtin KeyingSets ------------------------ */
-/* helper for commonkey_context_get() - get keyingsets for 3d-view */
-static void commonkey_context_getv3d (const bContext *C, ListBase *sources, bKeyingContext **ksc)
+static bBuiltinKeyingSet def_builtin_keyingsets_v3d[] =
{
- Scene *scene= CTX_data_scene(C);
- Object *ob;
- IpoCurve *icu;
+ /* Simple Keying Sets ************************************* */
+ /* Keying Set - "Location" ---------- */
+ {
+ /* KeyingSet Definition */
+ BI_KS_DEFINE("Location", 0),
+
+ /* Path Definitions */
+ BI_KS_PATHS_BEGIN(1)
+ BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN, "location", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_KSNAME)
+ BI_KS_PATHS_END
+ },
+
+ /* Keying Set - "Rotation" ---------- */
+ {
+ /* KeyingSet Definition */
+ BI_KS_DEFINE("Rotation", 0),
+
+ /* Path Definitions */
+ BI_KS_PATHS_BEGIN(1)
+ BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN, "rotation", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_KSNAME)
+ BI_KS_PATHS_END
+ },
- if ((OBACT) && (OBACT->flag & OB_POSEMODE)) {
- bPoseChannel *pchan;
+ /* Keying Set - "Scaling" ---------- */
+ {
+ /* KeyingSet Definition */
+ BI_KS_DEFINE("Scaling", 0),
- /* pose-level */
- ob= OBACT;
- *ksc= &ks_contexts[KSC_V3D_PCHAN];
- // XXX
- //set_pose_keys(ob); /* sets pchan->flag to POSE_KEY if bone selected, and clears if not */
+ /* Path Definitions */
+ BI_KS_PATHS_BEGIN(1)
+ BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN, "scaling", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_KSNAME)
+ BI_KS_PATHS_END
+ },
+
+ /* Compound Keying Sets *********************************** */
+ /* Keying Set - "LocRot" ---------- */
+ {
+ /* KeyingSet Definition */
+ BI_KS_DEFINE("LocRot", 0),
- /* loop through posechannels */
- for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next) {
- if (pchan->flag & POSE_KEY) {
- bCommonKeySrc *cks;
-
- /* add new keyframing destination */
- cks= MEM_callocN(sizeof(bCommonKeySrc), "bCommonKeySrc");
- BLI_addtail(sources, cks);
-
- /* set id-block to key to, and action */
- cks->id= (ID *)ob;
- cks->act= ob->action;
-
- /* set pchan */
- cks->pchan= pchan;
- cks->actname= pchan->name;
- }
- }
+ /* Path Definitions */
+ BI_KS_PATHS_BEGIN(2)
+ BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN, "location", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_KSNAME),
+ BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN, "rotation", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_KSNAME)
+ BI_KS_PATHS_END
}
- else {
- /* object-level */
- *ksc= &ks_contexts[KSC_V3D_OBJECT];
-
- /* loop through bases */
- // XXX but we're only supposed to do this on editable ones, not just selected ones!
- CTX_DATA_BEGIN(C, Base*, base, selected_bases) {
- bCommonKeySrc *cks;
-
- /* add new keyframing destination */
- cks= MEM_callocN(sizeof(bCommonKeySrc), "bCommonKeySrc");
- BLI_addtail(sources, cks);
+};
+
+/* All Builtin KeyingSets ------------------------ */
+
+/* total number of builtin KeyingSet contexts */
+#define MAX_BKSC_TYPES 1
+
+/* array containing all the available builtin KeyingSets definition sets
+ * - size of this is MAX_BKSC_TYPES+1 so that we don't smash the stack
+ */
+static bBuiltinKSContext def_builtin_keyingsets[MAX_BKSC_TYPES+1] =
+{
+ BKSC_TEMPLATE(v3d)
+ /* add more contexts above this line... */
+};
+
+
+/* ListBase of these KeyingSets chained up ready for usage */
+static ListBase builtin_keyingsets = {NULL, NULL};
+
+/* Utility API ------------------------ */
+
+/* Link up all of the builtin Keying Sets when starting up Blender
+ * This is called from WM_init() in wm_init_exit.c
+ */
+void init_builtin_keyingsets (void)
+{
+ bBuiltinKSContext *bksc;
+ bBuiltinKeyingSet *bks;
+ int bksc_i, bks_i;
+
+ /* loop over all the sets of KeyingSets, setting them up, and chaining them to the builtins list */
+ for (bksc_i= 0, bksc= &def_builtin_keyingsets[0]; bksc_i < MAX_BKSC_TYPES; bksc_i++, bksc++)
+ {
+ /* for each set definitions for a builtin KeyingSet, chain the paths to that KeyingSet and add */
+ for (bks_i= 0, bks= bksc->bks; bks_i < bksc->tot; bks_i++, bks++)
+ {
+ KeyingSet *ks= &bks->ks;
+ KS_Path *ksp;
+ int pIndex;
- /* set id-block to key to */
- ob= base->object;
- cks->id= (ID *)ob;
+ /* loop over paths, linking them to the KeyingSet and each other */
+ for (pIndex= 0, ksp= &bks->paths[0]; pIndex < bks->tot; pIndex++, ksp++)
+ BLI_addtail(&ks->paths, ksp);
+
+ /* add KeyingSet to builtin sets list */
+ BLI_addtail(&builtin_keyingsets, ks);
}
- CTX_DATA_END;
}
}
-/* helper for commonkey_context_get() - get keyingsets for buttons window */
-static void commonkey_context_getsbuts (const bContext *C, ListBase *sources, bKeyingContext **ksc)
+/* ******************************************* */
+/* KEYFRAME MODIFICATION */
+
+/* mode for commonkey_modifykey */
+enum {
+ COMMONKEY_MODE_INSERT = 0,
+ COMMONKEY_MODE_DELETE,
+} eCommonModifyKey_Modes;
+
+/* KeyingSet Menu Helpers ------------ */
+
+/* Extract the maximum set of requirements from the KeyingSet */
+static int keyingset_relative_get_templates (KeyingSet *ks)
{
-#if 0 // XXX dunno what's the future of this stuff...
- bCommonKeySrc *cks;
+ KS_Path *ksp;
+ int templates= 0;
- /* check on tab-type */
- switch (G.buts->mainb) {
- case CONTEXT_SHADING: /* ------------- Shading buttons ---------------- */
- /* subtabs include "Material", "Texture", "Lamp", "World"*/
- switch (G.buts->tab[CONTEXT_SHADING]) {
- case TAB_SHADING_MAT: /* >------------- Material Tab -------------< */
- {
- Material *ma= editnode_get_active_material(G.buts->lockpoin);
-
- if (ma) {
- /* add new keyframing destination */
- cks= MEM_callocN(sizeof(bCommonKeySrc), "bCommonKeySrc");
- BLI_addtail(sources, cks);
-
- /* set data */
- cks->id= (ID *)ma;
- cks->ipo= ma->ipo;
- cks->map= texchannel_to_adrcode(ma->texact);
-
- /* set keyingsets */
- *ksc= &ks_contexts[KSC_BUTS_MAT];
- return;
- }
- }
- break;
- case TAB_SHADING_WORLD: /* >------------- World Tab -------------< */
- {
- World *wo= G.buts->lockpoin;
-
- if (wo) {
- /* add new keyframing destination */
- cks= MEM_callocN(sizeof(bCommonKeySrc), "bCommonKeySrc");
- BLI_addtail(sources, cks);
-
- /* set data */
- cks->id= (ID *)wo;
- cks->ipo= wo->ipo;
- cks->map= texchannel_to_adrcode(wo->texact);
-
- /* set keyingsets */
- *ksc= &ks_contexts[KSC_BUTS_WO];
- return;
- }
- }
- break;
- case TAB_SHADING_LAMP: /* >------------- Lamp Tab -------------< */
- {
- Lamp *la= G.buts->lockpoin;
-
- if (la) {
- /* add new keyframing destination */
- cks= MEM_callocN(sizeof(bCommonKeySrc), "bCommonKeySrc");
- BLI_addtail(sources, cks);
-
- /* set data */
- cks->id= (ID *)la;
- cks->ipo= la->ipo;
- cks->map= texchannel_to_adrcode(la->texact);
-
- /* set keyingsets */
- *ksc= &ks_contexts[KSC_BUTS_LA];
- return;
- }
- }
- break;
- case TAB_SHADING_TEX: /* >------------- Texture Tab -------------< */
- {
- Tex *tex= G.buts->lockpoin;
-
- if (tex) {
- /* add new keyframing destination */
- cks= MEM_callocN(sizeof(bCommonKeySrc), "bCommonKeySrc");
- BLI_addtail(sources, cks);
-
- /* set data */
- cks->id= (ID *)tex;
- cks->ipo= tex->ipo;
-
- /* set keyingsets */
- *ksc= &ks_contexts[KSC_BUTS_TEX];
- return;
- }
- }
- break;
- }
- break;
+ /* loop over the paths (could be slow to do for a number of KeyingSets)? */
+ for (ksp= ks->paths.first; ksp; ksp= ksp->next) {
+ /* add the destination's templates to the set of templates required for the set */
+ templates |= ksp->templates;
+ }
- case CONTEXT_OBJECT: /* ------------- Object buttons ---------------- */
- {
- Object *ob= OBACT;
-
- if (ob) {
- /* add new keyframing destination */
- cks= MEM_callocN(sizeof(bCommonKeySrc), "bCommonKeySrc");
- BLI_addtail(sources, cks);
-
- /* set id-block to key to */
- cks->id= (ID *)ob;
- cks->ipo= ob->ipo;
-
- /* set keyingsets */
- *ksc= &ks_contexts[KSC_BUTS_OB];
- return;
- }
- }
- break;
+ return templates;
+}
+
+/* Check if context data is suitable for the given absolute Keying Set */
+static short keyingset_context_ok_poll (bContext *C, KeyingSet *ks)
+{
+ ScrArea *sa= CTX_wm_area(C);
- case CONTEXT_EDITING: /* ------------- Editing buttons ---------------- */
+ /* data retrieved from context depends on active editor */
+ if (sa == NULL) return 0;
+
+ switch (sa->spacetype) {
+ case SPACE_VIEW3D:
{
- Object *ob= OBACT;
+ Object *obact= CTX_data_active_object(C);
- if ((ob) && (ob->type==OB_CAMERA) && (G.buts->lockpoin)) { /* >---------------- camera buttons ---------------< */
- Camera *ca= G.buts->lockpoin;
+ /* if in posemode, check if 'pose-channels' requested for in KeyingSet */
+ if ((obact && obact->pose) && (obact->flag & OB_POSEMODE)) {
+ /* check for posechannels */
- /* add new keyframing destination */
- cks= MEM_callocN(sizeof(bCommonKeySrc), "bCommonKeySrc");
- BLI_addtail(sources, cks);
-
- /* set id-block to key to */
- cks->id= (ID *)ca;
- cks->ipo= ca->ipo;
+ }
+ else {
+ /* check for selected object */
- /* set keyingsets */
- *ksc= &ks_contexts[KSC_BUTS_CAM];
- return;
}
}
- break;
+ break;
}
-#endif // XXX end of buttons stuff to port...
- /* if nothing happened... */
- *ksc= NULL;
+
+ return 1;
}
-#endif // XXX old keyingsets code based on adrcodes... to be restored in due course
-
-#if 0 // XXX new relative keyingsets code
+/* KeyingSet Context Operations ------------ */
-/* Check if context data is suitable for the given absolute Keying Set */
-static short keyingset_context_ok_poll (bContext *C, KeyingSet *ks)
+/* Get list of data-sources from context (in 3D-View) for inserting keyframes using the given relative Keying Set */
+static short commonkey_get_context_v3d_data (bContext *C, ListBase *dsources, KeyingSet *ks)
{
+ bCommonKeySrc *cks;
+ Object *obact= CTX_data_active_object(C);
+ int templates;
+ short ok= 0;
+
+ /* get the templates in use in this KeyingSet which we should supply data for */
+ templates = keyingset_relative_get_templates(ks);
+
+ /* check if the active object is in PoseMode (i.e. only deal with bones) */
+ // TODO: check with the templates to see what we really need to store
+ if ((obact && obact->pose) && (obact->flag & OB_POSEMODE)) {
+ /* Pose Mode: Selected bones */
+#if 0
+ //set_pose_keys(ob); /* sets pchan->flag to POSE_KEY if bone selected, and clears if not */
+
+ /* loop through posechannels */
+ //for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next) {
+ // if (pchan->flag & POSE_KEY) {
+ // }
+ //}
+#endif
+
+ CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pchans)
+ {
+ /* add a new keying-source */
+ cks= MEM_callocN(sizeof(bCommonKeySrc), "bCommonKeySrc");
+ BLI_addtail(dsources, cks);
+
+ /* set necessary info */
+ cks->id= &obact->id;
+ cks->pchan= pchan;
+
+ if (templates & KSP_TEMPLATE_CONSTRAINT)
+ cks->con= constraints_get_active(&pchan->constraints);
+
+ ok= 1;
+ }
+ CTX_DATA_END;
+ }
+ else {
+ /* Object Mode: Selected objects */
+ CTX_DATA_BEGIN(C, Base*, base, selected_bases)
+ {
+ Object *ob= base->object;
+
+ /* add a new keying-source */
+ cks= MEM_callocN(sizeof(bCommonKeySrc), "bCommonKeySrc");
+ BLI_addtail(dsources, cks);
+
+ /* set necessary info */
+ cks->id= &ob->id;
+
+ if (templates & KSP_TEMPLATE_CONSTRAINT)
+ cks->con= constraints_get_active(&ob->constraints);
+
+ ok= 1;
+ }
+ CTX_DATA_END;
+ }
- return 1;
+ /* return whether any data was extracted */
+ return ok;
}
/* Get list of data-sources from context for inserting keyframes using the given relative Keying Set */
static short commonkey_get_context_data (bContext *C, ListBase *dsources, KeyingSet *ks)
{
+ ScrArea *sa= CTX_wm_area(C);
+ /* for now, the active area is used to determine what set of contexts apply */
+ if (sa == NULL)
+ return 0;
+
+ switch (sa->spacetype) {
+ case SPACE_VIEW3D: /* 3D-View: Selected Objects or Bones */
+ return commonkey_get_context_v3d_data(C, dsources, ks);
+ }
+
+ /* nothing happened */
+ return 0;
}
-#endif // XXX new relative keyingsets code
+/* KeyingSet Operations (Insert/Delete Keyframes) ------------ */
/* Given a KeyingSet and context info (if required), modify keyframes for the channels specified
* by the KeyingSet. This takes into account many of the different combinations of using KeyingSets.
* Returns the number of channels that keyframes were added to
*/
-static int commonkey_modifykey (ListBase *dsources, KeyingSet *ks, short mode, float cfra)
+static int commonkey_modifykey (bContext *C, ListBase *dsources, KeyingSet *ks, short mode, float cfra)
{
KS_Path *ksp;
int kflag=0, success= 0;
@@ -1851,26 +1934,125 @@ static int commonkey_modifykey (ListBase *dsources, KeyingSet *ks, short mode, f
if (mode == COMMONKEY_MODE_INSERT)
success+= insertkey(ksp->id, groupname, ksp->rna_path, i, cfra, kflag);
else if (mode == COMMONKEY_MODE_DELETE)
- success+= deletekey(ksp->id, groupname, ksp->rna_path, i, cfra, kflag);
+ success+= deletekey(ksp->id, groupname, ksp->rna_path, i, cfra, kflag);
}
- // TODO: set recalc tags on the ID?
+ /* send notifiers and set recalc-flags */
+ // TODO: hopefully this doesn't result in execessive flooding of the notifier stack
+ if (C && ksp->id) {
+ switch (GS(ksp->id->name)) {
+ case ID_OB: /* Object (or Object-Related) Keyframes */
+ {
+ Object *ob= (Object *)ksp->id;
+
+ ob->recalc |= OB_RECALC;
+ WM_event_add_notifier(C, NC_OBJECT|ND_KEYS, ksp->id);
+ }
+ break;
+ case ID_MA: /* Material Keyframes */
+ WM_event_add_notifier(C, NC_MATERIAL|ND_KEYS, ksp->id);
+ break;
+ }
+ }
}
}
-#if 0 // XXX still need to figure out how to get such keyingsets working
- else if (dsources) {
+ else if (dsources && dsources->first) {
/* for each one of the 'sources', resolve the template markers and expand arrays, then insert keyframes */
bCommonKeySrc *cks;
- char *path = NULL;
- int index=0, tot=0;
/* for each 'source' for keyframe data, resolve each of the paths from the KeyingSet */
for (cks= dsources->first; cks; cks= cks->next) {
+ /* for each path in KeyingSet, construct a path using the templates */
+ for (ksp= ks->paths.first; ksp; ksp= ksp->next) {
+ DynStr *pathds= BLI_dynstr_new();
+ char *path = NULL;
+ int arraylen, i;
+
+ /* construct the path */
+ // FIXME: this currently only works with a few hardcoded cases
+ if ((ksp->templates & KSP_TEMPLATE_PCHAN) && (cks->pchan)) {
+ /* add basic pose-channel path access */
+ BLI_dynstr_append(pathds, "pose.pose_channels[\"");
+ BLI_dynstr_append(pathds, cks->pchan->name);
+ BLI_dynstr_append(pathds, "\"]");
+ }
+ if ((ksp->templates & KSP_TEMPLATE_CONSTRAINT) && (cks->con)) {
+ /* add basic constraint path access */
+ BLI_dynstr_append(pathds, "constraints[\"");
+ BLI_dynstr_append(pathds, cks->con->name);
+ BLI_dynstr_append(pathds, "\"]");
+ }
+ {
+ /* add property stored in KeyingSet Path */
+ if (BLI_dynstr_get_len(pathds))
+ BLI_dynstr_append(pathds, ".");
+ BLI_dynstr_append(pathds, ksp->rna_path);
+
+ /* convert to C-string */
+ path= BLI_dynstr_get_cstring(pathds);
+ BLI_dynstr_free(pathds);
+ }
+
+ /* get pointer to name of group to add channels to */
+ if (ksp->groupmode == KSP_GROUP_NONE)
+ groupname= NULL;
+ else if (ksp->groupmode == KSP_GROUP_KSNAME)
+ groupname= ks->name;
+ else
+ groupname= ksp->group;
+
+ /* init arraylen and i - arraylen should be greater than i so that
+ * normal non-array entries get keyframed correctly
+ */
+ i= ksp->array_index;
+ arraylen= i+1;
+
+ /* get length of array if whole array option is enabled */
+ if (ksp->flag & KSP_FLAG_WHOLE_ARRAY) {
+ PointerRNA id_ptr, ptr;
+ PropertyRNA *prop;
+
+ RNA_id_pointer_create(cks->id, &id_ptr);
+ if (RNA_path_resolve(&id_ptr, path, &ptr, &prop) && prop)
+ arraylen= RNA_property_array_length(&ptr, prop);
+ }
+
+ /* for each possible index, perform operation
+ * - assume that arraylen is greater than index
+ */
+ for (; i < arraylen; i++) {
+ /* action to take depends on mode */
+ if (mode == COMMONKEY_MODE_INSERT)
+ success+= insertkey(cks->id, groupname, path, i, cfra, kflag);
+ else if (mode == COMMONKEY_MODE_DELETE)
+ success+= deletekey(cks->id, groupname, path, i, cfra, kflag);
+ }
+
+ /* free the path */
+ MEM_freeN(path);
+ }
+ /* send notifiers and set recalc-flags */
+ // TODO: hopefully this doesn't result in execessive flooding of the notifier stack
+ if (C && cks->id) {
+ switch (GS(cks->id->name)) {
+ case ID_OB: /* Object (or Object-Related) Keyframes */
+ {
+ Object *ob= (Object *)cks->id;
+
+ ob->recalc |= OB_RECALC;
+ WM_event_add_notifier(C, NC_OBJECT|ND_KEYS, cks->id);
+ }
+ break;
+ case ID_MA: /* Material Keyframes */
+ WM_event_add_notifier(C, NC_MATERIAL|ND_KEYS, cks->id);
+ break;
+ }
+ }
}
}
-#endif // XXX still need to figure out how to get such
+ /* return the number of channels successfully affected */
return success;
}
@@ -1904,38 +2086,56 @@ static int modify_key_op_poll(bContext *C)
/* Insert Key Operator ------------------------ */
-/* NOTE:
- * This is one of the 'simpler new-style' Insert Keyframe operators which relies on Keying Sets.
- * For now, these are absolute Keying Sets only, so there is very little context info involved.
- *
- * -- Joshua Leung, Feb 2009
- */
-
static int insert_key_exec (bContext *C, wmOperator *op)
{
ListBase dsources = {NULL, NULL};
Scene *scene= CTX_data_scene(C);
KeyingSet *ks= NULL;
+ int type= RNA_int_get(op->ptr, "type");
float cfra= (float)CFRA; // XXX for now, don't bother about all the yucky offset crap
short success;
- /* try to get KeyingSet */
- if (scene->active_keyingset > 0)
+ /* type is the Keying Set the user specified to use when calling the operator:
+ * - type == 0: use scene's active Keying Set
+ * - type > 0: use a user-defined Keying Set from the active scene
+ * - type < 0: use a builtin Keying Set
+ */
+ if (type == 0)
+ type= scene->active_keyingset;
+ if (type > 0)
ks= BLI_findlink(&scene->keyingsets, scene->active_keyingset-1);
- /* report failure */
+ else
+ ks= BLI_findlink(&builtin_keyingsets, -type-1);
+
+ /* report failures */
if (ks == NULL) {
BKE_report(op->reports, RPT_ERROR, "No active Keying Set");
return OPERATOR_CANCELLED;
}
+ /* get context info for relative Keying Sets */
+ if ((ks->flag & KEYINGSET_ABSOLUTE) == 0) {
+ /* exit if no suitable data obtained */
+ if (commonkey_get_context_data(C, &dsources, ks) == 0) {
+ BKE_report(op->reports, RPT_ERROR, "No suitable context info for active Keying Set");
+ return OPERATOR_CANCELLED;
+ }
+ }
+
/* try to insert keyframes for the channels specified by KeyingSet */
- success= commonkey_modifykey(&dsources, ks, COMMONKEY_MODE_INSERT, cfra);
+ success= commonkey_modifykey(C, &dsources, ks, COMMONKEY_MODE_INSERT, cfra);
printf("KeyingSet '%s' - Successfully added %d Keyframes \n", ks->name, success);
/* report failure? */
if (success == 0)
BKE_report(op->reports, RPT_WARNING, "Keying Set failed to insert any keyframes");
+ /* free temp context-data if available */
+ if (dsources.first) {
+ /* we assume that there is no extra data that needs to be freed from here... */
+ BLI_freelistN(&dsources);
+ }
+
/* send updates */
ED_anim_dag_flush_update(C);
@@ -1957,42 +2157,126 @@ void ANIM_OT_insert_keyframe (wmOperatorType *ot)
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* settings */
+ RNA_def_boolean(ot->srna, "builtin", 0, "Built-In Keying Set", "Use one of the relative Keying Sets defined by default");
}
-/* Delete Key Operator ------------------------ */
+/* Insert Key Operator (With Menu) ------------------------ */
-/* NOTE:
- * This is one of the 'simpler new-style' Insert Keyframe operators which relies on Keying Sets.
- * For now, these are absolute Keying Sets only, so there is very little context info involved.
- *
- * -- Joshua Leung, Feb 2009
+/* XXX
+ * This operator pops up a menu which sets gets the index of the keyingset to use,
+ * setting the global settings, and calling the insert-keyframe operator using these
+ * settings
*/
+
+static int insert_key_menu_invoke (bContext *C, wmOperator *op, wmEvent *event)
+{
+ Scene *scene= CTX_data_scene(C);
+ KeyingSet *ks;
+ uiMenuItem *head;
+ int i = 0;
+
+ head= uiPupMenuBegin("Insert Keyframe", 0);
+
+ /* active Keying Set */
+ uiMenuItemIntO(head, "Active Keying Set", 0, "ANIM_OT_insert_keyframe_menu", "type", i++);
+ uiMenuSeparator(head);
+
+ /* user-defined Keying Sets
+ * - these are listed in the order in which they were defined for the active scene
+ */
+ for (ks= scene->keyingsets.first; ks; ks= ks->next)
+ uiMenuItemIntO(head, ks->name, 0, "ANIM_OT_insert_keyframe_menu", "type", i++);
+ uiMenuSeparator(head);
+
+ /* builtin Keying Sets */
+ // XXX polling the entire list may lag
+ i= -1;
+ for (ks= builtin_keyingsets.first; ks; ks= ks->next) {
+ /* only show KeyingSet if context is suitable */
+ if (keyingset_context_ok_poll(C, ks)) {
+ uiMenuItemIntO(head, ks->name, 0, "ANIM_OT_insert_keyframe_menu", "type", i--);
+ }
+ }
+
+ uiPupMenuEnd(C, head);
+
+ return OPERATOR_CANCELLED;
+}
+void ANIM_OT_insert_keyframe_menu (wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Insert Keyframe";
+ ot->idname= "ANIM_OT_insert_keyframe_menu";
+
+ /* callbacks */
+ ot->invoke= insert_key_menu_invoke;
+ ot->exec= insert_key_exec;
+ ot->poll= ED_operator_areaactive;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* properties
+ * - NOTE: here the type is int not enum, since many of the indicies here are determined dynamically
+ */
+ RNA_def_int(ot->srna, "type", 0, INT_MIN, INT_MAX, "Keying Set Number", "Index (determined internally) of the Keying Set to use", 0, 1);
+}
+
+/* Delete Key Operator ------------------------ */
+
static int delete_key_exec (bContext *C, wmOperator *op)
{
ListBase dsources = {NULL, NULL};
Scene *scene= CTX_data_scene(C);
- KeyingSet *ks= NULL;
+ KeyingSet *ks= NULL;
+ int type= RNA_int_get(op->ptr, "type");
float cfra= (float)CFRA; // XXX for now, don't bother about all the yucky offset crap
short success;
- /* try to get KeyingSet */
- if (scene->active_keyingset > 0)
+ /* type is the Keying Set the user specified to use when calling the operator:
+ * - type == 0: use scene's active Keying Set
+ * - type > 0: use a user-defined Keying Set from the active scene
+ * - type < 0: use a builtin Keying Set
+ */
+ if (type == 0)
+ type= scene->active_keyingset;
+ if (type > 0)
ks= BLI_findlink(&scene->keyingsets, scene->active_keyingset-1);
+ else
+ ks= BLI_findlink(&builtin_keyingsets, -type-1);
+
/* report failure */
if (ks == NULL) {
BKE_report(op->reports, RPT_ERROR, "No active Keying Set");
return OPERATOR_CANCELLED;
}
+ /* get context info for relative Keying Sets */
+ if ((ks->flag & KEYINGSET_ABSOLUTE) == 0) {
+ /* exit if no suitable data obtained */
+ if (commonkey_get_context_data(C, &dsources, ks) == 0) {
+ BKE_report(op->reports, RPT_ERROR, "No suitable context info for active Keying Set");
+ return OPERATOR_CANCELLED;
+ }
+ }
+
/* try to insert keyframes for the channels specified by KeyingSet */
- success= commonkey_modifykey(&dsources, ks, COMMONKEY_MODE_DELETE, cfra);
+ success= commonkey_modifykey(C, &dsources, ks, COMMONKEY_MODE_DELETE, cfra);
printf("KeyingSet '%s' - Successfully removed %d Keyframes \n", ks->name, success);
/* report failure? */
if (success == 0)
BKE_report(op->reports, RPT_WARNING, "Keying Set failed to remove any keyframes");
+ /* free temp context-data if available */
+ if (dsources.first) {
+ /* we assume that there is no extra data that needs to be freed from here... */
+ BLI_freelistN(&dsources);
+ }
+
/* send updates */
ED_anim_dag_flush_update(C);
@@ -2014,220 +2298,18 @@ void ANIM_OT_delete_keyframe (wmOperatorType *ot)
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
-}
-
-/* Insert Key Operator ------------------------ */
-
-/* XXX WARNING:
- * This is currently just a basic operator, which work in 3d-view context on objects/bones only
- * and will insert keyframes for a few settings only. This is until it becomes clear how
- * to separate (or not) the process for RNA-path creation between context + keyingsets.
- *
- * -- Joshua Leung, Jan 2009
- */
-
-/* defines for basic insert-key testing operator */
- // XXX this will definitely be replaced
-EnumPropertyItem prop_insertkey_types[] = {
- {0, "KEYINGSET", "Active KeyingSet", ""},
- {1, "OBLOC", "Object Location", ""},
- {2, "OBROT", "Object Rotation", ""},
- {3, "OBSCALE", "Object Scale", ""},
- {4, "MAT_COL", "Active Material - Color", ""},
- {5, "PCHANLOC", "Pose-Channel Location", ""},
- {6, "PCHANROT", "Pose-Channel Rotation", ""},
- {7, "PCHANSCALE", "Pose-Channel Scale", ""},
- {0, NULL, NULL, NULL}
-};
-
-static int insert_key_old_invoke (bContext *C, wmOperator *op, wmEvent *event)
-{
- Object *ob= CTX_data_active_object(C);
- uiMenuItem *head;
-
- if (ob == NULL)
- return OPERATOR_CANCELLED;
-
- head= uiPupMenuBegin("Insert Keyframe", 0);
-
- /* active keyingset */
- uiMenuItemEnumO(head, "", 0, "ANIM_OT_insert_keyframe_old", "type", 0);
-
- /* selective inclusion */
- if ((ob->pose) && (ob->flag & OB_POSEMODE)) {
- /* bone types */
- uiMenuItemEnumO(head, "", 0, "ANIM_OT_insert_keyframe_old", "type", 5);
- uiMenuItemEnumO(head, "", 0, "ANIM_OT_insert_keyframe_old", "type", 6);
- uiMenuItemEnumO(head, "", 0, "ANIM_OT_insert_keyframe_old", "type", 7);
- }
- else {
- /* object types */
- uiMenuItemEnumO(head, "", 0, "ANIM_OT_insert_keyframe_old", "type", 1);
- uiMenuItemEnumO(head, "", 0, "ANIM_OT_insert_keyframe_old", "type", 2);
- uiMenuItemEnumO(head, "", 0, "ANIM_OT_insert_keyframe_old", "type", 3);
- uiMenuItemEnumO(head, "", 0, "ANIM_OT_insert_keyframe_old", "type", 4);
- }
-
- uiPupMenuEnd(C, head);
-
- return OPERATOR_CANCELLED;
-}
-
-static int insert_key_old_exec (bContext *C, wmOperator *op)
-{
- Scene *scene= CTX_data_scene(C);
- short mode= RNA_enum_get(op->ptr, "type");
- float cfra= (float)CFRA; // XXX for now, don't bother about all the yucky offset crap
-
- /* for now, handle 'active keyingset' one separately */
- if (mode == 0) {
- ListBase dsources = {NULL, NULL};
- KeyingSet *ks= NULL;
- short success;
-
- /* try to get KeyingSet */
- if (scene->active_keyingset > 0)
- ks= BLI_findlink(&scene->keyingsets, scene->active_keyingset-1);
- /* report failure */
- if (ks == NULL) {
- BKE_report(op->reports, RPT_ERROR, "No active Keying Set");
- return OPERATOR_CANCELLED;
- }
-
- /* try to insert keyframes for the channels specified by KeyingSet */
- success= commonkey_modifykey(&dsources, ks, COMMONKEY_MODE_INSERT, cfra);
- printf("KeyingSet '%s' - Successfully added %d Keyframes \n", ks->name, success);
-
- /* report failure? */
- if (success == 0)
- BKE_report(op->reports, RPT_WARNING, "Keying Set failed to insert any keyframes");
- }
- else {
- // more comprehensive tests will be needed
- CTX_DATA_BEGIN(C, Base*, base, selected_bases)
- {
- Object *ob= base->object;
- ID *id= (ID *)ob;
- short success= 0;
-
- /* check which keyframing mode chosen for this object */
- if (mode < 4) {
- /* object-based keyframes */
- switch (mode) {
- case 4: /* color of active material (only for geometry...) */
- // NOTE: this is just a demo... but ideally we'd go through materials instead of active one only so reference stays same
- // XXX no group for now
- success+= insertkey(id, NULL, "active_material.diffuse_color", 0, cfra, 0);
- success+= insertkey(id, NULL, "active_material.diffuse_color", 1, cfra, 0);
- success+= insertkey(id, NULL, "active_material.diffuse_color", 2, cfra, 0);
- break;
- case 3: /* object scale */
- success+= insertkey(id, "Object Transforms", "scale", 0, cfra, 0);
- success+= insertkey(id, "Object Transforms", "scale", 1, cfra, 0);
- success+= insertkey(id, "Object Transforms", "scale", 2, cfra, 0);
- break;
- case 2: /* object rotation */
- success+= insertkey(id, "Object Transforms", "rotation", 0, cfra, 0);
- success+= insertkey(id, "Object Transforms", "rotation", 1, cfra, 0);
- success+= insertkey(id, "Object Transforms", "rotation", 2, cfra, 0);
- break;
- default: /* object location */
- success+= insertkey(id, "Object Transforms", "location", 0, cfra, 0);
- success+= insertkey(id, "Object Transforms", "location", 1, cfra, 0);
- success+= insertkey(id, "Object Transforms", "location", 2, cfra, 0);
- break;
- }
-
- ob->recalc |= OB_RECALC_OB;
- }
- else if ((ob->pose) && (ob->flag & OB_POSEMODE)) {
- /* PoseChannel based keyframes */
- bPoseChannel *pchan;
-
- for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
- /* only if selected */
- if ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED)) {
- char buf[512];
-
- switch (mode) {
- case 7: /* pchan scale */
- sprintf(buf, "pose.pose_channels[\"%s\"].scale", pchan->name);
- success+= insertkey(id, pchan->name, buf, 0, cfra, 0);
- success+= insertkey(id, pchan->name, buf, 1, cfra, 0);
- success+= insertkey(id, pchan->name, buf, 2, cfra, 0);
- break;
- case 6: /* pchan rotation */
- if (pchan->rotmode == PCHAN_ROT_QUAT) {
- sprintf(buf, "pose.pose_channels[\"%s\"].rotation", pchan->name);
- success+= insertkey(id, pchan->name, buf, 0, cfra, 0);
- success+= insertkey(id, pchan->name, buf, 1, cfra, 0);
- success+= insertkey(id, pchan->name, buf, 2, cfra, 0);
- success+= insertkey(id, pchan->name, buf, 3, cfra, 0);
- }
- else {
- sprintf(buf, "pose.pose_channels[\"%s\"].euler_rotation", pchan->name);
- success+= insertkey(id, pchan->name, buf, 0, cfra, 0);
- success+= insertkey(id, pchan->name, buf, 1, cfra, 0);
- success+= insertkey(id, pchan->name, buf, 2, cfra, 0);
- }
- break;
- default: /* pchan location */
- sprintf(buf, "pose.pose_channels[\"%s\"].location", pchan->name);
- success+= insertkey(id, pchan->name, buf, 0, cfra, 0);
- success+= insertkey(id, pchan->name, buf, 1, cfra, 0);
- success+= insertkey(id, pchan->name, buf, 2, cfra, 0);
- break;
- }
- }
- }
-
- ob->recalc |= OB_RECALC_OB;
- }
-
- printf("Ob '%s' - Successfully added %d Keyframes \n", id->name+2, success);
- }
- CTX_DATA_END;
- }
-
- /* send updates */
- ED_anim_dag_flush_update(C);
-
- if (mode == 0) /* for now, only send ND_KEYS for KeyingSets */
- WM_event_add_notifier(C, ND_KEYS, NULL);
- else if (mode == 4) /* material color requires different notifiers */
- WM_event_add_notifier(C, NC_MATERIAL|ND_KEYS, NULL);
- else
- WM_event_add_notifier(C, NC_OBJECT|ND_KEYS, NULL);
-
- return OPERATOR_FINISHED;
-}
-
-void ANIM_OT_insert_keyframe_old (wmOperatorType *ot)
-{
- PropertyRNA *prop;
-
- /* identifiers */
- ot->name= "Insert Keyframe";
- ot->idname= "ANIM_OT_insert_keyframe_old";
-
- /* callbacks */
- ot->invoke= insert_key_old_invoke;
- ot->exec= insert_key_old_exec;
- ot->poll= ED_operator_areaactive;
-
- /* flags */
- ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
- /* properties */
- // XXX update this for the latest RNA stuff styles...
- prop= RNA_def_property(ot->srna, "type", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, prop_insertkey_types);
+ /* properties
+ * - NOTE: here the type is int not enum, since many of the indicies here are determined dynamically
+ */
+ RNA_def_int(ot->srna, "type", 0, INT_MIN, INT_MAX, "Keying Set Number", "Index (determined internally) of the Keying Set to use", 0, 1);
}
/* Delete Key Operator ------------------------ */
/* XXX WARNING:
* This is currently just a basic operator, which work in 3d-view context on objects only.
+ * Should this be kept? It does have advantages over a version which requires selecting a keyingset to use...
* -- Joshua Leung, Jan 2009
*/
@@ -2264,7 +2346,6 @@ static int delete_key_old_exec (bContext *C, wmOperator *op)
/* send updates */
ED_anim_dag_flush_update(C);
- // XXX what if it was a material keyframe?
WM_event_add_notifier(C, NC_OBJECT|ND_KEYS, NULL);
return OPERATOR_FINISHED;
@@ -2277,7 +2358,7 @@ void ANIM_OT_delete_keyframe_old (wmOperatorType *ot)
ot->idname= "ANIM_OT_delete_keyframe_old";
/* callbacks */
- ot->invoke= WM_operator_confirm; // XXX we will need our own one eventually, to cope with the dynamic menus...
+ ot->invoke= WM_operator_confirm;
ot->exec= delete_key_old_exec;
ot->poll= ED_operator_areaactive;
diff --git a/source/blender/editors/include/ED_keyframing.h b/source/blender/editors/include/ED_keyframing.h
index b2846fc0bd9..16e0dbc8c35 100644
--- a/source/blender/editors/include/ED_keyframing.h
+++ b/source/blender/editors/include/ED_keyframing.h
@@ -69,6 +69,9 @@ short deletekey(struct ID *id, const char group[], const char rna_path[], int ar
/* Generate menu of KeyingSets */
char *ANIM_build_keyingsets_menu(struct ListBase *list, short for_edit);
+/* Initialise builtin KeyingSets on startup */
+void init_builtin_keyingsets(void);
+
/* KeyingSet Editing Operators:
* These can add a new KeyingSet and/or add 'destinations' to the KeyingSets,
* acting as a means by which they can be added outside the Outliner.
@@ -83,12 +86,13 @@ void ANIM_OT_keyingset_add_destination(struct wmOperatorType *ot);
void ANIM_OT_insert_keyframe(struct wmOperatorType *ot);
void ANIM_OT_delete_keyframe(struct wmOperatorType *ot);
-/* Main Keyframe Management operators (legacy style):
+/* Main Keyframe Management operators:
* These handle keyframes management from various spaces. They will handle the menus
* required for each space.
*/
-void ANIM_OT_insert_keyframe_old(struct wmOperatorType *ot);
-void ANIM_OT_delete_keyframe_old(struct wmOperatorType *ot);
+void ANIM_OT_insert_keyframe_menu(struct wmOperatorType *ot);
+void ANIM_OT_delete_keyframe_menu(struct wmOperatorType *ot); // xxx unimplemented yet
+void ANIM_OT_delete_keyframe_old(struct wmOperatorType *ot); // xxx rename and keep?
/* ************ Auto-Keyframing ********************** */
/* Notes:
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index 8cbf9bf5287..6c8c6e6b60f 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -136,7 +136,7 @@ void ED_keymap_object(wmWindowManager *wm)
WM_keymap_verify_item(keymap, "OBJECT_OT_duplicate_add", DKEY, KM_PRESS, KM_SHIFT, 0);
// XXX this should probably be in screen instead... here for testing purposes in the meantime... - Aligorith
- WM_keymap_verify_item(keymap, "ANIM_OT_insert_keyframe_old", IKEY, KM_PRESS, 0, 0);
+ WM_keymap_verify_item(keymap, "ANIM_OT_insert_keyframe_menu", IKEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "ANIM_OT_delete_keyframe_old", IKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_verify_item(keymap, "GROUP_OT_group_create", GKEY, KM_PRESS, KM_CTRL, 0);
diff --git a/source/blender/editors/space_outliner/outliner.c b/source/blender/editors/space_outliner/outliner.c
index 54652587c53..93297e37d4d 100644
--- a/source/blender/editors/space_outliner/outliner.c
+++ b/source/blender/editors/space_outliner/outliner.c
@@ -3088,7 +3088,7 @@ static KeyingSet *verify_active_keyingset(Scene *scene, short add)
/* add if none found */
// XXX the default settings have yet to evolve
if ((add) && (ks==NULL)) {
- ks= BKE_keyingset_add(&scene->keyingsets, "KeyingSet", KEYINGSET_ABSOLUTE, 0);
+ ks= BKE_keyingset_add(&scene->keyingsets, "Keying Set", KEYINGSET_ABSOLUTE, 0);
scene->active_keyingset= BLI_countlist(&scene->keyingsets);
}
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index d5828f7e3a3..90b1ec7c9be 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -588,7 +588,7 @@ typedef struct Scene {
int frame_step;
/* User-Defined KeyingSets */
- int active_keyingset; /* index of the active KeyingSet. first KeyingSet has index 1 */
+ int active_keyingset; /* index of the active KeyingSet. first KeyingSet has index 1, 'none' active is 0, 'add new' is -1 */
ListBase keyingsets; /* KeyingSets for the given frame */
} Scene;
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index 990a862a102..1fa184e74a4 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -83,6 +83,7 @@
#include "wm_window.h"
#include "ED_armature.h"
+#include "ED_keyframing.h"
#include "ED_node.h"
#include "ED_previewrender.h"
#include "ED_space_api.h"
@@ -125,6 +126,8 @@ void WM_init(bContext *C)
BLF_init();
BLF_lang_init();
+ init_builtin_keyingsets(); /* editors/animation/keyframing.c */
+
/* get the default database, plus a wm */
WM_read_homefile(C, NULL);