remove unused includes
[blender.git] / source / blender / editors / animation / keyingsets.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2009 Blender Foundation, Joshua Leung
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): Joshua Leung (full recode)
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29  
30 #include <stdio.h>
31 #include <stddef.h>
32 #include <string.h>
33 #include <math.h>
34 #include <float.h>
35
36 #include "MEM_guardedalloc.h"
37
38 #include "BLI_blenlib.h"
39 #include "BLI_math.h"
40 #include "BLI_dynstr.h"
41
42 #include "DNA_anim_types.h"
43 #include "DNA_scene_types.h"
44 #include "DNA_object_types.h"
45
46 #include "BKE_main.h"
47 #include "BKE_animsys.h"
48 #include "BKE_context.h"
49 #include "BKE_depsgraph.h"
50 #include "BKE_report.h"
51
52 #include "ED_keyframing.h"
53 #include "ED_screen.h"
54
55 #include "UI_interface.h"
56
57 #include "WM_api.h"
58 #include "WM_types.h"
59
60 #include "RNA_access.h"
61 #include "RNA_define.h"
62
63 #include "anim_intern.h"
64
65 /* ************************************************** */
66 /* KEYING SETS - OPERATORS (for use in UI panels) */
67 /* These operators are really duplication of existing functionality, but just for completeness,
68  * they're here too, and will give the basic data needed...
69  */
70
71 /* poll callback for adding default KeyingSet */
72 static int keyingset_poll_default_add (bContext *C)
73 {
74         /* as long as there's an active Scene, it's fine */
75         return (CTX_data_scene(C) != NULL);
76 }
77
78 /* poll callback for editing active KeyingSet */
79 static int keyingset_poll_active_edit (bContext *C)
80 {
81         Scene *scene= CTX_data_scene(C);
82         
83         if (scene == NULL)
84                 return 0;
85         
86         /* there must be an active KeyingSet (and KeyingSets) */
87         return ((scene->active_keyingset > 0) && (scene->keyingsets.first));
88 }
89
90 /* poll callback for editing active KeyingSet Path */
91 static int keyingset_poll_activePath_edit (bContext *C)
92 {
93         Scene *scene= CTX_data_scene(C);
94         KeyingSet *ks;
95         
96         if (scene == NULL)
97                 return 0;
98         if (scene->active_keyingset <= 0)
99                 return 0;
100         else
101                 ks= BLI_findlink(&scene->keyingsets, scene->active_keyingset-1);
102         
103         /* there must be an active KeyingSet and an active path */
104         return ((ks) && (ks->paths.first) && (ks->active_path > 0));
105 }
106
107  
108 /* Add a Default (Empty) Keying Set ------------------------- */
109
110 static int add_default_keyingset_exec (bContext *C, wmOperator *op)
111 {
112         Scene *scene= CTX_data_scene(C);
113         short flag=0, keyingflag=0;
114         
115         /* validate flags 
116          *      - absolute KeyingSets should be created by default
117          */
118         flag |= KEYINGSET_ABSOLUTE;
119         
120         /* 2nd arg is 0 to indicate that we don't want to include autokeying mode related settings */
121         keyingflag = ANIM_get_keyframing_flags(scene, 0);
122         
123         /* call the API func, and set the active keyingset index */
124         BKE_keyingset_add(&scene->keyingsets, NULL, flag, keyingflag);
125         
126         scene->active_keyingset= BLI_countlist(&scene->keyingsets);
127         
128         /* send notifiers */
129         WM_event_add_notifier(C, NC_SCENE|ND_KEYINGSET, NULL);
130         
131         return OPERATOR_FINISHED;
132 }
133
134 void ANIM_OT_keying_set_add (wmOperatorType *ot)
135 {
136         /* identifiers */
137         ot->name= "Add Empty Keying Set";
138         ot->idname= "ANIM_OT_keying_set_add";
139         ot->description= "Add a new (empty) Keying Set to the active Scene";
140         
141         /* callbacks */
142         ot->exec= add_default_keyingset_exec;
143         ot->poll= keyingset_poll_default_add;
144 }
145
146 /* Remove 'Active' Keying Set ------------------------- */
147
148 static int remove_active_keyingset_exec (bContext *C, wmOperator *op)
149 {
150         Scene *scene= CTX_data_scene(C);
151         KeyingSet *ks;
152         
153         /* verify the Keying Set to use:
154          *      - use the active one
155          *      - return error if it doesn't exist
156          */
157         if (scene->active_keyingset == 0) {
158                 BKE_report(op->reports, RPT_ERROR, "No active Keying Set to remove");
159                 return OPERATOR_CANCELLED;
160         }
161         else if (scene->active_keyingset < 0) {
162                 BKE_report(op->reports, RPT_ERROR, "Cannot remove built in Keying Set");
163                 return OPERATOR_CANCELLED;
164         }
165         else
166                 ks= BLI_findlink(&scene->keyingsets, scene->active_keyingset-1);
167         
168         /* free KeyingSet's data, then remove it from the scene */
169         BKE_keyingset_free(ks);
170         BLI_freelinkN(&scene->keyingsets, ks);
171         
172         /* the active one should now be the previously second-to-last one */
173         scene->active_keyingset--;
174         
175         /* send notifiers */
176         WM_event_add_notifier(C, NC_SCENE|ND_KEYINGSET, NULL);
177         
178         return OPERATOR_FINISHED;
179 }
180
181 void ANIM_OT_keying_set_remove (wmOperatorType *ot)
182 {
183         /* identifiers */
184         ot->name= "Removed Active Keying Set";
185         ot->idname= "ANIM_OT_keying_set_remove";
186         ot->description= "Remove the active Keying Set";
187         
188         /* callbacks */
189         ot->exec= remove_active_keyingset_exec;
190         ot->poll= keyingset_poll_active_edit;
191 }
192
193 /* Add Empty Keying Set Path ------------------------- */
194
195 static int add_empty_ks_path_exec (bContext *C, wmOperator *op)
196 {
197         Scene *scene= CTX_data_scene(C);
198         KeyingSet *ks;
199         KS_Path *ksp;
200         
201         /* verify the Keying Set to use:
202          *      - use the active one
203          *      - return error if it doesn't exist
204          */
205         if (scene->active_keyingset == 0) {
206                 BKE_report(op->reports, RPT_ERROR, "No active Keying Set to add empty path to");
207                 return OPERATOR_CANCELLED;
208         }
209         else
210                 ks= BLI_findlink(&scene->keyingsets, scene->active_keyingset-1);
211         
212         /* don't use the API method for this, since that checks on values... */
213         ksp= MEM_callocN(sizeof(KS_Path), "KeyingSetPath Empty");
214         BLI_addtail(&ks->paths, ksp);
215         ks->active_path= BLI_countlist(&ks->paths);
216         
217         ksp->groupmode= KSP_GROUP_KSNAME; // XXX?
218         ksp->idtype= ID_OB;
219         
220         return OPERATOR_FINISHED;
221 }
222
223 void ANIM_OT_keying_set_path_add (wmOperatorType *ot)
224 {
225         /* identifiers */
226         ot->name= "Add Empty Keying Set Path";
227         ot->idname= "ANIM_OT_keying_set_path_add";
228         ot->description= "Add empty path to active Keying Set";
229         
230         /* callbacks */
231         ot->exec= add_empty_ks_path_exec;
232         ot->poll= keyingset_poll_active_edit;
233 }
234
235 /* Remove Active Keying Set Path ------------------------- */
236
237 static int remove_active_ks_path_exec (bContext *C, wmOperator *op)
238 {
239         Scene *scene= CTX_data_scene(C);
240         KeyingSet *ks= BLI_findlink(&scene->keyingsets, scene->active_keyingset-1);
241         
242         /* if there is a KeyingSet, find the nominated path to remove */
243         if (ks) {
244                 KS_Path *ksp= BLI_findlink(&ks->paths, ks->active_path-1);
245                 
246                 if (ksp) {
247                         /* remove the active path from the KeyingSet */
248                         BKE_keyingset_free_path(ks, ksp);
249                         
250                         /* the active path should now be the previously second-to-last active one */
251                         ks->active_path--;
252                 }
253                 else {
254                         BKE_report(op->reports, RPT_ERROR, "No active Keying Set Path to remove");
255                         return OPERATOR_CANCELLED;
256                 }
257         }
258         else {
259                 BKE_report(op->reports, RPT_ERROR, "No active Keying Set to remove a path from");
260                 return OPERATOR_CANCELLED;
261         }
262         
263         return OPERATOR_FINISHED;
264 }
265
266 void ANIM_OT_keying_set_path_remove (wmOperatorType *ot)
267 {
268         /* identifiers */
269         ot->name= "Remove Active Keying Set Path";
270         ot->idname= "ANIM_OT_keying_set_path_remove";
271         ot->description= "Remove active Path from active Keying Set";
272         
273         /* callbacks */
274         ot->exec= remove_active_ks_path_exec;
275         ot->poll= keyingset_poll_activePath_edit;
276 }
277
278 /* ************************************************** */
279 /* KEYING SETS - OPERATORS (for use in UI menus) */
280
281 /* Add to KeyingSet Button Operator ------------------------ */
282
283 static int add_keyingset_button_exec (bContext *C, wmOperator *op)
284 {
285         Main *bmain= CTX_data_main(C);
286         Scene *scene= CTX_data_scene(C);
287         KeyingSet *ks = NULL;
288         PropertyRNA *prop= NULL;
289         PointerRNA ptr;
290         char *path = NULL;
291         short success= 0;
292         int index=0, pflag=0;
293         int all= RNA_boolean_get(op->ptr, "all");
294         
295         /* verify the Keying Set to use:
296          *      - use the active one for now (more control over this can be added later)
297          *      - add a new one if it doesn't exist 
298          */
299         if (scene->active_keyingset == 0) {
300                 short flag=0, keyingflag=0;
301                 
302                 /* validate flags 
303                  *      - absolute KeyingSets should be created by default
304                  */
305                 flag |= KEYINGSET_ABSOLUTE;
306                 
307                 keyingflag |= ANIM_get_keyframing_flags(scene, 0);
308                 
309                 if (IS_AUTOKEY_FLAG(XYZ2RGB)) 
310                         keyingflag |= INSERTKEY_XYZ2RGB;
311                         
312                 /* call the API func, and set the active keyingset index */
313                 ks= BKE_keyingset_add(&scene->keyingsets, "ButtonKeyingSet", flag, keyingflag);
314                 
315                 scene->active_keyingset= BLI_countlist(&scene->keyingsets);
316         }
317         else if (scene->active_keyingset < 0) {
318                 BKE_report(op->reports, RPT_ERROR, "Cannot add property to built in Keying Set");
319                 return OPERATOR_CANCELLED;
320         }
321         else
322                 ks= BLI_findlink(&scene->keyingsets, scene->active_keyingset-1);
323         
324         /* try to add to keyingset using property retrieved from UI */
325         memset(&ptr, 0, sizeof(PointerRNA));
326         uiAnimContextProperty(C, &ptr, &prop, &index);
327         
328         /* check if property is able to be added */
329         if (ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
330                 path= RNA_path_from_ID_to_property(&ptr, prop);
331                 
332                 if (path) {
333                         /* set flags */
334                         if (all) {
335                                 pflag |= KSP_FLAG_WHOLE_ARRAY;
336                                 
337                                 /* we need to set the index for this to 0, even though it may break in some cases, this is 
338                                  * necessary if we want the entire array for most cases to get included without the user
339                                  * having to worry about where they clicked
340                                  */
341                                 index= 0;
342                         }
343                                 
344                         /* add path to this setting */
345                         BKE_keyingset_add_path(ks, ptr.id.data, NULL, path, index, pflag, KSP_GROUP_KSNAME);
346                         ks->active_path= BLI_countlist(&ks->paths);
347                         success= 1;
348                         
349                         /* free the temp path created */
350                         MEM_freeN(path);
351                 }
352         }
353         
354         if (success) {
355                 /* send updates */
356                 DAG_ids_flush_update(bmain, 0);
357                 
358                 /* for now, only send ND_KEYS for KeyingSets */
359                 WM_event_add_notifier(C, NC_SCENE|ND_KEYINGSET, NULL);
360         }
361         
362         return (success)? OPERATOR_FINISHED: OPERATOR_CANCELLED;
363 }
364
365 void ANIM_OT_keyingset_button_add (wmOperatorType *ot)
366 {
367         /* identifiers */
368         ot->name= "Add to Keying Set";
369         ot->idname= "ANIM_OT_keyingset_button_add";
370         
371         /* callbacks */
372         ot->exec= add_keyingset_button_exec; 
373         //op->poll= ???
374         
375         /* flags */
376         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
377
378         /* properties */
379         RNA_def_boolean(ot->srna, "all", 1, "All", "Add all elements of the array to a Keying Set.");
380 }
381
382 /* Remove from KeyingSet Button Operator ------------------------ */
383
384 static int remove_keyingset_button_exec (bContext *C, wmOperator *op)
385 {
386         Main *bmain= CTX_data_main(C);
387         Scene *scene= CTX_data_scene(C);
388         KeyingSet *ks = NULL;
389         PropertyRNA *prop= NULL;
390         PointerRNA ptr;
391         char *path = NULL;
392         short success= 0;
393         int index=0;
394         
395         /* verify the Keying Set to use:
396          *      - use the active one for now (more control over this can be added later)
397          *      - return error if it doesn't exist
398          */
399         if (scene->active_keyingset == 0) {
400                 BKE_report(op->reports, RPT_ERROR, "No active Keying Set to remove property from");
401                 return OPERATOR_CANCELLED;
402         }
403         else if (scene->active_keyingset < 0) {
404                 BKE_report(op->reports, RPT_ERROR, "Cannot remove property from built in Keying Set");
405                 return OPERATOR_CANCELLED;
406         }
407         else
408                 ks= BLI_findlink(&scene->keyingsets, scene->active_keyingset-1);
409         
410         /* try to add to keyingset using property retrieved from UI */
411         memset(&ptr, 0, sizeof(PointerRNA));
412         uiAnimContextProperty(C, &ptr, &prop, &index);
413
414         if (ptr.data && prop) {
415                 path= RNA_path_from_ID_to_property(&ptr, prop);
416                 
417                 if (path) {
418                         KS_Path *ksp;
419                         
420                         /* try to find a path matching this description */
421                         ksp= BKE_keyingset_find_path(ks, ptr.id.data, ks->name, path, index, KSP_GROUP_KSNAME);
422                         
423                         if (ksp) {
424                                 /* just free it... */
425                                 MEM_freeN(ksp->rna_path);
426                                 BLI_freelinkN(&ks->paths, ksp);
427                                 
428                                 success= 1;
429                         }
430                         
431                         /* free temp path used */
432                         MEM_freeN(path);
433                 }
434         }
435         
436         
437         if (success) {
438                 /* send updates */
439                 DAG_ids_flush_update(bmain, 0);
440                 
441                 /* for now, only send ND_KEYS for KeyingSets */
442                 WM_event_add_notifier(C, NC_SCENE|ND_KEYINGSET, NULL);
443         }
444         
445         return (success)? OPERATOR_FINISHED: OPERATOR_CANCELLED;
446 }
447
448 void ANIM_OT_keyingset_button_remove (wmOperatorType *ot)
449 {
450         /* identifiers */
451         ot->name= "Remove from Keying Set";
452         ot->idname= "ANIM_OT_keyingset_button_remove";
453         
454         /* callbacks */
455         ot->exec= remove_keyingset_button_exec; 
456         //op->poll= ???
457         
458         /* flags */
459         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
460 }
461
462 /* ******************************************* */
463
464 /* Change Active KeyingSet Operator ------------------------ */
465 /* This operator checks if a menu should be shown for choosing the KeyingSet to make the active one */
466
467 static int keyingset_active_menu_invoke (bContext *C, wmOperator *op, wmEvent *event)
468 {
469         /* call the menu, which will call this operator again, hence the cancelled */
470         ANIM_keying_sets_menu_setup(C, op->type->name, "ANIM_OT_keying_set_active_set");
471         return OPERATOR_CANCELLED;
472 }
473
474 static int keyingset_active_menu_exec (bContext *C, wmOperator *op)
475 {
476         Scene *scene= CTX_data_scene(C);
477         int type= RNA_int_get(op->ptr, "type");
478         
479         /* simply set the scene's active keying set index, unless the type == 0 
480          * (i.e. which happens if we want the current active to be maintained) 
481          */
482         if (type)
483                 scene->active_keyingset= type;
484                 
485         /* send notifiers */
486         WM_event_add_notifier(C, NC_SCENE|ND_KEYINGSET, NULL);
487         
488         return OPERATOR_FINISHED;
489 }
490  
491 void ANIM_OT_keying_set_active_set (wmOperatorType *ot)
492 {
493         /* identifiers */
494         ot->name= "Set Active Keying Set";
495         ot->idname= "ANIM_OT_keying_set_active_set";
496         
497         /* callbacks */
498         ot->invoke= keyingset_active_menu_invoke;
499         ot->exec= keyingset_active_menu_exec; 
500         ot->poll= ED_operator_areaactive;
501         
502         /* flags */
503         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
504         
505         /* keyingset to use
506          *      - here the type is int not enum, since many of the indicies here are determined dynamically
507          */
508         RNA_def_int(ot->srna, "type", 0, INT_MIN, INT_MAX, "Keying Set Number", "Index (determined internally) of the Keying Set to use", 0, 1);
509 }
510
511 /* ******************************************* */
512 /* REGISTERED KEYING SETS */
513
514 /* Keying Set Type Info declarations */
515 ListBase keyingset_type_infos = {NULL, NULL};
516
517 /* Built-In Keying Sets (referencing type infos)*/
518 ListBase builtin_keyingsets = {NULL, NULL};
519
520 /* --------------- */
521
522 /* Find KeyingSet type info given a name */
523 KeyingSetInfo *ANIM_keyingset_info_find_named (const char name[])
524 {
525         KeyingSetInfo *ksi;
526         
527         /* sanity checks */
528         if ((name == NULL) || (name[0] == 0))
529                 return NULL;
530                 
531         /* search by comparing names */
532         for (ksi = keyingset_type_infos.first; ksi; ksi = ksi->next) {
533                 if (strcmp(ksi->idname, name) == 0)
534                         return ksi;
535         }
536         
537         /* no matches found */
538         return NULL;
539 }
540
541 /* Find builtin KeyingSet by name */
542 KeyingSet *ANIM_builtin_keyingset_get_named (KeyingSet *prevKS, const char name[])
543 {
544         KeyingSet *ks, *first=NULL;
545         
546         /* sanity checks  any name to check? */
547         if (name[0] == 0)
548                 return NULL;
549         
550         /* get first KeyingSet to use */
551         if (prevKS && prevKS->next)
552                 first= prevKS->next;
553         else
554                 first= builtin_keyingsets.first;
555                 
556         /* loop over KeyingSets checking names */
557         for (ks= first; ks; ks= ks->next) {
558                 if (strcmp(name, ks->name) == 0)
559                         return ks;
560         }
561         
562         /* no matches found */
563         return NULL;
564 }
565
566 /* --------------- */
567
568 /* Add the given KeyingSetInfo to the list of type infos, and create an appropriate builtin set too */
569 void ANIM_keyingset_info_register (const bContext *C, KeyingSetInfo *ksi)
570 {
571         KeyingSet *ks;
572         
573         /* create a new KeyingSet 
574          *      - inherit name and keyframing settings from the typeinfo
575          */
576         ks = BKE_keyingset_add(&builtin_keyingsets, ksi->name, 1, ksi->keyingflag);
577         
578         /* link this KeyingSet with its typeinfo */
579         memcpy(&ks->typeinfo, ksi->idname, sizeof(ks->typeinfo));
580         
581         /* add type-info to the list */
582         BLI_addtail(&keyingset_type_infos, ksi);
583 }
584
585 /* Remove the given KeyingSetInfo from the list of type infos, and also remove the builtin set if appropriate */
586 void ANIM_keyingset_info_unregister (const bContext *C, KeyingSetInfo *ksi)
587 {
588         Main *bmain= CTX_data_main(C);
589         KeyingSet *ks, *ksn;
590         
591         /* find relevant builtin KeyingSets which use this, and remove them */
592         // TODO: this isn't done now, since unregister is really only used atm when we
593         // reload the scripts, which kindof defeats the purpose of "builtin"?
594         for (ks= builtin_keyingsets.first; ks; ks= ksn) {
595                 ksn = ks->next;
596                 
597                 /* remove if matching typeinfo name */
598                 if (strcmp(ks->typeinfo, ksi->idname) == 0) {
599                         Scene *scene;
600                         BKE_keyingset_free(ks);
601                         BLI_remlink(&builtin_keyingsets, ks);
602
603                         for(scene= bmain->scene.first; scene; scene= scene->id.next)
604                                 BLI_remlink_safe(&scene->keyingsets, ks);
605
606                         MEM_freeN(ks);
607                 }
608         }
609         
610         /* free the type info */
611         BLI_freelinkN(&keyingset_type_infos, ksi);
612 }
613
614 /* --------------- */
615
616 void ANIM_keyingset_infos_exit ()
617 {
618         KeyingSetInfo *ksi, *next;
619         
620         /* free type infos */
621         for (ksi=keyingset_type_infos.first; ksi; ksi=next) {
622                 next= ksi->next;
623                 
624                 /* free extra RNA data, and remove from list */
625                 if (ksi->ext.free)
626                         ksi->ext.free(ksi->ext.data);
627                 BLI_freelinkN(&keyingset_type_infos, ksi);
628         }
629         
630         /* free builtin sets */
631         BKE_keyingsets_free(&builtin_keyingsets);
632 }
633
634 /* ******************************************* */
635 /* KEYING SETS API (for UI) */
636
637 /* Getters for Active/Indices ----------------------------- */
638
639 /* Get the active Keying Set for the Scene provided */
640 KeyingSet *ANIM_scene_get_active_keyingset (Scene *scene)
641 {
642         /* if no scene, we've got no hope of finding the Keying Set */
643         if (scene == NULL)
644                 return NULL;
645         
646         /* currently, there are several possibilities here:
647          *      -   0: no active keying set
648          *      - > 0: one of the user-defined Keying Sets, but indices start from 0 (hence the -1)
649          *      - < 0: a builtin keying set
650          */
651         if (scene->active_keyingset > 0)
652                 return BLI_findlink(&scene->keyingsets, scene->active_keyingset-1);
653         else
654                 return BLI_findlink(&builtin_keyingsets, (-scene->active_keyingset)-1);
655 }
656
657 /* Get the index of the Keying Set provided, for the given Scene */
658 int ANIM_scene_get_keyingset_index (Scene *scene, KeyingSet *ks)
659 {
660         int index;
661         
662         /* if no KeyingSet provided, have none */
663         if (ks == NULL)
664                 return 0;
665         
666         /* check if the KeyingSet exists in scene list */
667         if (scene) {
668                 /* get index and if valid, return 
669                  *      - (absolute) Scene KeyingSets are from (>= 1)
670                  */
671                 index = BLI_findindex(&scene->keyingsets, ks);
672                 if (index != -1)
673                         return (index + 1);
674         }
675         
676         /* still here, so try builtins list too 
677          *      - builtins are from (<= -1)
678          *      - none/invalid is (= 0)
679          */
680         index = BLI_findindex(&builtin_keyingsets, ks);
681         if (index != -1)
682                 return -(index + 1);
683         else
684                 return 0;
685 }
686
687 /* Menu of All Keying Sets ----------------------------- */
688
689 /* Create (and show) a menu containing all the Keying Sets which can be used in the current context */
690 void ANIM_keying_sets_menu_setup (bContext *C, char title[], char op_name[])
691 {
692         Scene *scene= CTX_data_scene(C);
693         KeyingSet *ks;
694         uiPopupMenu *pup;
695         uiLayout *layout;
696         int i = 0;
697         
698         pup= uiPupMenuBegin(C, title, 0);
699         layout= uiPupMenuLayout(pup);
700         
701         /* active Keying Set 
702          *      - only include entry if it exists
703          */
704         if (scene->active_keyingset) {
705                 uiItemIntO(layout, "Active Keying Set", 0, op_name, "type", i++);
706                 uiItemS(layout);
707         }
708         else
709                 i++;
710         
711         /* user-defined Keying Sets 
712          *      - these are listed in the order in which they were defined for the active scene
713          */
714         if (scene->keyingsets.first) {
715                 for (ks= scene->keyingsets.first; ks; ks= ks->next) {
716                         if (ANIM_keyingset_context_ok_poll(C, ks))
717                                 uiItemIntO(layout, ks->name, 0, op_name, "type", i++);
718                 }
719                 uiItemS(layout);
720         }
721         
722         /* builtin Keying Sets */
723         i= -1;
724         for (ks= builtin_keyingsets.first; ks; ks= ks->next) {
725                 /* only show KeyingSet if context is suitable */
726                 if (ANIM_keyingset_context_ok_poll(C, ks))
727                         uiItemIntO(layout, ks->name, 0, op_name, "type", i--);
728         }
729         
730         uiPupMenuEnd(C, pup);
731
732
733 /* ******************************************* */
734 /* KEYFRAME MODIFICATION */
735
736 /* Polling API ----------------------------------------------- */
737
738 /* Check if KeyingSet can be used in the current context */
739 short ANIM_keyingset_context_ok_poll (bContext *C, KeyingSet *ks)
740 {
741         if ((ks->flag & KEYINGSET_ABSOLUTE) == 0) {
742                 KeyingSetInfo *ksi = ANIM_keyingset_info_find_named(ks->typeinfo);
743                 
744                 /* get the associated 'type info' for this KeyingSet */
745                 if (ksi == NULL)
746                         return 0;
747                 // TODO: check for missing callbacks!
748                 
749                 /* check if it can be used in the current context */
750                 return (ksi->poll(ksi, C));
751         }
752         
753         return 1;
754 }
755
756 /* Special 'Overrides' Iterator for Relative KeyingSets ------ */
757
758 /* 'Data Sources' for relative Keying Set 'overrides' 
759  *      - this is basically a wrapper for PointerRNA's in a linked list
760  *      - do not allow this to be accessed from outside for now
761  */
762 typedef struct tRKS_DSource {
763         struct tRKS_DSource *next, *prev;
764         PointerRNA ptr;         /* the whole point of this exercise! */
765 } tRKS_DSource;
766
767
768 /* Iterator used for overriding the behaviour of iterators defined for 
769  * relative Keying Sets, with the main usage of this being operators 
770  * requiring Auto Keyframing. Internal Use Only!
771  */
772 static void RKS_ITER_overrides_list (KeyingSetInfo *ksi, bContext *C, KeyingSet *ks, ListBase *dsources)
773 {
774         tRKS_DSource *ds;
775         
776         for (ds = dsources->first; ds; ds = ds->next) {
777                 /* run generate callback on this data */
778                 ksi->generate(ksi, C, ks, &ds->ptr);
779         }
780 }
781
782 /* Add new data source for relative Keying Sets */
783 void ANIM_relative_keyingset_add_source (ListBase *dsources, ID *id, StructRNA *srna, void *data)
784 {
785         tRKS_DSource *ds;
786         
787         /* sanity checks 
788          *      - we must have somewhere to output the data
789          *      - we must have both srna+data (and with id too optionally), or id by itself only
790          */
791         if (dsources == NULL)
792                 return;
793         if (ELEM(NULL, srna, data) && (id == NULL))
794                 return;
795         
796         /* allocate new elem, and add to the list */
797         ds = MEM_callocN(sizeof(tRKS_DSource), "tRKS_DSource");
798         BLI_addtail(dsources, ds);
799         
800         /* depending on what data we have, create using ID or full pointer call */
801         if (srna && data)
802                 RNA_pointer_create(id, srna, data, &ds->ptr);
803         else
804                 RNA_id_pointer_create(id, &ds->ptr);
805 }
806
807 /* KeyingSet Operations (Insert/Delete Keyframes) ------------ */
808
809 /* Given a KeyingSet and context info (if required), modify keyframes for the channels specified
810  * by the KeyingSet. This takes into account many of the different combinations of using KeyingSets.
811  * Returns the number of channels that keyframes were added to
812  */
813 int ANIM_apply_keyingset (bContext *C, ListBase *dsources, bAction *act, KeyingSet *ks, short mode, float cfra)
814 {
815         Scene *scene= CTX_data_scene(C);
816         KS_Path *ksp;
817         int kflag=0, success= 0;
818         char *groupname= NULL;
819         
820         /* sanity checks */
821         if (ks == NULL)
822                 return 0;
823         
824         /* get flags to use */
825         if (mode == MODIFYKEY_MODE_INSERT) {
826                 /* use KeyingSet's flags as base */
827                 kflag= ks->keyingflag;
828                 
829                 /* suppliment with info from the context */
830                 kflag |= ANIM_get_keyframing_flags(scene, 1);
831         }
832         else if (mode == MODIFYKEY_MODE_DELETE)
833                 kflag= 0;
834         
835         /* if relative Keying Sets, poll and build up the paths */
836         if ((ks->flag & KEYINGSET_ABSOLUTE) == 0) {
837                 KeyingSetInfo *ksi = ANIM_keyingset_info_find_named(ks->typeinfo);
838                 
839                 /* clear all existing paths 
840                  * NOTE: BKE_keyingset_free() frees all of the paths for the KeyingSet, but not the set itself
841                  */
842                 BKE_keyingset_free(ks);
843                 
844                 /* get the associated 'type info' for this KeyingSet */
845                 if (ksi == NULL)
846                         return MODIFYKEY_MISSING_TYPEINFO;
847                 // TODO: check for missing callbacks!
848                 
849                 /* check if it can be used in the current context */
850                 if (ksi->poll(ksi, C)) {
851                         /* if a list of data sources are provided, run a special iterator over them,
852                          * otherwise, just continue per normal
853                          */
854                         if (dsources) 
855                                 RKS_ITER_overrides_list(ksi, C, ks, dsources);
856                         else
857                                 ksi->iter(ksi, C, ks);
858                                 
859                         /* if we don't have any paths now, then this still qualifies as invalid context */
860                         if (ks->paths.first == NULL)
861                                 return MODIFYKEY_INVALID_CONTEXT;
862                 }
863                 else {
864                         /* poll callback tells us that KeyingSet is useless in current context */
865                         return MODIFYKEY_INVALID_CONTEXT;
866                 }
867         }
868         
869         /* apply the paths as specified in the KeyingSet now */
870         for (ksp= ks->paths.first; ksp; ksp= ksp->next) { 
871                 int arraylen, i;
872                 short kflag2;
873                 
874                 /* since keying settings can be defined on the paths too, extend the path before using it */
875                 kflag2 = (kflag | ksp->keyingflag);
876                 
877                 /* get pointer to name of group to add channels to */
878                 if (ksp->groupmode == KSP_GROUP_NONE)
879                         groupname= NULL;
880                 else if (ksp->groupmode == KSP_GROUP_KSNAME)
881                         groupname= ks->name;
882                 else
883                         groupname= ksp->group;
884                 
885                 /* init arraylen and i - arraylen should be greater than i so that
886                  * normal non-array entries get keyframed correctly
887                  */
888                 i= ksp->array_index;
889                 arraylen= i;
890                 
891                 /* get length of array if whole array option is enabled */
892                 if (ksp->flag & KSP_FLAG_WHOLE_ARRAY) {
893                         PointerRNA id_ptr, ptr;
894                         PropertyRNA *prop;
895                         
896                         RNA_id_pointer_create(ksp->id, &id_ptr);
897                         if (RNA_path_resolve(&id_ptr, ksp->rna_path, &ptr, &prop) && prop)
898                                 arraylen= RNA_property_array_length(&ptr, prop);
899                 }
900                 
901                 /* we should do at least one step */
902                 if (arraylen == i)
903                         arraylen++;
904                 
905                 /* for each possible index, perform operation 
906                  *      - assume that arraylen is greater than index
907                  */
908                 for (; i < arraylen; i++) {
909                         /* action to take depends on mode */
910                         if (mode == MODIFYKEY_MODE_INSERT)
911                                 success += insert_keyframe(ksp->id, act, groupname, ksp->rna_path, i, cfra, kflag2);
912                         else if (mode == MODIFYKEY_MODE_DELETE)
913                                 success += delete_keyframe(ksp->id, act, groupname, ksp->rna_path, i, cfra, kflag2);
914                 }
915                 
916                 /* set recalc-flags */
917                 if (ksp->id) {
918                         switch (GS(ksp->id->name)) {
919                                 case ID_OB: /* Object (or Object-Related) Keyframes */
920                                 {
921                                         Object *ob= (Object *)ksp->id;
922                                         
923                                         ob->recalc |= OB_RECALC_ALL; // XXX: only object transforms only?
924                                 }
925                                         break;
926                         }
927                         
928                         /* send notifiers for updates (this doesn't require context to work!) */
929                         WM_main_add_notifier(NC_ANIMATION|ND_KEYFRAME|NA_EDITED, NULL);
930                 }
931         }
932         
933         /* return the number of channels successfully affected */
934         return success;
935 }
936
937 /* ************************************************** */