/* Testing code for 2.5 animation system * Copyright 2009, Joshua Leung */ #include #include #include #include #include #include "MEM_guardedalloc.h" #include "BLI_blenlib.h" #include "BLI_arithb.h" #include "BLI_dynstr.h" #include "DNA_anim_types.h" #include "DNA_action_types.h" #include "DNA_armature_types.h" #include "DNA_constraint_types.h" #include "DNA_key_types.h" #include "DNA_object_types.h" #include "DNA_material_types.h" #include "DNA_scene_types.h" #include "DNA_userdef_types.h" #include "DNA_windowmanager_types.h" #include "BKE_animsys.h" #include "BKE_action.h" #include "BKE_constraint.h" #include "BKE_fcurve.h" #include "BKE_utildefines.h" #include "BKE_context.h" #include "BKE_report.h" #include "BKE_key.h" #include "BKE_material.h" #include "ED_anim_api.h" #include "ED_keyframing.h" #include "ED_keyframes_edit.h" #include "ED_screen.h" #include "ED_util.h" #include "UI_interface.h" #include "WM_api.h" #include "WM_types.h" #include "RNA_access.h" #include "RNA_define.h" #include "RNA_types.h" /* ************************************************** */ /* Animation Data Validation */ /* Get (or add relevant data to be able to do so) F-Curve from the driver stack, * for the given Animation Data block. This assumes that all the destinations are valid. */ FCurve *verify_driver_fcurve (ID *id, const char rna_path[], const int array_index, short add) { AnimData *adt; FCurve *fcu; /* sanity checks */ if ELEM(NULL, id, rna_path) return NULL; /* init animdata if none available yet */ adt= BKE_animdata_from_id(id); if ((adt == NULL) && (add)) adt= BKE_id_add_animdata(id); if (adt == NULL) { /* if still none (as not allowed to add, or ID doesn't have animdata for some reason) */ return NULL; } /* try to find f-curve matching for this setting * - add if not found and allowed to add one * TODO: add auto-grouping support? how this works will need to be resolved */ fcu= list_find_fcurve(&adt->drivers, rna_path, array_index); if ((fcu == NULL) && (add)) { /* use default settings to make a F-Curve */ fcu= MEM_callocN(sizeof(FCurve), "FCurve"); fcu->flag = (FCURVE_VISIBLE|FCURVE_AUTO_HANDLES|FCURVE_SELECTED); /* store path - make copy, and store that */ fcu->rna_path= BLI_strdupn(rna_path, strlen(rna_path)); fcu->array_index= array_index; /* add some new driver data */ fcu->driver= MEM_callocN(sizeof(ChannelDriver), "ChannelDriver"); /* add simple generator modifier for driver so that there is some visible representation */ fcurve_add_modifier(fcu, FMODIFIER_TYPE_GENERATOR); /* just add F-Curve to end of driver list */ BLI_addtail(&adt->drivers, fcu); } /* return the F-Curve */ return fcu; } /* ************************************************** */ /* Driver Management API */ /* Main Driver Management API calls: * Add a new driver for the specified property on the given ID block */ short ANIM_add_driver (ID *id, const char rna_path[], int array_index, short flag) { PointerRNA id_ptr, ptr; PropertyRNA *prop; FCurve *fcu; /* validate pointer first - exit if failure */ RNA_id_pointer_create(id, &id_ptr); if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) { printf("Insert Key: Could not add Driver, as RNA Path is invalid for the given ID (ID = %s, Path = %s)\n", id->name, rna_path); return 0; } /* create F-Curve with Driver */ fcu= verify_driver_fcurve(id, rna_path, array_index, 1); /* done */ return (fcu != NULL); } /* Main Driver Management API calls: * Remove the driver for the specified property on the given ID block (if available) */ short ANIM_remove_driver (struct ID *id, const char rna_path[], int array_index, short flag) { AnimData *adt; FCurve *fcu; /* get F-Curve * Note: here is one of the places where we don't want new F-Curve + Driver added! * so 'add' var must be 0 */ /* we don't check the validity of the path here yet, but it should be ok... */ fcu= verify_driver_fcurve(id, rna_path, array_index, 0); adt= BKE_animdata_from_id(id); /* only continue if we have an driver to remove */ if (adt && fcu) { /* remove F-Curve from driver stack, then free it */ BLI_remlink(&adt->drivers, fcu); free_fcurve(fcu); /* done successfully */ return 1; } /* failed */ return 0; } /* ************************************************** */ /* UI-Button Interface */ /* Add Driver Button Operator ------------------------ */ static int add_driver_button_exec (bContext *C, wmOperator *op) { PointerRNA ptr; PropertyRNA *prop= NULL; char *path; short success= 0; int a, index, length, all= RNA_boolean_get(op->ptr, "all"); /* try to insert keyframe using property retrieved from UI */ memset(&ptr, 0, sizeof(PointerRNA)); uiAnimContextProperty(C, &ptr, &prop, &index); if (ptr.data && prop && RNA_property_animateable(ptr.data, prop)) { path= RNA_path_from_ID_to_property(&ptr, prop); if (path) { if (all) { length= RNA_property_array_length(prop); if (length) index= 0; else length= 1; } else length= 1; for (a=0; aname= "Add Driver"; ot->idname= "ANIM_OT_add_driver_button"; /* callbacks */ ot->exec= add_driver_button_exec; //op->poll= ??? /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ RNA_def_boolean(ot->srna, "all", 1, "All", "Insert a keyframe for all element of the array."); } /* Remove Driver Button Operator ------------------------ */ static int remove_driver_button_exec (bContext *C, wmOperator *op) { PointerRNA ptr; PropertyRNA *prop= NULL; char *path; short success= 0; int a, index, length, all= RNA_boolean_get(op->ptr, "all"); /* try to insert keyframe using property retrieved from UI */ memset(&ptr, 0, sizeof(PointerRNA)); uiAnimContextProperty(C, &ptr, &prop, &index); if (ptr.data && prop) { path= RNA_path_from_ID_to_property(&ptr, prop); if (path) { if (all) { length= RNA_property_array_length(prop); if(length) index= 0; else length= 1; } else length= 1; for (a=0; aname= "Remove Driver"; ot->idname= "ANIM_OT_remove_driver_button"; /* callbacks */ ot->exec= remove_driver_button_exec; //op->poll= ??? /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; /* properties */ RNA_def_boolean(ot->srna, "all", 1, "All", "Delete keyfames from all elements of the array."); } /* ************************************************** */