diff options
Diffstat (limited to 'source/blender/makesrna/intern/rna_animation.c')
-rw-r--r-- | source/blender/makesrna/intern/rna_animation.c | 393 |
1 files changed, 374 insertions, 19 deletions
diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c index 453d9b9a844..e0cf4f912b1 100644 --- a/source/blender/makesrna/intern/rna_animation.c +++ b/source/blender/makesrna/intern/rna_animation.c @@ -26,7 +26,6 @@ #include "RNA_access.h" #include "RNA_define.h" -#include "RNA_types.h" #include "RNA_enum_types.h" #include "rna_internal.h" @@ -37,16 +36,19 @@ #include "MEM_guardedalloc.h" +#include "ED_keyframing.h" + /* exported for use in API */ EnumPropertyItem keyingset_path_grouping_items[] = { {KSP_GROUP_NAMED, "NAMED", 0, "Named Group", ""}, {KSP_GROUP_NONE, "NONE", 0, "None", ""}, {KSP_GROUP_KSNAME, "KEYINGSET", 0, "Keying Set Name", ""}, - {KSP_GROUP_TEMPLATE_ITEM, "TEMPLATE", 0, "Innermost Context-Item Name", ""}, {0, NULL, 0, NULL, NULL}}; #ifdef RNA_RUNTIME +#include "BKE_animsys.h" + static int rna_AnimData_action_editable(PointerRNA *ptr) { AnimData *adt= (AnimData *)ptr->data; @@ -66,6 +68,152 @@ static void rna_AnimData_action_set(PointerRNA *ptr, PointerRNA value) /* ****************************** */ +/* wrapper for poll callback */ +static int RKS_POLL_rna_internal(KeyingSetInfo *ksi, bContext *C) +{ + PointerRNA ptr; + ParameterList list; + FunctionRNA *func; + void *ret; + int ok; + + RNA_pointer_create(NULL, ksi->ext.srna, ksi, &ptr); + func= RNA_struct_find_function(&ptr, "poll"); + + RNA_parameter_list_create(&list, &ptr, func); + /* hook up arguments */ + RNA_parameter_set_lookup(&list, "ksi", &ksi); + RNA_parameter_set_lookup(&list, "context", &C); + + /* execute the function */ + ksi->ext.call(&ptr, func, &list); + + /* read the result */ + RNA_parameter_get_lookup(&list, "ok", &ret); + ok= *(int*)ret; + RNA_parameter_list_free(&list); + + return ok; +} + +/* wrapper for iterator callback */ +static void RKS_ITER_rna_internal(KeyingSetInfo *ksi, bContext *C, KeyingSet *ks) +{ + PointerRNA ptr; + ParameterList list; + FunctionRNA *func; + + RNA_pointer_create(NULL, ksi->ext.srna, ksi, &ptr); + func= RNA_struct_find_function(&ptr, "iterator"); + + RNA_parameter_list_create(&list, &ptr, func); + /* hook up arguments */ + RNA_parameter_set_lookup(&list, "ksi", &ksi); + RNA_parameter_set_lookup(&list, "context", &C); + RNA_parameter_set_lookup(&list, "ks", &ks); + + /* execute the function */ + ksi->ext.call(&ptr, func, &list); + RNA_parameter_list_free(&list); +} + +/* wrapper for generator callback */ +static void RKS_GEN_rna_internal(KeyingSetInfo *ksi, bContext *C, KeyingSet *ks, PointerRNA *data) +{ + PointerRNA ptr; + ParameterList list; + FunctionRNA *func; + + RNA_pointer_create(NULL, ksi->ext.srna, ksi, &ptr); + func= RNA_struct_find_function(&ptr, "generate"); + + RNA_parameter_list_create(&list, &ptr, func); + /* hook up arguments */ + RNA_parameter_set_lookup(&list, "ksi", &ksi); + RNA_parameter_set_lookup(&list, "context", &C); + RNA_parameter_set_lookup(&list, "ks", &ks); + RNA_parameter_set_lookup(&list, "data", data); + + /* execute the function */ + ksi->ext.call(&ptr, func, &list); + RNA_parameter_list_free(&list); +} + +/* ------ */ + +// XXX: the exact purpose of this is not too clear... maybe we want to revise this at some point? +static StructRNA *rna_KeyingSetInfo_refine(PointerRNA *ptr) +{ + KeyingSetInfo *ksi= (KeyingSetInfo *)ptr->data; + return (ksi->ext.srna)? ksi->ext.srna: &RNA_KeyingSetInfo; +} + +static void rna_KeyingSetInfo_unregister(const bContext *C, StructRNA *type) +{ + KeyingSetInfo *ksi= RNA_struct_blender_type_get(type); + + if (ksi == NULL) + return; + + /* free RNA data referencing this */ + RNA_struct_free_extension(type, &ksi->ext); + RNA_struct_free(&BLENDER_RNA, type); + + /* unlink Blender-side data */ + ANIM_keyingset_info_unregister(C, ksi); +} + +static StructRNA *rna_KeyingSetInfo_register(const bContext *C, ReportList *reports, void *data, const char *identifier, StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free) +{ + KeyingSetInfo dummyksi = {0}; + KeyingSetInfo *ksi; + PointerRNA dummyptr; + int have_function[3]; + + /* setup dummy type info to store static properties in */ + // TODO: perhaps we want to get users to register as if they're using 'KeyingSet' directly instead? + RNA_pointer_create(NULL, &RNA_KeyingSetInfo, &dummyksi, &dummyptr); + + /* validate the python class */ + if (validate(&dummyptr, data, have_function) != 0) + return NULL; + + if (strlen(identifier) >= sizeof(dummyksi.idname)) { + BKE_reportf(reports, RPT_ERROR, "registering keying set info class: '%s' is too long, maximum length is %d.", identifier, sizeof(dummyksi.idname)); + return NULL; + } + + /* check if we have registered this info before, and remove it */ + ksi = ANIM_keyingset_info_find_named(dummyksi.idname); + if (ksi && ksi->ext.srna) + rna_KeyingSetInfo_unregister(C, ksi->ext.srna); + + /* create a new KeyingSetInfo type */ + ksi= MEM_callocN(sizeof(KeyingSetInfo), "python keying set info"); + memcpy(ksi, &dummyksi, sizeof(KeyingSetInfo)); + + /* set RNA-extensions info */ + ksi->ext.srna= RNA_def_struct(&BLENDER_RNA, ksi->idname, "KeyingSetInfo"); + ksi->ext.data= data; + ksi->ext.call= call; + ksi->ext.free= free; + RNA_struct_blender_type_set(ksi->ext.srna, ksi); + + /* set callbacks */ + // NOTE: we really should have all of these... + ksi->poll= (have_function[0])? RKS_POLL_rna_internal: NULL; + ksi->iter= (have_function[1])? RKS_ITER_rna_internal: NULL; + ksi->generate= (have_function[2])? RKS_GEN_rna_internal: NULL; + + /* add and register with other info as needed */ + ANIM_keyingset_info_register(C, ksi); + + /* return the struct-rna added */ + return ksi->ext.srna; +} + +/* ****************************** */ + static StructRNA *rna_ksPath_id_typef(PointerRNA *ptr) { KS_Path *ksp= (KS_Path*)ptr->data; @@ -165,8 +313,167 @@ static void rna_KeyingSet_active_ksPath_index_range(PointerRNA *ptr, int *min, i *max= MAX2(0, *max); } +static PointerRNA rna_KeyingSet_typeinfo_get(PointerRNA *ptr) +{ + KeyingSet *ks= (KeyingSet *)ptr->data; + KeyingSetInfo *ksi = NULL; + + /* keying set info is only for builtin Keying Sets */ + if ((ks->flag & KEYINGSET_ABSOLUTE)==0) + ksi = ANIM_keyingset_info_find_named(ks->typeinfo); + return rna_pointer_inherit_refine(ptr, &RNA_KeyingSetInfo, ksi); +} + + + +static KS_Path *rna_KeyingSet_paths_add(KeyingSet *keyingset, ReportList *reports, + ID *id, char rna_path[], int index, int grouping_method, char group_name[]) +{ + KS_Path *ksp = NULL; + short flag = 0; + + /* special case when index = -1, we key the whole array (as with other places where index is used) */ + if (index == -1) { + flag |= KSP_FLAG_WHOLE_ARRAY; + index = 0; + } + + /* if data is valid, call the API function for this */ + if (keyingset) { + ksp= BKE_keyingset_add_path(keyingset, id, group_name, rna_path, index, flag, grouping_method); + keyingset->active_path= BLI_countlist(&keyingset->paths); + } + else { + BKE_report(reports, RPT_ERROR, "Keying Set Path could not be added."); + } + + /* return added path */ + return ksp; +} + +static void rna_KeyingSet_paths_remove(KeyingSet *keyingset, ReportList *reports, KS_Path *ksp) +{ + /* if data is valid, call the API function for this */ + if (keyingset && ksp) { + /* remove the active path from the KeyingSet */ + BKE_keyingset_free_path(keyingset, ksp); + + /* the active path number will most likely have changed */ + // TODO: we should get more fancy and actually check if it was removed, but this will do for now + keyingset->active_path = 0; + } + else { + BKE_report(reports, RPT_ERROR, "Keying Set Path could not be removed."); + } +} + +static void rna_KeyingSet_paths_clear(KeyingSet *keyingset, ReportList *reports) +{ + /* if data is valid, call the API function for this */ + if (keyingset) { + KS_Path *ksp, *kspn; + + /* free each path as we go to avoid looping twice */ + for (ksp= keyingset->paths.first; ksp; ksp= kspn) { + kspn= ksp->next; + BKE_keyingset_free_path(keyingset, ksp); + } + + /* reset the active path, since there aren't any left */ + keyingset->active_path = 0; + } + else { + BKE_report(reports, RPT_ERROR, "Keying Set Paths could not be removed."); + } +} + + #else +/* helper function for Keying Set -> keying settings */ +static void rna_def_common_keying_flags(StructRNA *srna, short reg) +{ + PropertyRNA *prop; + + prop= RNA_def_property(srna, "insertkey_needed", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "keyingflag", INSERTKEY_NEEDED); + RNA_def_property_ui_text(prop, "Insert Keyframes - Only Needed", "Only insert keyframes where they're needed in the relevant F-Curves"); + if (reg) RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL); + + prop= RNA_def_property(srna, "insertkey_visual", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "keyingflag", INSERTKEY_MATRIX); + RNA_def_property_ui_text(prop, "Insert Keyframes - Visual", "Insert keyframes based on 'visual transforms'"); + if (reg) RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL); + + prop= RNA_def_property(srna, "insertkey_xyz_to_rgb", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "keyingflag", INSERTKEY_XYZ2RGB); + RNA_def_property_ui_text(prop, "F-Curve Colors - XYZ to RGB", "Color for newly added transformation F-Curves (Location, Rotation, Scale) and also Color is based on the transform axis"); + if (reg) RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL); +} + +/* --- */ + +static void rna_def_keyingset_info(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + FunctionRNA *func; + PropertyRNA *parm; + + srna= RNA_def_struct(brna, "KeyingSetInfo", NULL); + RNA_def_struct_sdna(srna, "KeyingSetInfo"); + RNA_def_struct_ui_text(srna, "Keying Set Info", "Callback function defines for builtin Keying Sets"); + RNA_def_struct_refine_func(srna, "rna_KeyingSetInfo_refine"); + RNA_def_struct_register_funcs(srna, "rna_KeyingSetInfo_register", "rna_KeyingSetInfo_unregister"); + + /* Properties --------------------- */ + + RNA_define_verify_sdna(0); // not in sdna + + prop= RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "idname"); + RNA_def_property_flag(prop, PROP_REGISTER); + + /* Name */ + prop= RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "name"); + RNA_def_property_ui_text(prop, "Name", ""); + RNA_def_struct_name_property(srna, prop); + RNA_def_property_flag(prop, PROP_REGISTER); + + rna_def_common_keying_flags(srna, 1); /* '1' arg here is to indicate that we need these to be set on registering */ + + RNA_define_verify_sdna(1); + + /* Function Callbacks ------------- */ + /* poll */ + func= RNA_def_function(srna, "poll", NULL); + RNA_def_function_ui_description(func, "Test if Keying Set can be used or not"); + RNA_def_function_flag(func, FUNC_REGISTER); + RNA_def_function_return(func, RNA_def_boolean(func, "ok", 1, "", "")); + parm= RNA_def_pointer(func, "context", "Context", "", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + + /* iterator */ + func= RNA_def_function(srna, "iterator", NULL); + RNA_def_function_ui_description(func, "Call generate() on the structs which have properties to be keyframed"); + RNA_def_function_flag(func, FUNC_REGISTER); + parm= RNA_def_pointer(func, "context", "Context", "", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_pointer(func, "ks", "KeyingSet", "", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + + /* generate */ + func= RNA_def_function(srna, "generate", NULL); + RNA_def_function_ui_description(func, "Add Paths to the Keying Set to keyframe the properties of the given data"); + RNA_def_function_flag(func, FUNC_REGISTER); + parm= RNA_def_pointer(func, "context", "Context", "", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_pointer(func, "ks", "KeyingSet", "", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_pointer(func, "data", "AnyType", "", ""); + RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR|PROP_NEVER_NULL); +} static void rna_def_keyingset_path(BlenderRNA *brna) { @@ -215,6 +522,60 @@ static void rna_def_keyingset_path(BlenderRNA *brna) prop= RNA_def_property(srna, "entire_array", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", KSP_FLAG_WHOLE_ARRAY); RNA_def_property_ui_text(prop, "Entire Array", "When an 'array/vector' type is chosen (Location, Rotation, Color, etc.), entire array is to be used"); + + /* Keyframing Settings */ + rna_def_common_keying_flags(srna, 0); +} + + + +/* keyingset.paths */ +static void rna_def_keyingset_paths(BlenderRNA *brna, PropertyRNA *cprop) +{ + StructRNA *srna; + + FunctionRNA *func; + PropertyRNA *parm; + + RNA_def_property_srna(cprop, "KeyingSetPaths"); + srna= RNA_def_struct(brna, "KeyingSetPaths", NULL); + RNA_def_struct_sdna(srna, "KeyingSet"); + RNA_def_struct_ui_text(srna, "Keying set paths", "Collection of keying set paths"); + + + /* Add Path */ + func= RNA_def_function(srna, "add", "rna_KeyingSet_paths_add"); + RNA_def_function_ui_description(func, "Add a new path for the Keying Set."); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + /* return arg */ + parm= RNA_def_pointer(func, "ksp", "KeyingSetPath", "New Path", "Path created and added to the Keying Set"); + RNA_def_function_return(func, parm); + /* ID-block for target */ + parm= RNA_def_pointer(func, "target_id", "ID", "Target ID", "ID-Datablock for the destination."); + RNA_def_property_flag(parm, PROP_REQUIRED); + /* rna-path */ + parm= RNA_def_string(func, "data_path", "", 256, "Data-Path", "RNA-Path to destination property."); // xxx hopefully this is long enough + RNA_def_property_flag(parm, PROP_REQUIRED); + /* index (defaults to -1 for entire array) */ + parm=RNA_def_int(func, "index", -1, -1, INT_MAX, "Index", "The index of the destination property (i.e. axis of Location/Rotation/etc.), or -1 for the entire array.", 0, INT_MAX); + /* grouping */ + parm=RNA_def_enum(func, "grouping_method", keyingset_path_grouping_items, KSP_GROUP_KSNAME, "Grouping Method", "Method used to define which Group-name to use."); + parm=RNA_def_string(func, "group_name", "", 64, "Group Name", "Name of Action Group to assign destination to (only if grouping mode is to use this name)."); + + + /* Remove Path */ + func= RNA_def_function(srna, "remove", "rna_KeyingSet_paths_remove"); + RNA_def_function_ui_description(func, "Remove the given path from the Keying Set."); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + /* path to remove */ + parm= RNA_def_pointer(func, "path", "KeyingSetPath", "Path", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + + + /* Remove All Paths */ + func= RNA_def_function(srna, "clear", "rna_KeyingSet_paths_clear"); + RNA_def_function_ui_description(func, "Remove all the paths from the Keying Set."); + RNA_def_function_flag(func, FUNC_USE_REPORTS); } static void rna_def_keyingset(BlenderRNA *brna) @@ -228,13 +589,21 @@ static void rna_def_keyingset(BlenderRNA *brna) /* Name */ prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); RNA_def_property_ui_text(prop, "Name", ""); + RNA_def_struct_ui_icon(srna, ICON_KEY_HLT); // TODO: we need a dedicated icon RNA_def_struct_name_property(srna, prop); + /* KeyingSetInfo (Type Info) for Builtin Sets only */ + prop= RNA_def_property(srna, "type_info", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "KeyingSetInfo"); + RNA_def_property_pointer_funcs(prop, "rna_KeyingSet_typeinfo_get", NULL, NULL); + RNA_def_property_ui_text(prop, "Type Info", "Callback function defines for built-in Keying Sets"); + /* Paths */ prop= RNA_def_property(srna, "paths", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "paths", NULL); RNA_def_property_struct_type(prop, "KeyingSetPath"); RNA_def_property_ui_text(prop, "Paths", "Keying Set Paths to define settings that get keyframed together"); + rna_def_keyingset_paths(brna, prop); prop= RNA_def_property(srna, "active_path", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "KeyingSetPath"); @@ -249,28 +618,13 @@ static void rna_def_keyingset(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Active Path Index", "Current Keying Set index"); /* Flags */ - // XXX: depreceated - prop= RNA_def_property(srna, "builtin", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", KEYINGSET_BUILTIN); - RNA_def_property_ui_text(prop, "Built-In", "Keying Set is a built-in to Blender"); - prop= RNA_def_property(srna, "absolute", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", KEYINGSET_ABSOLUTE); - RNA_def_property_ui_text(prop, "Absolute", "Keying Set defines specific paths/settings to be keyframed (i.e. is not reliant on context info)"); + RNA_def_property_ui_text(prop, "Absolute", "Keying Set defines specific paths/settings to be keyframed (i.e. is not reliant on context info)"); /* Keyframing Flags */ - prop= RNA_def_property(srna, "insertkey_needed", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "keyingflag", INSERTKEY_NEEDED); - RNA_def_property_ui_text(prop, "Insert Keyframes - Only Needed", "Only insert keyframes where they're needed in the relevant F-Curves"); + rna_def_common_keying_flags(srna, 0); - prop= RNA_def_property(srna, "insertkey_visual", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "keyingflag", INSERTKEY_MATRIX); - RNA_def_property_ui_text(prop, "Insert Keyframes - Visual", "Insert keyframes based on 'visual transforms'"); - - prop= RNA_def_property(srna, "insertkey_xyz_to_rgb", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "keyingflag", INSERTKEY_XYZ2RGB); - RNA_def_property_ui_text(prop, "F-Curve Colors - XYZ to RGB", "Color for newly added transformation F-Curves (Location, Rotation, Scale) and also Color is based on the transform axis"); /* Keying Set API */ RNA_api_keyingset(srna); @@ -347,6 +701,7 @@ void RNA_def_animation(BlenderRNA *brna) rna_def_keyingset(brna); rna_def_keyingset_path(brna); + rna_def_keyingset_info(brna); } #endif |