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:
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/animation/anim_intern.h6
-rw-r--r--source/blender/editors/animation/keyframing.c58
-rw-r--r--source/blender/editors/animation/keyingsets.c1143
-rw-r--r--source/blender/editors/armature/editarmature.c72
-rw-r--r--source/blender/editors/armature/poseUtils.c25
-rw-r--r--source/blender/editors/armature/poselib.c61
-rw-r--r--source/blender/editors/armature/poseobject.c129
-rw-r--r--source/blender/editors/include/ED_keyframing.h86
-rw-r--r--source/blender/editors/object/object_transform.c84
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c20
-rw-r--r--source/blender/editors/transform/transform_conversions.c90
11 files changed, 523 insertions, 1251 deletions
diff --git a/source/blender/editors/animation/anim_intern.h b/source/blender/editors/animation/anim_intern.h
index 5602bff77ce..379b8c27de5 100644
--- a/source/blender/editors/animation/anim_intern.h
+++ b/source/blender/editors/animation/anim_intern.h
@@ -33,12 +33,6 @@
/* list of builtin KeyingSets (defined in keyingsets.c) */
extern ListBase builtin_keyingsets;
-/* for builtin keyingsets - context poll */
-short keyingset_context_ok_poll(bContext *C, KeyingSet *ks);
-
-/* Main KeyingSet operations API call */
-short modifykey_get_context_data (bContext *C, ListBase *dsources, KeyingSet *ks);
-
/* Operator Define Prototypes ------------------- */
/* Main Keyframe Management operators:
diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c
index d0675dc42ba..eaebab2efab 100644
--- a/source/blender/editors/animation/keyframing.c
+++ b/source/blender/editors/animation/keyframing.c
@@ -1073,7 +1073,6 @@ static int modify_key_op_poll(bContext *C)
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");
@@ -1098,22 +1097,17 @@ static int insert_key_exec (bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- /* get context info for relative Keying Sets */
- if ((ks->flag & KEYINGSET_ABSOLUTE) == 0) {
- /* exit if no suitable data obtained */
- if (modifykey_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= modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
+ success= ANIM_apply_keyingset(C, NULL, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
if (G.f & G_DEBUG)
BKE_reportf(op->reports, RPT_INFO, "KeyingSet '%s' - Successfully added %d Keyframes \n", ks->name, success);
/* report failure or do updates? */
- if (success) {
+ if (success == MODIFYKEY_INVALID_CONTEXT) {
+ BKE_report(op->reports, RPT_ERROR, "No suitable context info for active Keying Set");
+ return OPERATOR_CANCELLED;
+ }
+ else if (success) {
/* if the appropriate properties have been set, make a note that we've inserted something */
if (RNA_boolean_get(op->ptr, "confirm_success"))
BKE_reportf(op->reports, RPT_INFO, "Successfully added %d Keyframes for KeyingSet '%s'", success, ks->name);
@@ -1123,13 +1117,6 @@ static int insert_key_exec (bContext *C, wmOperator *op)
}
else
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 */
DAG_ids_flush_update(0);
@@ -1191,8 +1178,10 @@ static void insert_key_menu_prompt (bContext *C)
* - these are listed in the order in which they were defined for the active scene
*/
if (scene->keyingsets.first) {
- for (ks= scene->keyingsets.first; ks; ks= ks->next)
- uiItemIntO(layout, ks->name, 0, "ANIM_OT_keyframe_insert_menu", "type", i++);
+ for (ks= scene->keyingsets.first; ks; ks= ks->next) {
+ if (ANIM_keyingset_context_ok_poll(C, ks))
+ uiItemIntO(layout, ks->name, 0, "ANIM_OT_keyframe_insert_menu", "type", i++);
+ }
uiItemS(layout);
}
@@ -1200,9 +1189,8 @@ static void insert_key_menu_prompt (bContext *C)
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)) {
+ if (ANIM_keyingset_context_ok_poll(C, ks))
uiItemIntO(layout, ks->name, 0, "ANIM_OT_keyframe_insert_menu", "type", i--);
- }
}
uiPupMenuEnd(C, pup);
@@ -1261,7 +1249,6 @@ void ANIM_OT_keyframe_insert_menu (wmOperatorType *ot)
static int delete_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");
@@ -1286,22 +1273,17 @@ static int delete_key_exec (bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- /* get context info for relative Keying Sets */
- if ((ks->flag & KEYINGSET_ABSOLUTE) == 0) {
- /* exit if no suitable data obtained */
- if (modifykey_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= modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_DELETE, cfra);
+ success= ANIM_apply_keyingset(C, NULL, NULL, ks, MODIFYKEY_MODE_DELETE, cfra);
if (G.f & G_DEBUG)
printf("KeyingSet '%s' - Successfully removed %d Keyframes \n", ks->name, success);
/* report failure or do updates? */
- if (success) {
+ if (success == MODIFYKEY_INVALID_CONTEXT) {
+ BKE_report(op->reports, RPT_ERROR, "No suitable context info for active Keying Set");
+ return OPERATOR_CANCELLED;
+ }
+ else if (success) {
/* if the appropriate properties have been set, make a note that we've inserted something */
if (RNA_boolean_get(op->ptr, "confirm_success"))
BKE_reportf(op->reports, RPT_INFO, "Successfully removed %d Keyframes for KeyingSet '%s'", success, ks->name);
@@ -1312,12 +1294,6 @@ static int delete_key_exec (bContext *C, wmOperator *op)
else
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 */
DAG_ids_flush_update(0);
diff --git a/source/blender/editors/animation/keyingsets.c b/source/blender/editors/animation/keyingsets.c
index 63323a8519d..1e4180a3ae7 100644
--- a/source/blender/editors/animation/keyingsets.c
+++ b/source/blender/editors/animation/keyingsets.c
@@ -256,14 +256,8 @@ static int remove_active_ks_path_exec (bContext *C, wmOperator *op)
KS_Path *ksp= BLI_findlink(&ks->paths, ks->active_path-1);
if (ksp) {
- /* NOTE: sync this code with BKE_keyingset_free() */
- {
- /* free RNA-path info */
- MEM_freeN(ksp->rna_path);
-
- /* free path itself */
- BLI_freelinkN(&ks->paths, ksp);
- }
+ /* remove the active path from the KeyingSet */
+ BKE_keyingset_free_path(ks, ksp);
/* the active path should now be the previously second-to-last active one */
ks->active_path--;
@@ -467,663 +461,136 @@ void ANIM_OT_keyingset_button_remove (wmOperatorType *ot)
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
-/* ************************************************** */
-/* KEYING SETS - EDITING API */
-
-/* UI API --------------------------------------------- */
-
-/* Build menu-string of available keying-sets (allocates memory for string)
- * NOTE: mode must not be longer than 64 chars
- */
-char *ANIM_build_keyingsets_menu (ListBase *list, short for_edit)
-{
- DynStr *pupds= BLI_dynstr_new();
- KeyingSet *ks;
- char buf[64];
- char *str;
- int i;
-
- /* add title first */
- BLI_dynstr_append(pupds, "Keying Sets%t|");
-
- /* add dummy entries for none-active */
- if (for_edit) {
- BLI_dynstr_append(pupds, "Add New%x-1|");
- BLI_dynstr_append(pupds, " %x0|");
- }
- else
- BLI_dynstr_append(pupds, "No Keying Set%x0|");
-
- /* loop through keyingsets, adding them */
- for (ks=list->first, i=1; ks; ks=ks->next, i++) {
- if (for_edit == 0)
- BLI_dynstr_append(pupds, "KS: ");
-
- BLI_dynstr_append(pupds, ks->name);
- BLI_snprintf( buf, 64, "%%x%d%s", i, ((ks->next)?"|":"") );
- BLI_dynstr_append(pupds, buf);
- }
-
- /* convert to normal MEM_malloc'd string */
- str= BLI_dynstr_get_cstring(pupds);
- BLI_dynstr_free(pupds);
-
- return str;
-}
-
-
/* ******************************************* */
-/* KEYING SETS - BUILTIN */
-
-#if 0 // XXX old keyingsets code based on adrcodes... to be restored in due course
-
-/* ------------- KeyingSet Defines ------------ */
-/* Note: these must all be named with the defks_* prefix, otherwise the template macro will not work! */
-
-/* macro for defining keyingset contexts */
-#define KSC_TEMPLATE(ctx_name) {&defks_##ctx_name[0], NULL, sizeof(defks_##ctx_name)/sizeof(bKeyingSet)}
+/* REGISTERED KEYING SETS */
-/* --- */
+/* Keying Set Type Info declarations */
+ListBase keyingset_type_infos = {NULL, NULL};
-/* check if option not available for deleting keys */
-static short incl_non_del_keys (bKeyingSet *ks, const char mode[])
-{
- /* as optimisation, assume that it is sufficient to check only first letter
- * of mode (int comparison should be faster than string!)
- */
- //if (strcmp(mode, "Delete")==0)
- if (mode && mode[0]=='D')
- return 0;
-
- return 1;
-}
+/* Built-In Keying Sets (referencing type infos)*/
+ListBase builtin_keyingsets = {NULL, NULL};
-/* Object KeyingSets ------ */
+/* --------------- */
-/* check if include shapekey entry */
-static short incl_v3d_ob_shapekey (bKeyingSet *ks, const char mode[])
+/* Find KeyingSet type info given a name */
+KeyingSetInfo *ANIM_keyingset_info_find_named (const char name[])
{
- //Object *ob= (G.obedit)? (G.obedit) : (OBACT); // XXX
- Object *ob= NULL;
- char *newname= NULL;
-
- if(ob==NULL)
- return 0;
-
- /* not available for delete mode */
- if (strcmp(mode, "Delete")==0)
- return 0;
+ KeyingSetInfo *ksi;
- /* check if is geom object that can get shapekeys */
- switch (ob->type) {
- /* geometry? */
- case OB_MESH: newname= "Mesh"; break;
- case OB_CURVE: newname= "Curve"; break;
- case OB_SURF: newname= "Surface"; break;
- case OB_LATTICE: newname= "Lattice"; break;
+ /* sanity checks */
+ if ((name == NULL) || (name[0] == 0))
+ return NULL;
- /* not geometry! */
- default:
- return 0;
+ /* search by comparing names */
+ for (ksi = keyingset_type_infos.first; ksi; ksi = ksi->next) {
+ if (strcmp(ksi->name, name) == 0)
+ return ksi;
}
- /* if ks is shapekey entry (this could be callled for separator before too!) */
- if (ks->flag == -3)
- BLI_strncpy(ks->name, newname, sizeof(ks->name));
-
- /* if it gets here, it's ok */
- return 1;
+ /* no matches found */
+ return NULL;
}
-/* array for object keyingset defines */
-bKeyingSet defks_v3d_object[] =
-{
- /* include_cb, adrcode-getter, name, blocktype, flag, chan_num, adrcodes */
- {NULL, "Loc", ID_OB, 0, 3, {OB_LOC_X,OB_LOC_Y,OB_LOC_Z}},
- {NULL, "Rot", ID_OB, 0, 3, {OB_ROT_X,OB_ROT_Y,OB_ROT_Z}},
- {NULL, "Scale", ID_OB, 0, 3, {OB_SIZE_X,OB_SIZE_Y,OB_SIZE_Z}},
-
- {NULL, "%l", 0, -1, 0, {0}}, // separator
-
- {NULL, "LocRot", ID_OB, 0, 6,
- {OB_LOC_X,OB_LOC_Y,OB_LOC_Z,
- OB_ROT_X,OB_ROT_Y,OB_ROT_Z}},
-
- {NULL, "LocScale", ID_OB, 0, 6,
- {OB_LOC_X,OB_LOC_Y,OB_LOC_Z,
- OB_SIZE_X,OB_SIZE_Y,OB_SIZE_Z}},
-
- {NULL, "LocRotScale", ID_OB, 0, 9,
- {OB_LOC_X,OB_LOC_Y,OB_LOC_Z,
- OB_ROT_X,OB_ROT_Y,OB_ROT_Z,
- OB_SIZE_X,OB_SIZE_Y,OB_SIZE_Z}},
-
- {NULL, "RotScale", ID_OB, 0, 6,
- {OB_ROT_X,OB_ROT_Y,OB_ROT_Z,
- OB_SIZE_X,OB_SIZE_Y,OB_SIZE_Z}},
-
- {incl_non_del_keys, "%l", 0, -1, 0, {0}}, // separator
-
- {incl_non_del_keys, "VisualLoc", ID_OB, INSERTKEY_MATRIX, 3, {OB_LOC_X,OB_LOC_Y,OB_LOC_Z}},
- {incl_non_del_keys, "VisualRot", ID_OB, INSERTKEY_MATRIX, 3, {OB_ROT_X,OB_ROT_Y,OB_ROT_Z}},
-
- {incl_non_del_keys, "VisualLocRot", ID_OB, INSERTKEY_MATRIX, 6,
- {OB_LOC_X,OB_LOC_Y,OB_LOC_Z,
- OB_ROT_X,OB_ROT_Y,OB_ROT_Z}},
-
- {NULL, "%l", 0, -1, 0, {0}}, // separator
-
- {NULL, "Layer", ID_OB, 0, 1, {OB_LAY}}, // icky option...
- {NULL, "Available", ID_OB, -2, 0, {0}},
-
- {incl_v3d_ob_shapekey, "%l%l", 0, -1, 0, {0}}, // separator (linked to shapekey entry)
- {incl_v3d_ob_shapekey, "<ShapeKey>", ID_OB, -3, 0, {0}}
-};
-
-/* PoseChannel KeyingSets ------ */
-
-/* array for posechannel keyingset defines */
-bKeyingSet defks_v3d_pchan[] =
+/* Find builtin KeyingSet by name */
+KeyingSet *ANIM_builtin_keyingset_get_named (KeyingSet *prevKS, const char name[])
{
- /* include_cb, name, blocktype, flag, chan_num, adrcodes */
- {NULL, "Loc", ID_PO, 0, 3, {AC_LOC_X,AC_LOC_Y,AC_LOC_Z}},
- {NULL, "Rot", ID_PO, COMMONKEY_PCHANROT, 1, {KAG_CHAN_EXTEND}},
- {NULL, "Scale", ID_PO, 0, 3, {AC_SIZE_X,AC_SIZE_Y,AC_SIZE_Z}},
-
- {NULL, "%l", 0, -1, 0, {0}}, // separator
-
- {NULL, "LocRot", ID_PO, COMMONKEY_PCHANROT, 4,
- {AC_LOC_X,AC_LOC_Y,AC_LOC_Z,
- KAG_CHAN_EXTEND}},
-
- {NULL, "LocScale", ID_PO, 0, 6,
- {AC_LOC_X,AC_LOC_Y,AC_LOC_Z,
- AC_SIZE_X,AC_SIZE_Y,AC_SIZE_Z}},
-
- {NULL, "LocRotScale", ID_PO, COMMONKEY_PCHANROT, 7,
- {AC_LOC_X,AC_LOC_Y,AC_LOC_Z,AC_SIZE_X,AC_SIZE_Y,AC_SIZE_Z,
- KAG_CHAN_EXTEND}},
-
- {NULL, "RotScale", ID_PO, 0, 4,
- {AC_SIZE_X,AC_SIZE_Y,AC_SIZE_Z,
- KAG_CHAN_EXTEND}},
-
- {incl_non_del_keys, "%l", 0, -1, 0, {0}}, // separator
-
- {incl_non_del_keys, "VisualLoc", ID_PO, INSERTKEY_MATRIX, 3, {AC_LOC_X,AC_LOC_Y,AC_LOC_Z}},
- {incl_non_del_keys, "VisualRot", ID_PO, INSERTKEY_MATRIX|COMMONKEY_PCHANROT, 1, {KAG_CHAN_EXTEND}},
-
- {incl_non_del_keys, "VisualLocRot", ID_PO, INSERTKEY_MATRIX|COMMONKEY_PCHANROT, 4,
- {AC_LOC_X,AC_LOC_Y,AC_LOC_Z, KAG_CHAN_EXTEND}},
-
- {NULL, "%l", 0, -1, 0, {0}}, // separator
-
- {NULL, "Available", ID_PO, -2, 0, {0}}
-};
-
-/* Material KeyingSets ------ */
-
-/* array for material keyingset defines */
-bKeyingSet defks_buts_shading_mat[] =
-{
- /* include_cb, name, blocktype, flag, chan_num, adrcodes */
- {NULL, "RGB", ID_MA, 0, 3, {MA_COL_R,MA_COL_G,MA_COL_B}},
- {NULL, "Alpha", ID_MA, 0, 1, {MA_ALPHA}},
- {NULL, "Halo Size", ID_MA, 0, 1, {MA_HASIZE}},
- {NULL, "Mode", ID_MA, 0, 1, {MA_MODE}}, // evil bitflags
-
- {NULL, "%l", 0, -1, 0, {0}}, // separator
-
- {NULL, "All Color", ID_MA, 0, 18,
- {MA_COL_R,MA_COL_G,MA_COL_B,
- MA_ALPHA,MA_HASIZE, MA_MODE,
- MA_SPEC_R,MA_SPEC_G,MA_SPEC_B,
- MA_REF,MA_EMIT,MA_AMB,MA_SPEC,MA_HARD,
- MA_MODE,MA_TRANSLU,MA_ADD}},
-
- {NULL, "All Mirror", ID_MA, 0, 5,
- {MA_RAYM,MA_FRESMIR,MA_FRESMIRI,
- MA_FRESTRA,MA_FRESTRAI}},
-
- {NULL, "%l", 0, -1, 0, {0}}, // separator
-
- {NULL, "Ofs", ID_MA, COMMONKEY_ADDMAP, 3, {MAP_OFS_X,MAP_OFS_Y,MAP_OFS_Z}},
- {NULL, "Size", ID_MA, COMMONKEY_ADDMAP, 3, {MAP_SIZE_X,MAP_SIZE_Y,MAP_SIZE_Z}},
-
- {NULL, "All Mapping", ID_MA, COMMONKEY_ADDMAP, 14,
- {MAP_OFS_X,MAP_OFS_Y,MAP_OFS_Z,
- MAP_SIZE_X,MAP_SIZE_Y,MAP_SIZE_Z,
- MAP_R,MAP_G,MAP_B,MAP_DVAR,
- MAP_COLF,MAP_NORF,MAP_VARF,MAP_DISP}},
-
- {NULL, "%l", 0, -1, 0, {0}}, // separator
-
- {NULL, "Available", ID_MA, -2, 0, {0}}
-};
-
-/* World KeyingSets ------ */
-
-/* array for world keyingset defines */
-bKeyingSet defks_buts_shading_wo[] =
-{
- /* include_cb, name, blocktype, flag, chan_num, adrcodes */
- {NULL, "Zenith RGB", ID_WO, 0, 3, {WO_ZEN_R,WO_ZEN_G,WO_ZEN_B}},
- {NULL, "Horizon RGB", ID_WO, 0, 3, {WO_HOR_R,WO_HOR_G,WO_HOR_B}},
-
- {NULL, "%l", 0, -1, 0, {0}}, // separator
-
- {NULL, "Mist", ID_WO, 0, 4, {WO_MISI,WO_MISTDI,WO_MISTSTA,WO_MISTHI}},
- {NULL, "Stars", ID_WO, 0, 5, {WO_STAR_R,WO_STAR_G,WO_STAR_B,WO_STARDIST,WO_STARSIZE}},
-
-
- {NULL, "%l", 0, -1, 0, {0}}, // separator
-
- {NULL, "Ofs", ID_WO, COMMONKEY_ADDMAP, 3, {MAP_OFS_X,MAP_OFS_Y,MAP_OFS_Z}},
- {NULL, "Size", ID_WO, COMMONKEY_ADDMAP, 3, {MAP_SIZE_X,MAP_SIZE_Y,MAP_SIZE_Z}},
-
- {NULL, "All Mapping", ID_WO, COMMONKEY_ADDMAP, 14,
- {MAP_OFS_X,MAP_OFS_Y,MAP_OFS_Z,
- MAP_SIZE_X,MAP_SIZE_Y,MAP_SIZE_Z,
- MAP_R,MAP_G,MAP_B,MAP_DVAR,
- MAP_COLF,MAP_NORF,MAP_VARF,MAP_DISP}},
-
- {NULL, "%l", 0, -1, 0, {0}}, // separator
-
- {NULL, "Available", ID_WO, -2, 0, {0}}
-};
-
-/* Lamp KeyingSets ------ */
-
-/* array for lamp keyingset defines */
-bKeyingSet defks_buts_shading_la[] =
-{
- /* include_cb, name, blocktype, flag, chan_num, adrcodes */
- {NULL, "RGB", ID_LA, 0, 3, {LA_COL_R,LA_COL_G,LA_COL_B}},
- {NULL, "Energy", ID_LA, 0, 1, {LA_ENERGY}},
- {NULL, "Spot Size", ID_LA, 0, 1, {LA_SPOTSI}},
-
- {NULL, "%l", 0, -1, 0, {0}}, // separator
-
- {NULL, "Ofs", ID_LA, COMMONKEY_ADDMAP, 3, {MAP_OFS_X,MAP_OFS_Y,MAP_OFS_Z}},
- {NULL, "Size", ID_LA, COMMONKEY_ADDMAP, 3, {MAP_SIZE_X,MAP_SIZE_Y,MAP_SIZE_Z}},
-
- {NULL, "All Mapping", ID_LA, COMMONKEY_ADDMAP, 14,
- {MAP_OFS_X,MAP_OFS_Y,MAP_OFS_Z,
- MAP_SIZE_X,MAP_SIZE_Y,MAP_SIZE_Z,
- MAP_R,MAP_G,MAP_B,MAP_DVAR,
- MAP_COLF,MAP_NORF,MAP_VARF,MAP_DISP}},
+ KeyingSet *ks, *first=NULL;
- {NULL, "%l", 0, -1, 0, {0}}, // separator
+ /* sanity checks any name to check? */
+ if (name[0] == 0)
+ return NULL;
- {NULL, "Available", ID_LA, -2, 0, {0}}
-};
-
-/* Texture KeyingSets ------ */
-
-/* array for texture keyingset defines */
-bKeyingSet defks_buts_shading_tex[] =
-{
- /* include_cb, name, blocktype, flag, chan_num, adrcodes */
- {NULL, "Clouds", ID_TE, 0, 5,
- {TE_NSIZE,TE_NDEPTH,TE_NTYPE,
- TE_MG_TYP,TE_N_BAS1}},
-
- {NULL, "Marble", ID_TE, 0, 7,
- {TE_NSIZE,TE_NDEPTH,TE_NTYPE,
- TE_TURB,TE_MG_TYP,TE_N_BAS1,TE_N_BAS2}},
-
- {NULL, "Stucci", ID_TE, 0, 5,
- {TE_NSIZE,TE_NTYPE,TE_TURB,
- TE_MG_TYP,TE_N_BAS1}},
-
- {NULL, "Wood", ID_TE, 0, 6,
- {TE_NSIZE,TE_NTYPE,TE_TURB,
- TE_MG_TYP,TE_N_BAS1,TE_N_BAS2}},
-
- {NULL, "Magic", ID_TE, 0, 2, {TE_NDEPTH,TE_TURB}},
-
- {NULL, "Blend", ID_TE, 0, 1, {TE_MG_TYP}},
-
- {NULL, "Musgrave", ID_TE, 0, 6,
- {TE_MG_TYP,TE_MGH,TE_MG_LAC,
- TE_MG_OCT,TE_MG_OFF,TE_MG_GAIN}},
-
- {NULL, "Voronoi", ID_TE, 0, 9,
- {TE_VNW1,TE_VNW2,TE_VNW3,TE_VNW4,
- TE_VNMEXP,TE_VN_DISTM,TE_VN_COLT,
- TE_ISCA,TE_NSIZE}},
+ /* get first KeyingSet to use */
+ if (prevKS && prevKS->next)
+ first= prevKS->next;
+ else
+ first= builtin_keyingsets.first;
- {NULL, "Distorted Noise", ID_TE, 0, 4,
- {TE_MG_OCT,TE_MG_OFF,TE_MG_GAIN,TE_DISTA}},
-
- {NULL, "Color Filter", ID_TE, 0, 5,
- {TE_COL_R,TE_COL_G,TE_COL_B,TE_BRIGHT,TE_CONTRA}},
-
- {NULL, "%l", 0, -1, 0, {0}}, // separator
-
- {NULL, "Available", ID_TE, -2, 0, {0}}
-};
-
-/* Object Buttons KeyingSets ------ */
-
-/* check if include particles entry */
-static short incl_buts_ob (bKeyingSet *ks, const char mode[])
-{
- //Object *ob= OBACT; // xxx
- Object *ob= NULL;
- /* only if object is mesh type */
-
- if(ob==NULL) return 0;
- return (ob->type == OB_MESH);
-}
-
-/* array for texture keyingset defines */
-bKeyingSet defks_buts_object[] =
-{
- /* include_cb, name, blocktype, flag, chan_num, adrcodes */
- {incl_buts_ob, "Surface Damping", ID_OB, 0, 1, {OB_PD_SDAMP}},
- {incl_buts_ob, "Random Damping", ID_OB, 0, 1, {OB_PD_RDAMP}},
- {incl_buts_ob, "Permeability", ID_OB, 0, 1, {OB_PD_PERM}},
-
- {NULL, "%l", 0, -1, 0, {0}}, // separator
-
- {NULL, "Force Strength", ID_OB, 0, 1, {OB_PD_FSTR}},
- {NULL, "Force Falloff", ID_OB, 0, 1, {OB_PD_FFALL}},
-
- {NULL, "%l", 0, -1, 0, {0}}, // separator
+ /* loop over KeyingSets checking names */
+ for (ks= first; ks; ks= ks->next) {
+ if (strcmp(name, ks->name) == 0)
+ return ks;
+ }
- {NULL, "Available", ID_OB, -2, 0, {0}} // this will include ob-transforms too!
-};
-
-/* Camera Buttons KeyingSets ------ */
-
-/* check if include internal-renderer entry */
-static short incl_buts_cam1 (bKeyingSet *ks, const char mode[])
-{
- Scene *scene= NULL; // FIXME this will cause a crash, but we need an extra arg first!
- /* only if renderer is internal renderer */
- return (scene->r.renderer==R_INTERN);
+ /* no matches found */
+ return NULL;
}
-/* check if include external-renderer entry */
-static short incl_buts_cam2 (bKeyingSet *ks, const char mode[])
-{
- Scene *scene= NULL; // FIXME this will cause a crash, but we need an extra arg first!
- /* only if renderer is internal renderer */
- return (scene->r.renderer!=R_INTERN);
-}
+/* --------------- */
-/* array for camera keyingset defines */
-bKeyingSet defks_buts_cam[] =
+/* Add the given KeyingSetInfo to the list of type infos, and create an appropriate builtin set too */
+void ANIM_keyingset_info_register (const bContext *C, KeyingSetInfo *ksi)
{
- /* include_cb, name, blocktype, flag, chan_num, adrcodes */
- {NULL, "Lens", ID_CA, 0, 1, {CAM_LENS}},
- {NULL, "Clipping", ID_CA, 0, 2, {CAM_STA,CAM_END}},
- {NULL, "Focal Distance", ID_CA, 0, 1, {CAM_YF_FDIST}},
-
- {NULL, "%l", 0, -1, 0, {0}}, // separator
+ Scene *scene = CTX_data_scene(C);
+ ListBase *list = NULL;
+ KeyingSet *ks;
+ /* determine the KeyingSet list to include the new KeyingSet in */
+ if (ksi->builtin)
+ list = &builtin_keyingsets;
+ else
+ list = &scene->keyingsets;
- {incl_buts_cam2, "Aperture", ID_CA, 0, 1, {CAM_YF_APERT}},
- {incl_buts_cam1, "Viewplane Shift", ID_CA, 0, 2, {CAM_SHIFT_X,CAM_SHIFT_Y}},
+ /* create a new KeyingSet
+ * - inherit name and keyframing settings from the typeinfo
+ */
+ ks = BKE_keyingset_add(list, ksi->name, ksi->builtin, ksi->keyingflag);
- {NULL, "%l", 0, -1, 0, {0}}, // separator
+ /* link this KeyingSet with its typeinfo */
+ memcpy(&ks->typeinfo, ksi->name, sizeof(ks->typeinfo));
- {NULL, "Available", ID_CA, -2, 0, {0}}
-};
-
-/* --- */
+ /* add type-info to the list */
+ BLI_addtail(&keyingset_type_infos, ksi);
+}
-/* Keying Context Defines - Must keep in sync with enumeration (eKS_Contexts) */
-bKeyingContext ks_contexts[] =
+/* Remove the given KeyingSetInfo from the list of type infos, and also remove the builtin set if appropriate */
+void ANIM_keyingset_info_unregister (const bContext *C, KeyingSetInfo *ksi)
{
- KSC_TEMPLATE(v3d_object),
- KSC_TEMPLATE(v3d_pchan),
+ Scene *scene = CTX_data_scene(C);
+ KeyingSet *ks, *ksn;
- KSC_TEMPLATE(buts_shading_mat),
- KSC_TEMPLATE(buts_shading_wo),
- KSC_TEMPLATE(buts_shading_la),
- KSC_TEMPLATE(buts_shading_tex),
-
- KSC_TEMPLATE(buts_object),
- KSC_TEMPLATE(buts_cam)
-};
-
-/* Keying Context Enumeration - Must keep in sync with definitions*/
-typedef enum eKS_Contexts {
- KSC_V3D_OBJECT = 0,
- KSC_V3D_PCHAN,
-
- KSC_BUTS_MAT,
- KSC_BUTS_WO,
- KSC_BUTS_LA,
- KSC_BUTS_TEX,
-
- KSC_BUTS_OB,
- KSC_BUTS_CAM,
-
- /* make sure this last one remains untouched! */
- KSC_TOT_TYPES
-} eKS_Contexts;
-
-
-#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.
- *
- * -- Joshua Leung, April 2009
- */
-
-/* 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_BEGIN(name, keyingflag) \
- {{NULL, NULL, {NULL, NULL}, name, KEYINGSET_BUILTIN, keyingflag},
-
-/* macro to finish defining a builtin KeyingSet */
-#define BI_KS_DEFINE_END \
- }
-
-/* 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 \
+ /* find relevant scene KeyingSets which use this, and remove them */
+ for (ks= scene->keyingsets.first; ks; ks= ksn) {
+ ksn = ks->next;
+
+ /* remove if matching typeinfo name */
+ if (strcmp(ks->typeinfo, ksi->name) == 0) {
+ BKE_keyingset_free(ks);
+ BLI_freelinkN(&scene->keyingsets, ks);
+ }
}
-/* 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}
+ /* do the same with builtin sets? */
+ // TODO: this isn't done now, since unregister is really only used atm when we
+ // reload the scripts, which kindof defeats the purpose of "builtin"?
-/* macro for defining a builtin KeyingSet with no paths (use in place of BI_KS_PAHTS_BEGIN/END block) */
-#define BI_KS_PATHS_NONE \
- 0, {0}
-/* ---- */
-
-/* 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 ------------------------ */
-
-static bBuiltinKeyingSet def_builtin_keyingsets_v3d[] =
-{
- /* Simple Keying Sets ************************************* */
- /* Keying Set - "Location" ---------- */
- BI_KS_DEFINE_BEGIN("Location", 0)
- BI_KS_PATHS_BEGIN(1)
- BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN, "location", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM)
- BI_KS_PATHS_END
- BI_KS_DEFINE_END,
-
- /* Keying Set - "Rotation" ---------- */
- BI_KS_DEFINE_BEGIN("Rotation", 0)
- BI_KS_PATHS_BEGIN(1)
- BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN|KSP_TEMPLATE_ROT, "rotation", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM)
- BI_KS_PATHS_END
- BI_KS_DEFINE_END,
-
- /* Keying Set - "Scaling" ---------- */
- BI_KS_DEFINE_BEGIN("Scaling", 0)
- BI_KS_PATHS_BEGIN(1)
- BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN, "scale", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM)
- BI_KS_PATHS_END
- BI_KS_DEFINE_END,
-
- /* Compound Keying Sets *********************************** */
- /* Keying Set - "LocRot" ---------- */
- BI_KS_DEFINE_BEGIN("LocRot", 0)
- BI_KS_PATHS_BEGIN(2)
- BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN, "location", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM),
- BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN|KSP_TEMPLATE_ROT, "rotation", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM)
- BI_KS_PATHS_END
- BI_KS_DEFINE_END,
-
- /* Keying Set - "LocRotScale" ---------- */
- BI_KS_DEFINE_BEGIN("LocRotScale", 0)
- BI_KS_PATHS_BEGIN(3)
- BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN, "location", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM),
- BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN|KSP_TEMPLATE_ROT, "rotation", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM),
- BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN, "scale", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM)
- BI_KS_PATHS_END
- BI_KS_DEFINE_END,
-
- /* Keying Sets with Keying Flags ************************* */
- /* Keying Set - "VisualLoc" ---------- */
- BI_KS_DEFINE_BEGIN("VisualLoc", INSERTKEY_MATRIX)
- BI_KS_PATHS_BEGIN(1)
- BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN, "location", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM)
- BI_KS_PATHS_END
- BI_KS_DEFINE_END,
-
- /* Keying Set - "Rotation" ---------- */
- BI_KS_DEFINE_BEGIN("VisualRot", INSERTKEY_MATRIX)
- BI_KS_PATHS_BEGIN(1)
- BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN|KSP_TEMPLATE_ROT, "rotation", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM)
- BI_KS_PATHS_END
- BI_KS_DEFINE_END,
-
- /* Keying Set - "VisualLocRot" ---------- */
- BI_KS_DEFINE_BEGIN("VisualLocRot", INSERTKEY_MATRIX)
- BI_KS_PATHS_BEGIN(2)
- BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN, "location", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM),
- BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN|KSP_TEMPLATE_ROT, "rotation", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM)
- BI_KS_PATHS_END
- BI_KS_DEFINE_END
-};
-
-/* 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
- * NOTE: this is exported to keyframing.c for use...
- */
-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;
-
- /* 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);
- }
- }
+ /* free the type info */
+ BLI_freelinkN(&keyingset_type_infos, ksi);
}
+/* --------------- */
-/* Get the first builtin KeyingSet with the given name, which occurs after the given one (or start of list if none given) */
-KeyingSet *ANIM_builtin_keyingset_get_named (KeyingSet *prevKS, char name[])
+void ANIM_keyingset_infos_exit ()
{
- KeyingSet *ks, *first=NULL;
-
- /* sanity checks - any name to check? */
- if (name[0] == 0)
- return NULL;
+ KeyingSetInfo *ksi, *next;
- /* get first KeyingSet to use */
- if (prevKS && prevKS->next)
- first= prevKS->next;
- else
- first= builtin_keyingsets.first;
+ /* free type infos */
+ for (ksi=keyingset_type_infos.first; ksi; ksi=next) {
+ next= ksi->next;
- /* loop over KeyingSets checking names */
- for (ks= first; ks; ks= ks->next) {
- if (strcmp(name, ks->name) == 0)
- return ks;
+ /* free extra RNA data, and remove from list */
+ if (ksi->ext.free)
+ ksi->ext.free(ksi->ext.data);
+ BLI_freelinkN(&keyingset_type_infos, ksi);
}
- /* no matches found */
- return NULL;
+ /* free builtin sets */
+ BKE_keyingsets_free(&builtin_keyingsets);
}
+/* ******************************************* */
+/* KEYING SETS API (for UI) */
/* Get the active Keying Set for the Scene provided */
KeyingSet *ANIM_scene_get_active_keyingset (Scene *scene)
@@ -1142,127 +609,74 @@ KeyingSet *ANIM_scene_get_active_keyingset (Scene *scene)
return NULL;
}
-/* ******************************************* */
-/* KEYFRAME MODIFICATION */
-
-/* KeyingSet Menu Helpers ------------ */
-
-/* Extract the maximum set of requirements from the KeyingSet */
-static int keyingset_relative_get_templates (KeyingSet *ks)
+/* Check if KeyingSet can be used in the current context */
+short ANIM_keyingset_context_ok_poll (bContext *C, KeyingSet *ks)
{
- KS_Path *ksp;
- int templates= 0;
-
- /* 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;
+ if ((ks->flag & KEYINGSET_ABSOLUTE) == 0) {
+ KeyingSetInfo *ksi = ANIM_keyingset_info_find_named(ks->typeinfo);
+
+ /* get the associated 'type info' for this KeyingSet */
+ if (ksi == NULL)
+ return 0;
+ // TODO: check for missing callbacks!
+
+ /* check if it can be used in the current context */
+ return (ksi->poll(ksi, C));
}
- return templates;
-}
-
-/* Check if context data is suitable for the given Keying Set */
-short keyingset_context_ok_poll (bContext *C, KeyingSet *ks)
-{
- // TODO:
- // For 'relative' keyingsets (i.e. py-keyingsets), add a call here
- // which basically gets a listing of all the paths to be used for this
- // set.
-
-
return 1;
}
-/* KeyingSet Context Operations ------------ */
+/* ******************************************* */
+/* KEYFRAME MODIFICATION */
+
+/* Special 'Overrides' Iterator for Relative KeyingSets ------ */
+
+/* 'Data Sources' for relative Keying Set 'overrides'
+ * - this is basically a wrapper for PointerRNA's in a linked list
+ * - do not allow this to be accessed from outside for now
+ */
+typedef struct tRKS_DSource {
+ struct tRKS_DSource *next, *prev;
+ PointerRNA ptr; /* the whole point of this exercise! */
+} tRKS_DSource;
+
-/* Get list of data-sources from context (in 3D-View) for inserting keyframes using the given relative Keying Set */
-static short modifykey_get_context_v3d_data (bContext *C, ListBase *dsources, KeyingSet *ks)
+/* Iterator used for overriding the behaviour of iterators defined for
+ * relative Keying Sets, with the main usage of this being operators
+ * requiring Auto Keyframing. Internal Use Only!
+ */
+static void RKS_ITER_overrides_list (KeyingSetInfo *ksi, bContext *C, KeyingSet *ks, ListBase *dsources)
{
- 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->mode & OB_MODE_POSE)) {
- /* 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_pose_bones)
- {
- /* 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, Object*, ob, selected_objects)
- {
- /* 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;
- }
+ tRKS_DSource *ds;
- /* return whether any data was extracted */
- return ok;
+ for (ds = dsources->first; ds; ds = ds->next) {
+ /* run generate callback on this data */
+ ksi->generate(ksi, C, ks, &ds->ptr);
+ }
}
-/* Get list of data-sources from context for inserting keyframes using the given relative Keying Set */
-short modifykey_get_context_data (bContext *C, ListBase *dsources, KeyingSet *ks)
+/* Add new data source for relative Keying Sets */
+void ANIM_relative_keyingset_add_source (ListBase *dsources, ID *id, StructRNA *srna, void *data)
{
- ScrArea *sa= CTX_wm_area(C);
+ tRKS_DSource *ds;
- /* for now, the active area is used to determine what set of contexts apply */
- if (sa == NULL)
- return 0;
+ /* sanity checks
+ * we must have at least one valid data pointer to use
+ */
+ if (ELEM(NULL, dsources, srna) || ((id == data) && (id == NULL)))
+ return;
-#if 0
- switch (sa->spacetype) {
- case SPACE_VIEW3D: /* 3D-View: Selected Objects or Bones */
- return modifykey_get_context_v3d_data(C, dsources, ks);
- }
+ /* allocate new elem, and add to the list */
+ ds = MEM_callocN(sizeof(tRKS_DSource), "tRKS_DSource");
+ BLI_addtail(dsources, ds);
- /* nothing happened */
- return 0;
-#endif
-
- /* looking into this code, it doesnt use the 3D view - Campbell */
- return modifykey_get_context_v3d_data(C, dsources, ks);
-}
+ /* depending on what data we have, create using ID or full pointer call */
+ if (srna && data)
+ RNA_pointer_create(id, srna, data, &ds->ptr);
+ else
+ RNA_id_pointer_create(id, &ds->ptr);
+}
/* KeyingSet Operations (Insert/Delete Keyframes) ------------ */
@@ -1270,8 +684,9 @@ short modifykey_get_context_data (bContext *C, ListBase *dsources, KeyingSet *ks
* 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
*/
-int modify_keyframes (Scene *scene, ListBase *dsources, bAction *act, KeyingSet *ks, short mode, float cfra)
+int ANIM_apply_keyingset (bContext *C, ListBase *dsources, bAction *act, KeyingSet *ks, short mode, float cfra)
{
+ Scene *scene= CTX_data_scene(C);
KS_Path *ksp;
int kflag=0, success= 0;
char *groupname= NULL;
@@ -1291,201 +706,101 @@ int modify_keyframes (Scene *scene, ListBase *dsources, bAction *act, KeyingSet
else if (mode == MODIFYKEY_MODE_DELETE)
kflag= 0;
- /* check if the KeyingSet is absolute or not (i.e. does it requires sources info) */
- if (ks->flag & KEYINGSET_ABSOLUTE) {
- /* Absolute KeyingSets are simpler to use, as all the destination info has already been
- * provided by the user, and is stored, ready to use, in the KeyingSet paths.
+ /* if relative Keying Sets, poll and build up the paths */
+ if ((ks->flag & KEYINGSET_ABSOLUTE) == 0) {
+ KeyingSetInfo *ksi = ANIM_keyingset_info_find_named(ks->typeinfo);
+
+ /* clear all existing paths
+ * NOTE: BKE_keyingset_free() frees all of the paths for the KeyingSet, but not the set itself
*/
- for (ksp= ks->paths.first; ksp; ksp= ksp->next) {
- int arraylen, i;
-
- /* 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;
-
- /* 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(ksp->id, &id_ptr);
- if (RNA_path_resolve(&id_ptr, ksp->rna_path, &ptr, &prop) && prop)
- arraylen= RNA_property_array_length(&ptr, prop);
- }
-
- /* we should do at least one step */
- if (arraylen == i)
- arraylen++;
-
- /* for each possible index, perform operation
- * - assume that arraylen is greater than index
+ BKE_keyingset_free(ks);
+
+ /* get the associated 'type info' for this KeyingSet */
+ if (ksi == NULL)
+ return MODIFYKEY_MISSING_TYPEINFO;
+ // TODO: check for missing callbacks!
+
+ /* check if it can be used in the current context */
+ if (ksi->poll(ksi, C)) {
+ /* if a list of data sources are provided, run a special iterator over them,
+ * otherwise, just continue per normal
*/
- for (; i < arraylen; i++) {
- /* action to take depends on mode */
- if (mode == MODIFYKEY_MODE_INSERT)
- success += insert_keyframe(ksp->id, act, groupname, ksp->rna_path, i, cfra, kflag);
- else if (mode == MODIFYKEY_MODE_DELETE)
- success += delete_keyframe(ksp->id, act, groupname, ksp->rna_path, i, cfra, kflag);
- }
-
- /* set recalc-flags */
- if (ksp->id) {
- switch (GS(ksp->id->name)) {
- case ID_OB: /* Object (or Object-Related) Keyframes */
- {
- Object *ob= (Object *)ksp->id;
-
- ob->recalc |= OB_RECALC;
- }
- break;
- }
+ if (dsources)
+ RKS_ITER_overrides_list(ksi, C, ks, dsources);
+ else
+ ksi->iter(ksi, C, ks);
- /* send notifiers for updates (this doesn't require context to work!) */
- WM_main_add_notifier(NC_ANIMATION|ND_KEYFRAME_EDIT, NULL);
- }
+ /* if we don't have any paths now, then this still qualifies as invalid context */
+ if (ks->paths.first == NULL)
+ return MODIFYKEY_INVALID_CONTEXT;
+ }
+ else {
+ /* poll callback tells us that KeyingSet is useless in current context */
+ return MODIFYKEY_INVALID_CONTEXT;
}
}
- else if (dsources && dsources->first) {
- /* for each one of the 'sources', resolve the template markers and expand arrays, then insert keyframes */
- bCommonKeySrc *cks;
+
+ /* apply the paths as specified in the KeyingSet now */
+ for (ksp= ks->paths.first; ksp; ksp= ksp->next) {
+ int arraylen, i;
+ short kflag2;
- /* 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;
-
- /* set initial group name */
- if (cks->id == NULL) {
- printf("ERROR: Skipping 'Common-Key' Source. No valid ID present.\n");
- continue;
- }
- else
- groupname= cks->id->name+2;
-
- /* 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.bones[\"");
- BLI_dynstr_append(pathds, cks->pchan->name);
- BLI_dynstr_append(pathds, "\"]");
-
- /* override default group name */
- groupname= cks->pchan->name;
- }
- 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, "\"]");
-
- /* override default group name */
- groupname= cks->con->name;
- }
+ /* since keying settings can be defined on the paths too, extend the path before using it */
+ kflag2 = (kflag | ksp->keyingflag);
+
+ /* 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;
+
+ /* 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(ksp->id, &id_ptr);
+ if (RNA_path_resolve(&id_ptr, ksp->rna_path, &ptr, &prop) && prop)
+ arraylen= RNA_property_array_length(&ptr, prop);
+ }
+
+ /* we should do at least one step */
+ if (arraylen == i)
+ arraylen++;
+
+ /* 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 == MODIFYKEY_MODE_INSERT)
+ success += insert_keyframe(ksp->id, act, groupname, ksp->rna_path, i, cfra, kflag2);
+ else if (mode == MODIFYKEY_MODE_DELETE)
+ success += delete_keyframe(ksp->id, act, groupname, ksp->rna_path, i, cfra, kflag2);
+ }
+
+ /* set recalc-flags */
+ if (ksp->id) {
+ switch (GS(ksp->id->name)) {
+ case ID_OB: /* Object (or Object-Related) Keyframes */
{
- /* add property stored in KeyingSet Path */
- if (BLI_dynstr_get_len(pathds))
- BLI_dynstr_append(pathds, ".");
-
- /* apply some further templates? */
- if (ksp->templates & KSP_TEMPLATE_ROT) {
- /* for builtin Keying Sets, this template makes the best fitting path for the
- * current rotation mode of the Object / PoseChannel to be used
- */
- if (strcmp(ksp->rna_path, "rotation")==0) {
- /* get rotation mode */
- short rotmode= (cks->pchan)? (cks->pchan->rotmode) :
- (GS(cks->id->name)==ID_OB)? ( ((Object *)cks->id)->rotmode ) :
- (0);
-
- /* determine path to build */
- if (rotmode == ROT_MODE_QUAT)
- BLI_dynstr_append(pathds, "rotation_quaternion");
- else if (rotmode == ROT_MODE_AXISANGLE)
- BLI_dynstr_append(pathds, "rotation_axis_angle");
- else
- BLI_dynstr_append(pathds, "rotation_euler");
- }
- }
- else {
- /* just directly use the path */
- 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
- * - KSP_GROUP_TEMPLATE_ITEM is handled above while constructing the paths
- */
- if (ksp->groupmode == KSP_GROUP_NONE)
- groupname= NULL;
- else if (ksp->groupmode == KSP_GROUP_KSNAME)
- groupname= ks->name;
- else if (ksp->groupmode == KSP_GROUP_NAMED)
- 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;
+ Object *ob= (Object *)ksp->id;
- 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 == MODIFYKEY_MODE_INSERT)
- success+= insert_keyframe(cks->id, act, groupname, path, i, cfra, kflag);
- else if (mode == MODIFYKEY_MODE_DELETE)
- success+= delete_keyframe(cks->id, act, groupname, path, i, cfra, kflag);
+ ob->recalc |= OB_RECALC;
}
-
- /* free the path */
- MEM_freeN(path);
+ break;
}
- /* set recalc-flags */
- if (cks->id) {
- switch (GS(cks->id->name)) {
- case ID_OB: /* Object (or Object-Related) Keyframes */
- {
- Object *ob= (Object *)cks->id;
-
- ob->recalc |= OB_RECALC;
- }
- break;
- }
-
- /* send notifiers for updates (this doesn't require context to work!) */
- WM_main_add_notifier(NC_ANIMATION|ND_KEYFRAME_EDIT, NULL);
- }
+ /* send notifiers for updates (this doesn't require context to work!) */
+ WM_main_add_notifier(NC_ANIMATION|ND_KEYFRAME_EDIT, NULL);
}
}
diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c
index 4a3ef38daa6..3f26a146c53 100644
--- a/source/blender/editors/armature/editarmature.c
+++ b/source/blender/editors/armature/editarmature.c
@@ -4867,12 +4867,7 @@ static int pose_clear_scale_exec(bContext *C, wmOperator *op)
Object *ob= CTX_data_active_object(C);
KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Scaling");
- bCommonKeySrc cks;
- ListBase dsources = {&cks, &cks};
-
- /* init common-key-source for use by KeyingSets */
- memset(&cks, 0, sizeof(bCommonKeySrc));
- cks.id= &ob->id;
+ short autokey = 0;
/* only clear those channels that are not locked */
CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pose_bones) {
@@ -4885,13 +4880,12 @@ static int pose_clear_scale_exec(bContext *C, wmOperator *op)
/* do auto-keyframing as appropriate */
if (autokeyframe_cfra_can_key(scene, &ob->id)) {
- /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */
- cks.pchan= pchan;
- modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA);
-
/* clear any unkeyed tags */
if (pchan->bone)
pchan->bone->flag &= ~BONE_UNKEYED;
+
+ /* tag for autokeying later */
+ autokey = 1;
}
else {
/* add unkeyed tags */
@@ -4901,6 +4895,16 @@ static int pose_clear_scale_exec(bContext *C, wmOperator *op)
}
CTX_DATA_END;
+ /* perform autokeying on the bones if needed */
+ if (autokey) {
+ /* insert keyframes */
+ ANIM_apply_keyingset(C, NULL, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA);
+
+ /* now recalculate paths */
+ if ((ob->pose->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS))
+ ED_pose_recalculate_paths(C, scene, ob);
+ }
+
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
/* note, notifier might evolve */
@@ -4930,12 +4934,7 @@ static int pose_clear_loc_exec(bContext *C, wmOperator *op)
Object *ob= CTX_data_active_object(C);
KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Location");
- bCommonKeySrc cks;
- ListBase dsources = {&cks, &cks};
-
- /* init common-key-source for use by KeyingSets */
- memset(&cks, 0, sizeof(bCommonKeySrc));
- cks.id= &ob->id;
+ short autokey = 0;
/* only clear those channels that are not locked */
CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pose_bones) {
@@ -4949,13 +4948,12 @@ static int pose_clear_loc_exec(bContext *C, wmOperator *op)
/* do auto-keyframing as appropriate */
if (autokeyframe_cfra_can_key(scene, &ob->id)) {
- /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */
- cks.pchan= pchan;
- modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA);
-
/* clear any unkeyed tags */
if (pchan->bone)
pchan->bone->flag &= ~BONE_UNKEYED;
+
+ /* tag for autokeying later */
+ autokey = 1;
}
else {
/* add unkeyed tags */
@@ -4965,6 +4963,16 @@ static int pose_clear_loc_exec(bContext *C, wmOperator *op)
}
CTX_DATA_END;
+ /* perform autokeying on the bones if needed */
+ if (autokey) {
+ /* insert keyframes */
+ ANIM_apply_keyingset(C, NULL, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA);
+
+ /* now recalculate paths */
+ if ((ob->pose->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS))
+ ED_pose_recalculate_paths(C, scene, ob);
+ }
+
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
/* note, notifier might evolve */
@@ -4994,12 +5002,7 @@ static int pose_clear_rot_exec(bContext *C, wmOperator *op)
Object *ob= CTX_data_active_object(C);
KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Rotation");
- bCommonKeySrc cks;
- ListBase dsources = {&cks, &cks};
-
- /* init common-key-source for use by KeyingSets */
- memset(&cks, 0, sizeof(bCommonKeySrc));
- cks.id= &ob->id;
+ short autokey = 0;
/* only clear those channels that are not locked */
CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pose_bones) {
@@ -5097,13 +5100,12 @@ static int pose_clear_rot_exec(bContext *C, wmOperator *op)
/* do auto-keyframing as appropriate */
if (autokeyframe_cfra_can_key(scene, &ob->id)) {
- /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */
- cks.pchan= pchan;
- modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA);
-
/* clear any unkeyed tags */
if (pchan->bone)
pchan->bone->flag &= ~BONE_UNKEYED;
+
+ /* tag for autokeying later */
+ autokey = 1;
}
else {
/* add unkeyed tags */
@@ -5113,6 +5115,16 @@ static int pose_clear_rot_exec(bContext *C, wmOperator *op)
}
CTX_DATA_END;
+ /* perform autokeying on the bones if needed */
+ if (autokey) {
+ /* insert keyframes */
+ ANIM_apply_keyingset(C, NULL, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA);
+
+ /* now recalculate paths */
+ if ((ob->pose->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS))
+ ED_pose_recalculate_paths(C, scene, ob);
+ }
+
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
/* note, notifier might evolve */
diff --git a/source/blender/editors/armature/poseUtils.c b/source/blender/editors/armature/poseUtils.c
index e2fc2bd4088..ecc84aaf4bb 100644
--- a/source/blender/editors/armature/poseUtils.c
+++ b/source/blender/editors/armature/poseUtils.c
@@ -229,27 +229,28 @@ void poseAnim_mapping_autoKeyframe (bContext *C, Scene *scene, Object *ob, ListB
/* insert keyframes as necessary if autokeyframing */
if (autokeyframe_cfra_can_key(scene, &ob->id)) {
- bCommonKeySrc cks;
- ListBase dsources = {&cks, &cks};
tPChanFCurveLink *pfl;
- /* init common-key-source for use by KeyingSets */
- memset(&cks, 0, sizeof(bCommonKeySrc));
- cks.id= &ob->id;
-
/* iterate over each pose-channel affected, applying the changes */
for (pfl= pfLinks->first; pfl; pfl= pfl->next) {
+ ListBase dsources = {NULL, NULL};
bPoseChannel *pchan= pfl->pchan;
- /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */
- cks.pchan= pchan;
- /* insert keyframes */
+ /* add datasource override for the PoseChannel so KeyingSet will do right thing */
+ ANIM_relative_keyingset_add_source(&dsources, &ob->id, &RNA_PoseBone, pchan);
+
+ /* insert keyframes
+ * - these keyingsets here use dsources, since we need to specify exactly which keyframes get affected
+ */
if (pchan->flag & POSE_LOC)
- modify_keyframes(scene, &dsources, NULL, ks_loc, MODIFYKEY_MODE_INSERT, cframe);
+ ANIM_apply_keyingset(C, &dsources, NULL, ks_loc, MODIFYKEY_MODE_INSERT, cframe);
if (pchan->flag & POSE_ROT)
- modify_keyframes(scene, &dsources, NULL, ks_rot, MODIFYKEY_MODE_INSERT, cframe);
+ ANIM_apply_keyingset(C, &dsources, NULL, ks_rot, MODIFYKEY_MODE_INSERT, cframe);
if (pchan->flag & POSE_SIZE)
- modify_keyframes(scene, &dsources, NULL, ks_scale, MODIFYKEY_MODE_INSERT, cframe);
+ ANIM_apply_keyingset(C, &dsources, NULL, ks_scale, MODIFYKEY_MODE_INSERT, cframe);
+
+ /* free the temp info */
+ BLI_freelistN(&dsources);
}
}
}
diff --git a/source/blender/editors/armature/poselib.c b/source/blender/editors/armature/poselib.c
index 02194035ee9..8d38d0530ce 100644
--- a/source/blender/editors/armature/poselib.c
+++ b/source/blender/editors/armature/poselib.c
@@ -331,19 +331,14 @@ static int poselib_add_menu_invoke (bContext *C, wmOperator *op, wmEvent *evt)
static int poselib_add_exec (bContext *C, wmOperator *op)
{
- Scene *scene= CTX_data_scene(C);
Object *ob= CTX_data_active_object(C);
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;
@@ -373,25 +368,12 @@ static int poselib_add_exec (bContext *C, wmOperator *op)
/* validate name */
BLI_uniquename(&act->markers, marker, "Pose", '.', offsetof(TimeMarker, name), sizeof(marker->name));
- /* 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 || pchan->bone==arm->act_bone) {
- /* 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(scene, &dsources, act, poselib_ks_locrotscale, MODIFYKEY_MODE_INSERT, (float)frame);
- }
- }
- }
+ /* 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);
@@ -784,13 +766,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 */
@@ -798,21 +773,23 @@ 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};
+
+ /* get KeyingSet to use */
// TODO: for getting the KeyingSet used, we should really check which channels were affected
+ // TODO: this should get modified so that custom props are taken into account too!
if (poselib_ks_locrotscale == NULL)
poselib_ks_locrotscale= ANIM_builtin_keyingset_get_named(NULL, "LocRotScale");
- /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */
- cks.pchan= pchan;
-
- /* now insert the keyframe */
- modify_keyframes(scene, &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, poselib_ks_locrotscale, MODIFYKEY_MODE_INSERT, (float)CFRA);
+ BLI_freelistN(&dsources);
/* clear any unkeyed tags */
if (pchan->bone)
diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c
index a162c8eb21a..f20c79da17e 100644
--- a/source/blender/editors/armature/poseobject.c
+++ b/source/blender/editors/armature/poseobject.c
@@ -849,14 +849,14 @@ void free_posebuf(void)
{
if (g_posebuf) {
bPoseChannel *pchan;
-
+
for (pchan= g_posebuf->chanbase.first; pchan; pchan= pchan->next) {
if(pchan->prop) {
IDP_FreeProperty(pchan->prop);
MEM_freeN(pchan->prop);
}
}
-
+
/* was copied without constraints */
BLI_freelistN(&g_posebuf->chanbase);
MEM_freeN(g_posebuf);
@@ -908,9 +908,6 @@ void POSE_OT_copy (wmOperatorType *ot)
/* Pointers to the builtin KeyingSets that we want to use */
static KeyingSet *posePaste_ks_locrotscale = NULL; /* the only keyingset we'll need */
-/* transform.h */
-extern void autokeyframe_pose_cb_func(struct bContext *C, struct Scene *scene, struct View3D *v3d, struct Object *ob, int tmode, short targetless_ik);
-
static int pose_paste_exec (bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
@@ -919,13 +916,6 @@ static int pose_paste_exec (bContext *C, wmOperator *op)
char name[32];
int flip= RNA_boolean_get(op->ptr, "flipped");
- bCommonKeySrc cks;
- ListBase dsources = {&cks, &cks};
-
- /* init common-key-source for use by KeyingSets */
- memset(&cks, 0, sizeof(bCommonKeySrc));
- cks.id= &ob->id;
-
/* sanity checks */
if ELEM(NULL, ob, ob->pose)
return OPERATOR_CANCELLED;
@@ -974,14 +964,14 @@ static int pose_paste_exec (bContext *C, wmOperator *op)
else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
/* quat/euler to axis angle */
if (chan->rotmode > 0)
- eulO_to_axis_angle( pchan->rotAxis, &pchan->rotAngle,chan->eul, chan->rotmode);
+ eulO_to_axis_angle(pchan->rotAxis, &pchan->rotAngle, chan->eul, chan->rotmode);
else
- quat_to_axis_angle( pchan->rotAxis, &pchan->rotAngle,chan->quat);
+ quat_to_axis_angle(pchan->rotAxis, &pchan->rotAngle, chan->quat);
}
else {
/* euler/axis-angle to quat */
if (chan->rotmode > 0)
- eulO_to_quat( pchan->quat,chan->eul, chan->rotmode);
+ eulO_to_quat(pchan->quat, chan->eul, chan->rotmode);
else
axis_angle_to_quat(pchan->quat, chan->rotAxis, pchan->rotAngle);
}
@@ -998,10 +988,10 @@ static int pose_paste_exec (bContext *C, wmOperator *op)
else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
float eul[3];
- axis_angle_to_eulO( eul, EULER_ORDER_DEFAULT,pchan->rotAxis, pchan->rotAngle);
+ axis_angle_to_eulO(eul, EULER_ORDER_DEFAULT, pchan->rotAxis, pchan->rotAngle);
eul[1]*= -1;
eul[2]*= -1;
- eulO_to_axis_angle( pchan->rotAxis, &pchan->rotAngle,eul, EULER_ORDER_DEFAULT);
+ eulO_to_axis_angle(pchan->rotAxis, &pchan->rotAngle, eul, EULER_ORDER_DEFAULT);
// experimental method (uncomment to test):
#if 0
@@ -1013,62 +1003,55 @@ static int pose_paste_exec (bContext *C, wmOperator *op)
else {
float eul[3];
- quat_to_eul( eul,pchan->quat);
+ quat_to_eul(eul, pchan->quat);
eul[1]*= -1;
eul[2]*= -1;
- eul_to_quat( pchan->quat,eul);
+ eul_to_quat(pchan->quat, eul);
}
}
/* ID property */
- if(pchan->prop) {
+ if (pchan->prop) {
IDP_FreeProperty(pchan->prop);
MEM_freeN(pchan->prop);
pchan->prop= NULL;
}
-
- if(chan->prop) {
+
+ if (chan->prop)
pchan->prop= IDP_CopyProperty(chan->prop);
+
+ /* keyframing tagging */
+ if (autokeyframe_cfra_can_key(scene, &ob->id)) {
+ ListBase dsources = {NULL, NULL};
+
+ /* get KeyingSet to use */
+ // TODO: for getting the KeyingSet used, we should really check which channels were affected
+ // TODO: this should get modified so that custom props are taken into account too!
+ if (posePaste_ks_locrotscale == NULL)
+ posePaste_ks_locrotscale= ANIM_builtin_keyingset_get_named(NULL, "LocRotScale");
+
+ /* 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, &ob->id, &RNA_PoseBone, pchan);
+ ANIM_apply_keyingset(C, &dsources, NULL, posePaste_ks_locrotscale, MODIFYKEY_MODE_INSERT, (float)CFRA);
+ BLI_freelistN(&dsources);
+
+ /* clear any unkeyed tags */
+ if (chan->bone)
+ chan->bone->flag &= ~BONE_UNKEYED;
}
-
- /* auto key, TODO, fix up this INSERTAVAIL vs all other cases */
- if (IS_AUTOKEY_FLAG(INSERTAVAIL) == 0) { /* deal with this case later */
- if (autokeyframe_cfra_can_key(scene, &ob->id)) {
-
- /* Set keys on pose
- * - KeyingSet to use depends on rotation mode
- * (but that's handled by the templates code)
- */
- // TODO: for getting the KeyingSet used, we should really check which channels were affected
- if (posePaste_ks_locrotscale == NULL)
- posePaste_ks_locrotscale= ANIM_builtin_keyingset_get_named(NULL, "LocRotScale");
-
- /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */
- cks.pchan= pchan;
-
- modify_keyframes(scene, &dsources, NULL, posePaste_ks_locrotscale, MODIFYKEY_MODE_INSERT, (float)CFRA);
-
- /* clear any unkeyed tags */
- if (chan->bone)
- chan->bone->flag &= ~BONE_UNKEYED;
- }
- else {
- /* add unkeyed tags */
- if (chan->bone)
- chan->bone->flag |= BONE_UNKEYED;
- }
+ else {
+ /* add unkeyed tags */
+ if (chan->bone)
+ chan->bone->flag |= BONE_UNKEYED;
}
}
}
}
-
- if (IS_AUTOKEY_FLAG(INSERTAVAIL)) {
- View3D *v3d= CTX_wm_view3d(C);
- autokeyframe_pose_cb_func(C, scene, v3d, ob, TFM_TRANSLATION, 0);
- autokeyframe_pose_cb_func(C, scene, v3d, ob, TFM_ROTATION, 0);
- autokeyframe_pose_cb_func(C, scene, v3d, ob, TFM_TIME_SCALE, 0);
- }
-
+
/* Update event for pose and deformation children */
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
@@ -1077,13 +1060,13 @@ static int pose_paste_exec (bContext *C, wmOperator *op)
}
else {
/* need to trick depgraph, action is not allowed to execute on pose */
+ // XXX: this is probably not an issue anymore
where_is_pose(scene, ob);
ob->recalc= 0;
}
/* notifiers for updates */
WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
- WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); // XXX not really needed, but here for completeness...
return OPERATOR_FINISHED;
}
@@ -1754,13 +1737,7 @@ static int pose_flip_quats_exec (bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
Object *ob= CTX_data_active_object(C);
-
- bCommonKeySrc cks;
- ListBase dsources = {&cks, &cks};
-
- /* init common-key-source for use by KeyingSets */
- memset(&cks, 0, sizeof(bCommonKeySrc));
- cks.id= &ob->id;
+ KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, "LocRotScale");
/* loop through all selected pchans, flipping and keying (as needed) */
CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pose_bones)
@@ -1773,20 +1750,18 @@ static int pose_flip_quats_exec (bContext *C, wmOperator *op)
pchan->quat[2]= -pchan->quat[2];
pchan->quat[3]= -pchan->quat[3];
- /* perform auto-keying
- * NOTE: paths don't need recalculation here, since the orientations shouldn't have changed
- */
+ /* tagging */
if (autokeyframe_cfra_can_key(scene, &ob->id)) {
- /* Set keys on pose
- * - KeyingSet to use depends on rotation mode
- * (but that's handled by the templates code)
- */
- KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Rotation");
+ ListBase dsources = {NULL, NULL};
- /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */
- cks.pchan= pchan;
-
- modify_keyframes(scene, &dsources, NULL, ks, 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, &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)
diff --git a/source/blender/editors/include/ED_keyframing.h b/source/blender/editors/include/ED_keyframing.h
index 2c58d9e3ff5..576069d78e8 100644
--- a/source/blender/editors/include/ED_keyframing.h
+++ b/source/blender/editors/include/ED_keyframing.h
@@ -89,8 +89,6 @@ int insert_vert_fcurve(struct FCurve *fcu, float x, float y, short flag);
*/
short insert_keyframe_direct(struct PointerRNA ptr, struct PropertyRNA *prop, struct FCurve *fcu, float cfra, short flag);
-
-
/* -------- */
/* Main Keyframing API calls:
@@ -106,48 +104,92 @@ short delete_keyframe(struct ID *id, struct bAction *act, const char group[], co
/* ************ Keying Sets ********************** */
-/* temporary struct to gather data combos to keyframe
- * (is used by modify_keyframes for 'relative' KeyingSets, provided via the dsources arg)
- */
-typedef struct bCommonKeySrc {
- struct bCommonKeySrc *next, *prev;
-
- /* general data/destination-source settings */
- struct ID *id; /* id-block this comes from */
+/* forward decl. for this struct which is declared a bit later... */
+struct KeyingSetInfo;
+
+/* Polling Callback for KeyingSets */
+typedef int (*cbKeyingSet_Poll)(struct KeyingSetInfo *ksi, struct bContext *C);
+/* Context Iterator Callback for KeyingSets */
+typedef void (*cbKeyingSet_Iterator)(struct KeyingSetInfo *ksi, struct bContext *C, struct KeyingSet *ks);
+/* Property Specifier Callback for KeyingSets (called from iterators) */
+typedef void (*cbKeyingSet_Generate)(struct KeyingSetInfo *ksi, struct bContext *C, struct KeyingSet *ks, struct PointerRNA *ptr);
+
+
+/* Callback info for 'Procedural' KeyingSets to use */
+typedef struct KeyingSetInfo {
+ struct KeyingSetInfo *next, *prev;
+
+ /* info */
+ /* identifier so that user can hook this up to a KeyingSet */
+ char name[64];
+ /* keying settings */
+ short keyingflag;
+ /* builtin? */
+ short builtin;
+
+ /* polling callbacks */
+ /* callback for polling the context for whether the right data is available */
+ cbKeyingSet_Poll poll;
- /* specific cases */
- struct bPoseChannel *pchan;
- struct bConstraint *con;
-} bCommonKeySrc;
+ /* generate callbacks */
+ /* iterator to use to go through collections of data in context
+ * - this callback is separate from the 'adding' stage, allowing
+ * BuiltIn KeyingSets to be manually specified to use
+ */
+ cbKeyingSet_Iterator iter;
+ /* generator to use to add properties based on the data found by iterator */
+ cbKeyingSet_Generate generate;
+
+ /* RNA integration */
+ ExtensionRNA ext;
+} KeyingSetInfo;
/* -------- */
+/* Add another data source for Relative Keying Sets to be evaluated with */
+void ANIM_relative_keyingset_add_source(ListBase *dsources, struct ID *id, struct StructRNA *srna, void *data);
+
+
/* mode for modify_keyframes */
typedef enum eModifyKey_Modes {
MODIFYKEY_MODE_INSERT = 0,
MODIFYKEY_MODE_DELETE,
} eModifyKey_Modes;
-/* Keyframing Helper Call - use the provided Keying Set to Add/Remove Keyframes */
-int modify_keyframes(struct Scene *scene, struct ListBase *dsources, struct bAction *act, struct KeyingSet *ks, short mode, float cfra);
+/* return codes for errors (with Relative KeyingSets) */
+typedef enum eModifyKey_Returns {
+ /* context info was invalid for using the Keying Set */
+ MODIFYKEY_INVALID_CONTEXT = -1,
+ /* there isn't any typeinfo for generating paths from context */
+ MODIFYKEY_MISSING_TYPEINFO = -2,
+} eModifyKey_Returns;
-/* -------- */
+/* use the specified KeyingSet to add/remove various Keyframes on the specified frame */
+int ANIM_apply_keyingset(struct bContext *C, ListBase *dsources, struct bAction *act, struct KeyingSet *ks, short mode, float cfra);
-/* Generate menu of KeyingSets */
-char *ANIM_build_keyingsets_menu(struct ListBase *list, short for_edit);
+/* -------- */
/* Get the first builtin KeyingSet with the given name, which occurs after the given one (or start of list if none given) */
-struct KeyingSet *ANIM_builtin_keyingset_get_named(struct KeyingSet *prevKS, char name[]);
+struct KeyingSet *ANIM_builtin_keyingset_get_named(struct KeyingSet *prevKS, const char name[]);
+
+/* Find KeyingSet type info given a name */
+KeyingSetInfo *ANIM_keyingset_info_find_named(const char name[]);
-/* Initialise builtin KeyingSets on startup */
-void init_builtin_keyingsets(void);
+/* for RNA type registrations... */
+void ANIM_keyingset_info_register(const struct bContext *C, KeyingSetInfo *ksi);
+void ANIM_keyingset_info_unregister(const struct bContext *C, KeyingSetInfo *ksi);
+/* cleanup on exit */
+void ANIM_keyingset_infos_exit(void);
/* -------- */
/* Get the active KeyingSet for the given scene */
struct KeyingSet *ANIM_scene_get_active_keyingset(struct Scene *scene);
+/* Check if KeyingSet can be used in the current context */
+short ANIM_keyingset_context_ok_poll(struct bContext *C, struct KeyingSet *ks);
+
/* ************ Drivers ********************** */
/* Returns whether there is a driver in the copy/paste buffer to paste */
diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c
index 30df347bc60..db15322bbc4 100644
--- a/source/blender/editors/object/object_transform.c
+++ b/source/blender/editors/object/object_transform.c
@@ -75,32 +75,35 @@
static int object_location_clear_exec(bContext *C, wmOperator *op)
{
- Scene *scene= CTX_data_scene(C);
-
+ Scene *scene = CTX_data_scene(C);
KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Location");
- bCommonKeySrc cks;
- ListBase dsources = {&cks, &cks};
-
- /* init common-key-source for use by KeyingSets */
- memset(&cks, 0, sizeof(bCommonKeySrc));
/* clear location of selected objects if not in weight-paint mode */
CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) {
- if(!(ob->mode & OB_MODE_WEIGHT_PAINT)) {
- if((ob->protectflag & OB_LOCK_LOCX)==0)
+ if (!(ob->mode & OB_MODE_WEIGHT_PAINT)) {
+ /* clear location if not locked */
+ if ((ob->protectflag & OB_LOCK_LOCX)==0)
ob->loc[0]= ob->dloc[0]= 0.0f;
- if((ob->protectflag & OB_LOCK_LOCY)==0)
+ if ((ob->protectflag & OB_LOCK_LOCY)==0)
ob->loc[1]= ob->dloc[1]= 0.0f;
- if((ob->protectflag & OB_LOCK_LOCZ)==0)
+ if ((ob->protectflag & OB_LOCK_LOCZ)==0)
ob->loc[2]= ob->dloc[2]= 0.0f;
- /* do auto-keyframing as appropriate */
+ /* auto keyframing */
if (autokeyframe_cfra_can_key(scene, &ob->id)) {
- /* init cks for this object, then use the relative KeyingSets to keyframe it */
- cks.id= &ob->id;
- modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA);
+ ListBase dsources = {NULL, NULL};
+
+ /* 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, &ob->id, NULL, NULL);
+ ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA);
+ BLI_freelistN(&dsources);
}
}
+
ob->recalc |= OB_RECALC_OB;
}
CTX_DATA_END;
@@ -131,17 +134,12 @@ void OBJECT_OT_location_clear(wmOperatorType *ot)
static int object_rotation_clear_exec(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
-
KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Rotation");
- bCommonKeySrc cks;
- ListBase dsources = {&cks, &cks};
-
- /* init common-key-source for use by KeyingSets */
- memset(&cks, 0, sizeof(bCommonKeySrc));
/* clear rotation of selected objects if not in weight-paint mode */
CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) {
if(!(ob->mode & OB_MODE_WEIGHT_PAINT)) {
+ /* clear rotations that aren't locked */
if (ob->protectflag & (OB_LOCK_ROTX|OB_LOCK_ROTY|OB_LOCK_ROTZ|OB_LOCK_ROTW)) {
if (ob->protectflag & OB_LOCK_ROT4D) {
/* perform clamping on a component by component basis */
@@ -233,13 +231,21 @@ static int object_rotation_clear_exec(bContext *C, wmOperator *op)
}
}
- /* do auto-keyframing as appropriate */
+ /* auto keyframing */
if (autokeyframe_cfra_can_key(scene, &ob->id)) {
- /* init cks for this object, then use the relative KeyingSets to keyframe it */
- cks.id= &ob->id;
- modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA);
+ ListBase dsources = {NULL, NULL};
+
+ /* 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, &ob->id, NULL, NULL);
+ ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA);
+ BLI_freelistN(&dsources);
}
}
+
ob->recalc |= OB_RECALC_OB;
}
CTX_DATA_END;
@@ -270,35 +276,37 @@ void OBJECT_OT_rotation_clear(wmOperatorType *ot)
static int object_scale_clear_exec(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
-
KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Scaling");
- bCommonKeySrc cks;
- ListBase dsources = {&cks, &cks};
-
- /* init common-key-source for use by KeyingSets */
- memset(&cks, 0, sizeof(bCommonKeySrc));
/* clear scales of selected objects if not in weight-paint mode */
CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) {
if(!(ob->mode & OB_MODE_WEIGHT_PAINT)) {
- if((ob->protectflag & OB_LOCK_SCALEX)==0) {
+ /* clear scale factors which are not locked */
+ if ((ob->protectflag & OB_LOCK_SCALEX)==0) {
ob->dsize[0]= 0.0f;
ob->size[0]= 1.0f;
}
- if((ob->protectflag & OB_LOCK_SCALEY)==0) {
+ if ((ob->protectflag & OB_LOCK_SCALEY)==0) {
ob->dsize[1]= 0.0f;
ob->size[1]= 1.0f;
}
- if((ob->protectflag & OB_LOCK_SCALEZ)==0) {
+ if ((ob->protectflag & OB_LOCK_SCALEZ)==0) {
ob->dsize[2]= 0.0f;
ob->size[2]= 1.0f;
}
- /* do auto-keyframing as appropriate */
+ /* auto keyframing */
if (autokeyframe_cfra_can_key(scene, &ob->id)) {
- /* init cks for this object, then use the relative KeyingSets to keyframe it */
- cks.id= &ob->id;
- modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA);
+ ListBase dsources = {NULL, NULL};
+
+ /* 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, &ob->id, NULL, NULL);
+ ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA);
+ BLI_freelistN(&dsources);
}
}
ob->recalc |= OB_RECALC_OB;
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index 38a7163d35f..828d5368834 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -2323,7 +2323,7 @@ static void flyEvent(FlyInfo *fly, wmEvent *event)
}
}
-static int flyApply(FlyInfo *fly)
+static int flyApply(bContext *C, FlyInfo *fly)
{
/*
fly mode - Shift+F
@@ -2606,13 +2606,10 @@ static int flyApply(FlyInfo *fly)
/* record the motion */
if (autokeyframe_cfra_can_key(scene, id_key)) {
- bCommonKeySrc cks;
- ListBase dsources = {&cks, &cks};
- int cfra = CFRA;
+ ListBase dsources = {NULL, NULL};
- /* init common-key-source for use by KeyingSets */
- memset(&cks, 0, sizeof(bCommonKeySrc));
- cks.id= id_key;
+ /* add datasource override for the camera object */
+ ANIM_relative_keyingset_add_source(&dsources, id_key, NULL, NULL);
/* insert keyframes
* 1) on the first frame
@@ -2621,12 +2618,15 @@ static int flyApply(FlyInfo *fly)
*/
if (fly->xlock || fly->zlock || moffset[0] || moffset[1]) {
KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Rotation");
- modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
+ ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA);
}
if (fly->speed) {
KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Location");
- modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
+ ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA);
}
+
+ /* free temp data */
+ BLI_freelistN(&dsources);
}
}
} else
@@ -2689,7 +2689,7 @@ static int fly_modal(bContext *C, wmOperator *op, wmEvent *event)
flyEvent(fly, event);
if(event->type==TIMER && event->customdata == fly->timer)
- flyApply(fly);
+ flyApply(C, fly);
if(fly->redraw) {
ED_region_tag_redraw(CTX_wm_region(C));
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 372aa42bac3..9c570e10406 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -102,20 +102,7 @@
#include "BKE_report.h"
#include "BKE_scene.h"
-//#include "BIF_editview.h"
-//#include "BIF_editlattice.h"
-//#include "BIF_editconstraint.h"
-//#include "BIF_editmesh.h"
-//#include "BIF_editsima.h"
-//#include "BIF_editparticle.h"
#include "BIF_gl.h"
-//#include "BIF_poseobject.h"
-//#include "BIF_meshtools.h"
-//#include "BIF_mywindow.h"
-//#include "BIF_resources.h"
-//#include "BIF_screen.h"
-//#include "BIF_space.h"
-//#include "BIF_toolbox.h"
#include "ED_anim_api.h"
#include "ED_armature.h"
@@ -132,19 +119,11 @@
#include "UI_view2d.h"
-//#include "BSE_edit.h"
-//#include "BDR_editobject.h" // reset_slowparents()
-//#include "BDR_gpencil.h"
-
#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLI_editVert.h"
-//#include "editmesh.h"
-//
-//#include "blendef.h"
-//
-//#include "mydevice.h"
+#include "RNA_access.h"
extern ListBase editelems;
@@ -4484,20 +4463,21 @@ void autokeyframe_ob_cb_func(bContext *C, Scene *scene, View3D *v3d, Object *ob,
// TODO: this should probably be done per channel instead...
if (autokeyframe_cfra_can_key(scene, id)) {
KeyingSet *active_ks = ANIM_scene_get_active_keyingset(scene);
- bCommonKeySrc cks;
- ListBase dsources = {&cks, &cks};
+ ListBase dsources = {NULL, NULL};
float cfra= (float)CFRA; // xxx this will do for now
short flag = 0;
- /* init common-key-source for use by KeyingSets */
- memset(&cks, 0, sizeof(bCommonKeySrc));
- cks.id= &ob->id;
-
+ /* get flags used for inserting keyframes */
flag = ANIM_get_keyframing_flags(scene, 1);
+ /* add datasource override for the camera object */
+ ANIM_relative_keyingset_add_source(&dsources, id, NULL, NULL);
+
if (IS_AUTOKEY_FLAG(ONLYKEYINGSET) && (active_ks)) {
- /* only insert into active keyingset */
- modify_keyframes(scene, &dsources, NULL, active_ks, MODIFYKEY_MODE_INSERT, cfra);
+ /* only insert into active keyingset
+ * NOTE: we assume here that the active Keying Set does not need to have its iterator overridden spe
+ */
+ ANIM_apply_keyingset(C, NULL, NULL, active_ks, MODIFYKEY_MODE_INSERT, cfra);
}
else if (IS_AUTOKEY_FLAG(INSERTAVAIL)) {
AnimData *adt= ob->adt;
@@ -4543,22 +4523,25 @@ void autokeyframe_ob_cb_func(bContext *C, Scene *scene, View3D *v3d, Object *ob,
/* insert keyframes for the affected sets of channels using the builtin KeyingSets found */
if (doLoc) {
KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Location");
- modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
+ ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
}
if (doRot) {
KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Rotation");
- modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
+ ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
}
if (doScale) {
KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Scale");
- modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
+ ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
}
}
/* insert keyframe in all (transform) channels */
else {
KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "LocRotScale");
- modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
+ ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
}
+
+ /* free temp info */
+ BLI_freelistN(&dsources);
}
}
@@ -4579,15 +4562,9 @@ void autokeyframe_pose_cb_func(bContext *C, Scene *scene, View3D *v3d, Object *o
// TODO: this should probably be done per channel instead...
if (autokeyframe_cfra_can_key(scene, id)) {
KeyingSet *active_ks = ANIM_scene_get_active_keyingset(scene);
- bCommonKeySrc cks;
- ListBase dsources = {&cks, &cks};
float cfra= (float)CFRA;
short flag= 0;
- /* init common-key-source for use by KeyingSets */
- memset(&cks, 0, sizeof(bCommonKeySrc));
- cks.id= &ob->id;
-
/* flag is initialised from UserPref keyframing settings
* - special exception for targetless IK - INSERTKEY_MATRIX keyframes should get
* visual keyframes even if flag not set, as it's not that useful otherwise
@@ -4600,14 +4577,18 @@ void autokeyframe_pose_cb_func(bContext *C, Scene *scene, View3D *v3d, Object *o
for (pchan=pose->chanbase.first; pchan; pchan=pchan->next) {
if (pchan->bone->flag & BONE_TRANSFORM) {
+ ListBase dsources = {NULL, NULL};
+
/* clear any 'unkeyed' flag it may have */
pchan->bone->flag &= ~BONE_UNKEYED;
+ /* add datasource override for the camera object */
+ ANIM_relative_keyingset_add_source(&dsources, id, &RNA_PoseBone, pchan);
+
/* only insert into active keyingset? */
+ // TODO: move this first case out of the loop
if (IS_AUTOKEY_FLAG(ONLYKEYINGSET) && (active_ks)) {
- /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */
- cks.pchan= pchan;
- modify_keyframes(scene, &dsources, NULL, active_ks, MODIFYKEY_MODE_INSERT, cfra);
+ ANIM_apply_keyingset(C, NULL, NULL, active_ks, MODIFYKEY_MODE_INSERT, cfra);
}
/* only insert into available channels? */
else if (IS_AUTOKEY_FLAG(INSERTAVAIL)) {
@@ -4656,34 +4637,25 @@ void autokeyframe_pose_cb_func(bContext *C, Scene *scene, View3D *v3d, Object *o
if (doLoc) {
KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Location");
-
- /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */
- cks.pchan= pchan;
- modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
+ ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
}
if (doRot) {
KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Rotation");
-
- /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */
- cks.pchan= pchan;
- modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
+ ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
}
if (doScale) {
KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Scale");
-
- /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */
- cks.pchan= pchan;
- modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
+ ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
}
}
/* insert keyframe in all (transform) channels */
else {
KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "LocRotScale");
-
- /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */
- cks.pchan= pchan;
- modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
+ ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
}
+
+ /* free temp info */
+ BLI_freelistN(&dsources);
}
}