Keyframing Bugfixes and Feature Requests:
[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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, 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_action_types.h"
44 #include "DNA_armature_types.h"
45 #include "DNA_constraint_types.h"
46 #include "DNA_key_types.h"
47 #include "DNA_object_types.h"
48 #include "DNA_material_types.h"
49 #include "DNA_scene_types.h"
50 #include "DNA_userdef_types.h"
51 #include "DNA_windowmanager_types.h"
52
53 #include "BKE_animsys.h"
54 #include "BKE_action.h"
55 #include "BKE_constraint.h"
56 #include "BKE_depsgraph.h"
57 #include "BKE_fcurve.h"
58 #include "BKE_utildefines.h"
59 #include "BKE_context.h"
60 #include "BKE_report.h"
61 #include "BKE_key.h"
62 #include "BKE_material.h"
63
64 #include "ED_anim_api.h"
65 #include "ED_keyframing.h"
66 #include "ED_keyframes_edit.h"
67 #include "ED_screen.h"
68 #include "ED_util.h"
69
70 #include "UI_interface.h"
71
72 #include "WM_api.h"
73 #include "WM_types.h"
74
75 #include "RNA_access.h"
76 #include "RNA_define.h"
77 #include "RNA_types.h"
78
79 #include "anim_intern.h"
80
81 /* ************************************************** */
82 /* KEYING SETS - OPERATORS (for use in UI panels) */
83 /* These operators are really duplication of existing functionality, but just for completeness,
84  * they're here too, and will give the basic data needed...
85  */
86
87 /* poll callback for adding default KeyingSet */
88 static int keyingset_poll_default_add (bContext *C)
89 {
90         /* as long as there's an active Scene, it's fine */
91         return (CTX_data_scene(C) != NULL);
92 }
93
94 /* poll callback for editing active KeyingSet */
95 static int keyingset_poll_active_edit (bContext *C)
96 {
97         Scene *scene= CTX_data_scene(C);
98         
99         if (scene == NULL)
100                 return 0;
101         
102         /* there must be an active KeyingSet (and KeyingSets) */
103         return ((scene->active_keyingset > 0) && (scene->keyingsets.first));
104 }
105
106 /* poll callback for editing active KeyingSet Path */
107 static int keyingset_poll_activePath_edit (bContext *C)
108 {
109         Scene *scene= CTX_data_scene(C);
110         KeyingSet *ks;
111         
112         if (scene == NULL)
113                 return 0;
114         if (scene->active_keyingset <= 0)
115                 return 0;
116         else
117                 ks= BLI_findlink(&scene->keyingsets, scene->active_keyingset-1);
118         
119         /* there must be an active KeyingSet and an active path */
120         return ((ks) && (ks->paths.first) && (ks->active_path > 0));
121 }
122
123  
124 /* Add a Default (Empty) Keying Set ------------------------- */
125
126 static int add_default_keyingset_exec (bContext *C, wmOperator *op)
127 {
128         Scene *scene= CTX_data_scene(C);
129         short flag=0, keyingflag=0;
130         
131         /* validate flags 
132          *      - absolute KeyingSets should be created by default
133          */
134         flag |= KEYINGSET_ABSOLUTE;
135         
136         /* 2nd arg is 0 to indicate that we don't want to include autokeying mode related settings */
137         keyingflag = ANIM_get_keyframing_flags(scene, 0);
138         
139         /* call the API func, and set the active keyingset index */
140         BKE_keyingset_add(&scene->keyingsets, NULL, flag, keyingflag);
141         
142         scene->active_keyingset= BLI_countlist(&scene->keyingsets);
143         
144         /* send notifiers */
145         WM_event_add_notifier(C, NC_SCENE|ND_KEYINGSET, NULL);
146         
147         return OPERATOR_FINISHED;
148 }
149
150 void ANIM_OT_keying_set_add (wmOperatorType *ot)
151 {
152         /* identifiers */
153         ot->name= "Add Empty Keying Set";
154         ot->idname= "ANIM_OT_keying_set_add";
155         ot->description= "Add a new (empty) Keying Set to the active Scene.";
156         
157         /* callbacks */
158         ot->exec= add_default_keyingset_exec;
159         ot->poll= keyingset_poll_default_add;
160 }
161
162 /* Remove 'Active' Keying Set ------------------------- */
163
164 static int remove_active_keyingset_exec (bContext *C, wmOperator *op)
165 {
166         Scene *scene= CTX_data_scene(C);
167         KeyingSet *ks;
168         
169         /* verify the Keying Set to use:
170          *      - use the active one
171          *      - return error if it doesn't exist
172          */
173         if (scene->active_keyingset == 0) {
174                 BKE_report(op->reports, RPT_ERROR, "No active Keying Set to remove");
175                 return OPERATOR_CANCELLED;
176         }
177         else
178                 ks= BLI_findlink(&scene->keyingsets, scene->active_keyingset-1);
179         
180         /* free KeyingSet's data, then remove it from the scene */
181         BKE_keyingset_free(ks);
182         BLI_freelinkN(&scene->keyingsets, ks);
183         
184         /* the active one should now be the previously second-to-last one */
185         scene->active_keyingset--;
186         
187         /* send notifiers */
188         WM_event_add_notifier(C, NC_SCENE|ND_KEYINGSET, NULL);
189         
190         return OPERATOR_FINISHED;
191 }
192
193 void ANIM_OT_keying_set_remove (wmOperatorType *ot)
194 {
195         /* identifiers */
196         ot->name= "Removed Active Keying Set";
197         ot->idname= "ANIM_OT_keying_set_remove";
198         ot->description= "Remove the active Keying Set.";
199         
200         /* callbacks */
201         ot->exec= remove_active_keyingset_exec;
202         ot->poll= keyingset_poll_active_edit;
203 }
204
205 /* Add Empty Keying Set Path ------------------------- */
206
207 static int add_empty_ks_path_exec (bContext *C, wmOperator *op)
208 {
209         Scene *scene= CTX_data_scene(C);
210         KeyingSet *ks;
211         KS_Path *ksp;
212         
213         /* verify the Keying Set to use:
214          *      - use the active one
215          *      - return error if it doesn't exist
216          */
217         if (scene->active_keyingset == 0) {
218                 BKE_report(op->reports, RPT_ERROR, "No active Keying Set to add empty path to");
219                 return OPERATOR_CANCELLED;
220         }
221         else
222                 ks= BLI_findlink(&scene->keyingsets, scene->active_keyingset-1);
223         
224         /* don't use the API method for this, since that checks on values... */
225         ksp= MEM_callocN(sizeof(KS_Path), "KeyingSetPath Empty");
226         BLI_addtail(&ks->paths, ksp);
227         ks->active_path= BLI_countlist(&ks->paths);
228         
229         ksp->groupmode= KSP_GROUP_KSNAME; // XXX?
230         
231         return OPERATOR_FINISHED;
232 }
233
234 void ANIM_OT_keying_set_path_add (wmOperatorType *ot)
235 {
236         /* identifiers */
237         ot->name= "Add Empty Keying Set Path";
238         ot->idname= "ANIM_OT_keying_set_path_add";
239         ot->description= "Add empty path to active Keying Set";
240         
241         /* callbacks */
242         ot->exec= add_empty_ks_path_exec;
243         ot->poll= keyingset_poll_active_edit;
244 }
245
246 /* Remove Active Keying Set Path ------------------------- */
247
248 static int remove_active_ks_path_exec (bContext *C, wmOperator *op)
249 {
250         Scene *scene= CTX_data_scene(C);
251         KeyingSet *ks= BLI_findlink(&scene->keyingsets, scene->active_keyingset-1);
252         
253         /* if there is a KeyingSet, find the nominated path to remove */
254         if (ks) {
255                 KS_Path *ksp= BLI_findlink(&ks->paths, ks->active_path-1);
256                 
257                 if (ksp) {
258                         /* NOTE: sync this code with BKE_keyingset_free() */
259                         {
260                                 /* free RNA-path info */
261                                 MEM_freeN(ksp->rna_path);
262                                 
263                                 /* free path itself */
264                                 BLI_freelinkN(&ks->paths, ksp);
265                         }
266                         
267                         /* the active path should now be the previously second-to-last active one */
268                         ks->active_path--;
269                 }
270                 else {
271                         BKE_report(op->reports, RPT_ERROR, "No active Keying Set Path to remove");
272                         return OPERATOR_CANCELLED;
273                 }
274         }
275         else {
276                 BKE_report(op->reports, RPT_ERROR, "No active Keying Set to remove a path from");
277                 return OPERATOR_CANCELLED;
278         }
279         
280         return OPERATOR_FINISHED;
281 }
282
283 void ANIM_OT_keying_set_path_remove (wmOperatorType *ot)
284 {
285         /* identifiers */
286         ot->name= "Remove Active Keying Set Path";
287         ot->idname= "ANIM_OT_keying_set_path_remove";
288         ot->description= "Remove active Path from active Keying Set.";
289         
290         /* callbacks */
291         ot->exec= remove_active_ks_path_exec;
292         ot->poll= keyingset_poll_activePath_edit;
293 }
294
295 /* ************************************************** */
296 /* KEYING SETS - OPERATORS (for use in UI menus) */
297
298 /* Add to KeyingSet Button Operator ------------------------ */
299
300 static int add_keyingset_button_exec (bContext *C, wmOperator *op)
301 {
302         Scene *scene= CTX_data_scene(C);
303         KeyingSet *ks = NULL;
304         PropertyRNA *prop= NULL;
305         PointerRNA ptr;
306         char *path = NULL;
307         short success= 0;
308         int index=0, pflag=0;
309         int all= RNA_boolean_get(op->ptr, "all");
310         
311         /* verify the Keying Set to use:
312          *      - use the active one for now (more control over this can be added later)
313          *      - add a new one if it doesn't exist 
314          */
315         if (scene->active_keyingset == 0) {
316                 short flag=0, keyingflag=0;
317                 
318                 /* validate flags 
319                  *      - absolute KeyingSets should be created by default
320                  */
321                 flag |= KEYINGSET_ABSOLUTE;
322                 
323                 if (IS_AUTOKEY_FLAG(AUTOMATKEY)) 
324                         keyingflag |= INSERTKEY_MATRIX;
325                 if (IS_AUTOKEY_FLAG(INSERTNEEDED)) 
326                         keyingflag |= INSERTKEY_NEEDED;
327                 if (IS_AUTOKEY_FLAG(XYZ2RGB)) 
328                         keyingflag |= INSERTKEY_XYZ2RGB;
329                         
330                 /* call the API func, and set the active keyingset index */
331                 ks= BKE_keyingset_add(&scene->keyingsets, "ButtonKeyingSet", flag, keyingflag);
332                 
333                 scene->active_keyingset= BLI_countlist(&scene->keyingsets);
334         }
335         else
336                 ks= BLI_findlink(&scene->keyingsets, scene->active_keyingset-1);
337         
338         /* try to add to keyingset using property retrieved from UI */
339         memset(&ptr, 0, sizeof(PointerRNA));
340         uiAnimContextProperty(C, &ptr, &prop, &index);
341         
342         /* check if property is able to be added */
343         if (ptr.data && prop && RNA_property_animateable(ptr.data, prop)) {
344                 path= RNA_path_from_ID_to_property(&ptr, prop);
345                 
346                 if (path) {
347                         /* set flags */
348                         if (all) {
349                                 pflag |= KSP_FLAG_WHOLE_ARRAY;
350                                 
351                                 /* we need to set the index for this to 0, even though it may break in some cases, this is 
352                                  * necessary if we want the entire array for most cases to get included without the user
353                                  * having to worry about where they clicked
354                                  */
355                                 index= 0;
356                         }
357                                 
358                         /* add path to this setting */
359                         BKE_keyingset_add_destination(ks, ptr.id.data, NULL, path, index, pflag, KSP_GROUP_KSNAME);
360                         ks->active_path= BLI_countlist(&ks->paths);
361                         success= 1;
362                         
363                         /* free the temp path created */
364                         MEM_freeN(path);
365                 }
366         }
367         
368         if (success) {
369                 /* send updates */
370                 DAG_ids_flush_update(0);
371                 
372                 /* for now, only send ND_KEYS for KeyingSets */
373                 WM_event_add_notifier(C, NC_SCENE|ND_KEYINGSET, NULL);
374         }
375         
376         return (success)? OPERATOR_FINISHED: OPERATOR_CANCELLED;
377 }
378
379 void ANIM_OT_keyingset_button_add (wmOperatorType *ot)
380 {
381         /* identifiers */
382         ot->name= "Add to Keying Set";
383         ot->idname= "ANIM_OT_keyingset_button_add";
384         
385         /* callbacks */
386         ot->exec= add_keyingset_button_exec; 
387         //op->poll= ???
388         
389         /* flags */
390         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
391
392         /* properties */
393         RNA_def_boolean(ot->srna, "all", 1, "All", "Add all elements of the array to a Keying Set.");
394 }
395
396 /* Remove from KeyingSet Button Operator ------------------------ */
397
398 static int remove_keyingset_button_exec (bContext *C, wmOperator *op)
399 {
400         Scene *scene= CTX_data_scene(C);
401         KeyingSet *ks = NULL;
402         PropertyRNA *prop= NULL;
403         PointerRNA ptr;
404         char *path = NULL;
405         short success= 0;
406         int index=0;
407         
408         /* verify the Keying Set to use:
409          *      - use the active one for now (more control over this can be added later)
410          *      - return error if it doesn't exist
411          */
412         if (scene->active_keyingset == 0) {
413                 BKE_report(op->reports, RPT_ERROR, "No active Keying Set to remove property from");
414                 return OPERATOR_CANCELLED;
415         }
416         else
417                 ks= BLI_findlink(&scene->keyingsets, scene->active_keyingset-1);
418         
419         /* try to add to keyingset using property retrieved from UI */
420         memset(&ptr, 0, sizeof(PointerRNA));
421         uiAnimContextProperty(C, &ptr, &prop, &index);
422
423         if (ptr.data && prop) {
424                 path= RNA_path_from_ID_to_property(&ptr, prop);
425                 
426                 if (path) {
427                         KS_Path *ksp;
428                         
429                         /* try to find a path matching this description */
430                         ksp= BKE_keyingset_find_destination(ks, ptr.id.data, ks->name, path, index, KSP_GROUP_KSNAME);
431                         
432                         if (ksp) {
433                                 /* just free it... */
434                                 MEM_freeN(ksp->rna_path);
435                                 BLI_freelinkN(&ks->paths, ksp);
436                                 
437                                 success= 1;
438                         }
439                         
440                         /* free temp path used */
441                         MEM_freeN(path);
442                 }
443         }
444         
445         
446         if (success) {
447                 /* send updates */
448                 DAG_ids_flush_update(0);
449                 
450                 /* for now, only send ND_KEYS for KeyingSets */
451                 WM_event_add_notifier(C, NC_SCENE|ND_KEYINGSET, NULL);
452         }
453         
454         return (success)? OPERATOR_FINISHED: OPERATOR_CANCELLED;
455 }
456
457 void ANIM_OT_keyingset_button_remove (wmOperatorType *ot)
458 {
459         /* identifiers */
460         ot->name= "Remove from Keying Set";
461         ot->idname= "ANIM_OT_keyingset_button_remove";
462         
463         /* callbacks */
464         ot->exec= remove_keyingset_button_exec; 
465         //op->poll= ???
466         
467         /* flags */
468         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
469 }
470
471 /* ************************************************** */
472 /* KEYING SETS - EDITING API  */
473
474 /* UI API --------------------------------------------- */
475
476 /* Build menu-string of available keying-sets (allocates memory for string)
477  * NOTE: mode must not be longer than 64 chars
478  */
479 char *ANIM_build_keyingsets_menu (ListBase *list, short for_edit)
480 {
481         DynStr *pupds= BLI_dynstr_new();
482         KeyingSet *ks;
483         char buf[64];
484         char *str;
485         int i;
486         
487         /* add title first */
488         BLI_dynstr_append(pupds, "Keying Sets%t|");
489         
490         /* add dummy entries for none-active */
491         if (for_edit) { 
492                 BLI_dynstr_append(pupds, "Add New%x-1|");
493                 BLI_dynstr_append(pupds, " %x0|");
494         }
495         else
496                 BLI_dynstr_append(pupds, "No Keying Set%x0|");
497         
498         /* loop through keyingsets, adding them */
499         for (ks=list->first, i=1; ks; ks=ks->next, i++) {
500                 if (for_edit == 0)
501                         BLI_dynstr_append(pupds, "KS: ");
502                 
503                 BLI_dynstr_append(pupds, ks->name);
504                 BLI_snprintf( buf, 64, "%%x%d%s", i, ((ks->next)?"|":"") );
505                 BLI_dynstr_append(pupds, buf);
506         }
507         
508         /* convert to normal MEM_malloc'd string */
509         str= BLI_dynstr_get_cstring(pupds);
510         BLI_dynstr_free(pupds);
511         
512         return str;
513 }
514
515
516 /* ******************************************* */
517 /* KEYING SETS - BUILTIN */
518
519 #if 0 // XXX old keyingsets code based on adrcodes... to be restored in due course
520
521 /* ------------- KeyingSet Defines ------------ */
522 /* Note: these must all be named with the defks_* prefix, otherwise the template macro will not work! */
523
524 /* macro for defining keyingset contexts */
525 #define KSC_TEMPLATE(ctx_name) {&defks_##ctx_name[0], NULL, sizeof(defks_##ctx_name)/sizeof(bKeyingSet)}
526
527 /* --- */
528
529 /* check if option not available for deleting keys */
530 static short incl_non_del_keys (bKeyingSet *ks, const char mode[])
531 {
532         /* as optimisation, assume that it is sufficient to check only first letter
533          * of mode (int comparison should be faster than string!)
534          */
535         //if (strcmp(mode, "Delete")==0)
536         if (mode && mode[0]=='D')
537                 return 0;
538         
539         return 1;
540 }
541
542 /* Object KeyingSets  ------ */
543
544 /* check if include shapekey entry  */
545 static short incl_v3d_ob_shapekey (bKeyingSet *ks, const char mode[])
546 {
547         //Object *ob= (G.obedit)? (G.obedit) : (OBACT); // XXX
548         Object *ob= NULL;
549         char *newname= NULL;
550         
551         if(ob==NULL)
552                 return 0;
553         
554         /* not available for delete mode */
555         if (strcmp(mode, "Delete")==0)
556                 return 0;
557         
558         /* check if is geom object that can get shapekeys */
559         switch (ob->type) {
560                 /* geometry? */
561                 case OB_MESH:           newname= "Mesh";                break;
562                 case OB_CURVE:          newname= "Curve";               break;
563                 case OB_SURF:           newname= "Surface";             break;
564                 case OB_LATTICE:        newname= "Lattice";             break;
565                 
566                 /* not geometry! */
567                 default:
568                         return 0;
569         }
570         
571         /* if ks is shapekey entry (this could be callled for separator before too!) */
572         if (ks->flag == -3)
573                 BLI_strncpy(ks->name, newname, sizeof(ks->name));
574         
575         /* if it gets here, it's ok */
576         return 1;
577 }
578
579 /* array for object keyingset defines */
580 bKeyingSet defks_v3d_object[] = 
581 {
582         /* include_cb, adrcode-getter, name, blocktype, flag, chan_num, adrcodes */
583         {NULL, "Loc", ID_OB, 0, 3, {OB_LOC_X,OB_LOC_Y,OB_LOC_Z}},
584         {NULL, "Rot", ID_OB, 0, 3, {OB_ROT_X,OB_ROT_Y,OB_ROT_Z}},
585         {NULL, "Scale", ID_OB, 0, 3, {OB_SIZE_X,OB_SIZE_Y,OB_SIZE_Z}},
586         
587         {NULL, "%l", 0, -1, 0, {0}}, // separator
588         
589         {NULL, "LocRot", ID_OB, 0, 6, 
590                 {OB_LOC_X,OB_LOC_Y,OB_LOC_Z,
591                  OB_ROT_X,OB_ROT_Y,OB_ROT_Z}},
592                  
593         {NULL, "LocScale", ID_OB, 0, 6, 
594                 {OB_LOC_X,OB_LOC_Y,OB_LOC_Z,
595                  OB_SIZE_X,OB_SIZE_Y,OB_SIZE_Z}},
596                  
597         {NULL, "LocRotScale", ID_OB, 0, 9, 
598                 {OB_LOC_X,OB_LOC_Y,OB_LOC_Z,
599                  OB_ROT_X,OB_ROT_Y,OB_ROT_Z,
600                  OB_SIZE_X,OB_SIZE_Y,OB_SIZE_Z}},
601                  
602         {NULL, "RotScale", ID_OB, 0, 6, 
603                 {OB_ROT_X,OB_ROT_Y,OB_ROT_Z,
604                  OB_SIZE_X,OB_SIZE_Y,OB_SIZE_Z}},
605         
606         {incl_non_del_keys, "%l", 0, -1, 0, {0}}, // separator
607         
608         {incl_non_del_keys, "VisualLoc", ID_OB, INSERTKEY_MATRIX, 3, {OB_LOC_X,OB_LOC_Y,OB_LOC_Z}},
609         {incl_non_del_keys, "VisualRot", ID_OB, INSERTKEY_MATRIX, 3, {OB_ROT_X,OB_ROT_Y,OB_ROT_Z}},
610         
611         {incl_non_del_keys, "VisualLocRot", ID_OB, INSERTKEY_MATRIX, 6, 
612                 {OB_LOC_X,OB_LOC_Y,OB_LOC_Z,
613                  OB_ROT_X,OB_ROT_Y,OB_ROT_Z}},
614         
615         {NULL, "%l", 0, -1, 0, {0}}, // separator
616         
617         {NULL, "Layer", ID_OB, 0, 1, {OB_LAY}}, // icky option...
618         {NULL, "Available", ID_OB, -2, 0, {0}},
619         
620         {incl_v3d_ob_shapekey, "%l%l", 0, -1, 0, {0}}, // separator (linked to shapekey entry)
621         {incl_v3d_ob_shapekey, "<ShapeKey>", ID_OB, -3, 0, {0}}
622 };
623
624 /* PoseChannel KeyingSets  ------ */
625
626 /* array for posechannel keyingset defines */
627 bKeyingSet defks_v3d_pchan[] = 
628 {
629         /* include_cb, name, blocktype, flag, chan_num, adrcodes */
630         {NULL, "Loc", ID_PO, 0, 3, {AC_LOC_X,AC_LOC_Y,AC_LOC_Z}},
631         {NULL, "Rot", ID_PO, COMMONKEY_PCHANROT, 1, {KAG_CHAN_EXTEND}},
632         {NULL, "Scale", ID_PO, 0, 3, {AC_SIZE_X,AC_SIZE_Y,AC_SIZE_Z}},
633         
634         {NULL, "%l", 0, -1, 0, {0}}, // separator
635         
636         {NULL, "LocRot", ID_PO, COMMONKEY_PCHANROT, 4, 
637                 {AC_LOC_X,AC_LOC_Y,AC_LOC_Z,
638                  KAG_CHAN_EXTEND}},
639                  
640         {NULL, "LocScale", ID_PO, 0, 6, 
641                 {AC_LOC_X,AC_LOC_Y,AC_LOC_Z,
642                  AC_SIZE_X,AC_SIZE_Y,AC_SIZE_Z}},
643                  
644         {NULL, "LocRotScale", ID_PO, COMMONKEY_PCHANROT, 7, 
645                 {AC_LOC_X,AC_LOC_Y,AC_LOC_Z,AC_SIZE_X,AC_SIZE_Y,AC_SIZE_Z, 
646                  KAG_CHAN_EXTEND}},
647                  
648         {NULL, "RotScale", ID_PO, 0, 4, 
649                 {AC_SIZE_X,AC_SIZE_Y,AC_SIZE_Z, 
650                  KAG_CHAN_EXTEND}},
651         
652         {incl_non_del_keys, "%l", 0, -1, 0, {0}}, // separator
653         
654         {incl_non_del_keys, "VisualLoc", ID_PO, INSERTKEY_MATRIX, 3, {AC_LOC_X,AC_LOC_Y,AC_LOC_Z}},
655         {incl_non_del_keys, "VisualRot", ID_PO, INSERTKEY_MATRIX|COMMONKEY_PCHANROT, 1, {KAG_CHAN_EXTEND}},
656         
657         {incl_non_del_keys, "VisualLocRot", ID_PO, INSERTKEY_MATRIX|COMMONKEY_PCHANROT, 4, 
658                 {AC_LOC_X,AC_LOC_Y,AC_LOC_Z, KAG_CHAN_EXTEND}},
659         
660         {NULL, "%l", 0, -1, 0, {0}}, // separator
661         
662         {NULL, "Available", ID_PO, -2, 0, {0}}
663 };
664
665 /* Material KeyingSets  ------ */
666
667 /* array for material keyingset defines */
668 bKeyingSet defks_buts_shading_mat[] = 
669 {
670         /* include_cb, name, blocktype, flag, chan_num, adrcodes */
671         {NULL, "RGB", ID_MA, 0, 3, {MA_COL_R,MA_COL_G,MA_COL_B}},
672         {NULL, "Alpha", ID_MA, 0, 1, {MA_ALPHA}},
673         {NULL, "Halo Size", ID_MA, 0, 1, {MA_HASIZE}},
674         {NULL, "Mode", ID_MA, 0, 1, {MA_MODE}}, // evil bitflags
675         
676         {NULL, "%l", 0, -1, 0, {0}}, // separator
677         
678         {NULL, "All Color", ID_MA, 0, 18, 
679                 {MA_COL_R,MA_COL_G,MA_COL_B,
680                  MA_ALPHA,MA_HASIZE, MA_MODE,
681                  MA_SPEC_R,MA_SPEC_G,MA_SPEC_B,
682                  MA_REF,MA_EMIT,MA_AMB,MA_SPEC,MA_HARD,
683                  MA_MODE,MA_TRANSLU,MA_ADD}},
684                  
685         {NULL, "All Mirror", ID_MA, 0, 5, 
686                 {MA_RAYM,MA_FRESMIR,MA_FRESMIRI,
687                  MA_FRESTRA,MA_FRESTRAI}},
688         
689         {NULL, "%l", 0, -1, 0, {0}}, // separator
690         
691         {NULL, "Ofs", ID_MA, COMMONKEY_ADDMAP, 3, {MAP_OFS_X,MAP_OFS_Y,MAP_OFS_Z}},
692         {NULL, "Size", ID_MA, COMMONKEY_ADDMAP, 3, {MAP_SIZE_X,MAP_SIZE_Y,MAP_SIZE_Z}},
693         
694         {NULL, "All Mapping", ID_MA, COMMONKEY_ADDMAP, 14, 
695                 {MAP_OFS_X,MAP_OFS_Y,MAP_OFS_Z,
696                  MAP_SIZE_X,MAP_SIZE_Y,MAP_SIZE_Z,
697                  MAP_R,MAP_G,MAP_B,MAP_DVAR,
698                  MAP_COLF,MAP_NORF,MAP_VARF,MAP_DISP}},
699         
700         {NULL, "%l", 0, -1, 0, {0}}, // separator
701         
702         {NULL, "Available", ID_MA, -2, 0, {0}}
703 };
704
705 /* World KeyingSets  ------ */
706
707 /* array for world keyingset defines */
708 bKeyingSet defks_buts_shading_wo[] = 
709 {
710         /* include_cb, name, blocktype, flag, chan_num, adrcodes */
711         {NULL, "Zenith RGB", ID_WO, 0, 3, {WO_ZEN_R,WO_ZEN_G,WO_ZEN_B}},
712         {NULL, "Horizon RGB", ID_WO, 0, 3, {WO_HOR_R,WO_HOR_G,WO_HOR_B}},
713         
714         {NULL, "%l", 0, -1, 0, {0}}, // separator
715         
716         {NULL, "Mist", ID_WO, 0, 4, {WO_MISI,WO_MISTDI,WO_MISTSTA,WO_MISTHI}},
717         {NULL, "Stars", ID_WO, 0, 5, {WO_STAR_R,WO_STAR_G,WO_STAR_B,WO_STARDIST,WO_STARSIZE}},
718         
719         
720         {NULL, "%l", 0, -1, 0, {0}}, // separator
721         
722         {NULL, "Ofs", ID_WO, COMMONKEY_ADDMAP, 3, {MAP_OFS_X,MAP_OFS_Y,MAP_OFS_Z}},
723         {NULL, "Size", ID_WO, COMMONKEY_ADDMAP, 3, {MAP_SIZE_X,MAP_SIZE_Y,MAP_SIZE_Z}},
724         
725         {NULL, "All Mapping", ID_WO, COMMONKEY_ADDMAP, 14, 
726                 {MAP_OFS_X,MAP_OFS_Y,MAP_OFS_Z,
727                  MAP_SIZE_X,MAP_SIZE_Y,MAP_SIZE_Z,
728                  MAP_R,MAP_G,MAP_B,MAP_DVAR,
729                  MAP_COLF,MAP_NORF,MAP_VARF,MAP_DISP}},
730         
731         {NULL, "%l", 0, -1, 0, {0}}, // separator
732         
733         {NULL, "Available", ID_WO, -2, 0, {0}}
734 };
735
736 /* Lamp KeyingSets  ------ */
737
738 /* array for lamp keyingset defines */
739 bKeyingSet defks_buts_shading_la[] = 
740 {
741         /* include_cb, name, blocktype, flag, chan_num, adrcodes */
742         {NULL, "RGB", ID_LA, 0, 3, {LA_COL_R,LA_COL_G,LA_COL_B}},
743         {NULL, "Energy", ID_LA, 0, 1, {LA_ENERGY}},
744         {NULL, "Spot Size", ID_LA, 0, 1, {LA_SPOTSI}},
745         
746         {NULL, "%l", 0, -1, 0, {0}}, // separator
747         
748         {NULL, "Ofs", ID_LA, COMMONKEY_ADDMAP, 3, {MAP_OFS_X,MAP_OFS_Y,MAP_OFS_Z}},
749         {NULL, "Size", ID_LA, COMMONKEY_ADDMAP, 3, {MAP_SIZE_X,MAP_SIZE_Y,MAP_SIZE_Z}},
750         
751         {NULL, "All Mapping", ID_LA, COMMONKEY_ADDMAP, 14, 
752                 {MAP_OFS_X,MAP_OFS_Y,MAP_OFS_Z,
753                  MAP_SIZE_X,MAP_SIZE_Y,MAP_SIZE_Z,
754                  MAP_R,MAP_G,MAP_B,MAP_DVAR,
755                  MAP_COLF,MAP_NORF,MAP_VARF,MAP_DISP}},
756         
757         {NULL, "%l", 0, -1, 0, {0}}, // separator
758         
759         {NULL, "Available", ID_LA, -2, 0, {0}}
760 };
761
762 /* Texture KeyingSets  ------ */
763
764 /* array for texture keyingset defines */
765 bKeyingSet defks_buts_shading_tex[] = 
766 {
767         /* include_cb, name, blocktype, flag, chan_num, adrcodes */
768         {NULL, "Clouds", ID_TE, 0, 5, 
769                 {TE_NSIZE,TE_NDEPTH,TE_NTYPE,
770                  TE_MG_TYP,TE_N_BAS1}},
771         
772         {NULL, "Marble", ID_TE, 0, 7, 
773                 {TE_NSIZE,TE_NDEPTH,TE_NTYPE,
774                  TE_TURB,TE_MG_TYP,TE_N_BAS1,TE_N_BAS2}},
775                  
776         {NULL, "Stucci", ID_TE, 0, 5, 
777                 {TE_NSIZE,TE_NTYPE,TE_TURB,
778                  TE_MG_TYP,TE_N_BAS1}},
779                  
780         {NULL, "Wood", ID_TE, 0, 6, 
781                 {TE_NSIZE,TE_NTYPE,TE_TURB,
782                  TE_MG_TYP,TE_N_BAS1,TE_N_BAS2}},
783                  
784         {NULL, "Magic", ID_TE, 0, 2, {TE_NDEPTH,TE_TURB}},
785         
786         {NULL, "Blend", ID_TE, 0, 1, {TE_MG_TYP}},      
787                 
788         {NULL, "Musgrave", ID_TE, 0, 6, 
789                 {TE_MG_TYP,TE_MGH,TE_MG_LAC,
790                  TE_MG_OCT,TE_MG_OFF,TE_MG_GAIN}},
791                  
792         {NULL, "Voronoi", ID_TE, 0, 9, 
793                 {TE_VNW1,TE_VNW2,TE_VNW3,TE_VNW4,
794                 TE_VNMEXP,TE_VN_DISTM,TE_VN_COLT,
795                 TE_ISCA,TE_NSIZE}},
796                 
797         {NULL, "Distorted Noise", ID_TE, 0, 4, 
798                 {TE_MG_OCT,TE_MG_OFF,TE_MG_GAIN,TE_DISTA}},
799         
800         {NULL, "Color Filter", ID_TE, 0, 5, 
801                 {TE_COL_R,TE_COL_G,TE_COL_B,TE_BRIGHT,TE_CONTRA}},
802         
803         {NULL, "%l", 0, -1, 0, {0}}, // separator
804         
805         {NULL, "Available", ID_TE, -2, 0, {0}}
806 };
807
808 /* Object Buttons KeyingSets  ------ */
809
810 /* check if include particles entry  */
811 static short incl_buts_ob (bKeyingSet *ks, const char mode[])
812 {
813         //Object *ob= OBACT; // xxx
814         Object *ob= NULL;
815         /* only if object is mesh type */
816         
817         if(ob==NULL) return 0;
818         return (ob->type == OB_MESH);
819 }
820
821 /* array for texture keyingset defines */
822 bKeyingSet defks_buts_object[] = 
823 {
824         /* include_cb, name, blocktype, flag, chan_num, adrcodes */
825         {incl_buts_ob, "Surface Damping", ID_OB, 0, 1, {OB_PD_SDAMP}},
826         {incl_buts_ob, "Random Damping", ID_OB, 0, 1, {OB_PD_RDAMP}},
827         {incl_buts_ob, "Permeability", ID_OB, 0, 1, {OB_PD_PERM}},
828         
829         {NULL, "%l", 0, -1, 0, {0}}, // separator
830         
831         {NULL, "Force Strength", ID_OB, 0, 1, {OB_PD_FSTR}},
832         {NULL, "Force Falloff", ID_OB, 0, 1, {OB_PD_FFALL}},
833         
834         {NULL, "%l", 0, -1, 0, {0}}, // separator
835         
836         {NULL, "Available", ID_OB, -2, 0, {0}}  // this will include ob-transforms too!
837 };
838
839 /* Camera Buttons KeyingSets  ------ */
840
841 /* check if include internal-renderer entry  */
842 static short incl_buts_cam1 (bKeyingSet *ks, const char mode[])
843 {
844         Scene *scene= NULL; // FIXME this will cause a crash, but we need an extra arg first!
845         /* only if renderer is internal renderer */
846         return (scene->r.renderer==R_INTERN);
847 }
848
849 /* check if include external-renderer entry  */
850 static short incl_buts_cam2 (bKeyingSet *ks, const char mode[])
851 {
852         Scene *scene= NULL; // FIXME this will cause a crash, but we need an extra arg first!
853         /* only if renderer is internal renderer */
854         return (scene->r.renderer!=R_INTERN);
855 }
856
857 /* array for camera keyingset defines */
858 bKeyingSet defks_buts_cam[] = 
859 {
860         /* include_cb, name, blocktype, flag, chan_num, adrcodes */
861         {NULL, "Lens", ID_CA, 0, 1, {CAM_LENS}},
862         {NULL, "Clipping", ID_CA, 0, 2, {CAM_STA,CAM_END}},
863         {NULL, "Focal Distance", ID_CA, 0, 1, {CAM_YF_FDIST}},
864         
865         {NULL, "%l", 0, -1, 0, {0}}, // separator
866         
867         
868         {incl_buts_cam2, "Aperture", ID_CA, 0, 1, {CAM_YF_APERT}},
869         {incl_buts_cam1, "Viewplane Shift", ID_CA, 0, 2, {CAM_SHIFT_X,CAM_SHIFT_Y}},
870         
871         {NULL, "%l", 0, -1, 0, {0}}, // separator
872         
873         {NULL, "Available", ID_CA, -2, 0, {0}}
874 };
875
876 /* --- */
877
878 /* Keying Context Defines - Must keep in sync with enumeration (eKS_Contexts) */
879 bKeyingContext ks_contexts[] = 
880 {
881         KSC_TEMPLATE(v3d_object),
882         KSC_TEMPLATE(v3d_pchan),
883         
884         KSC_TEMPLATE(buts_shading_mat),
885         KSC_TEMPLATE(buts_shading_wo),
886         KSC_TEMPLATE(buts_shading_la),
887         KSC_TEMPLATE(buts_shading_tex),
888
889         KSC_TEMPLATE(buts_object),
890         KSC_TEMPLATE(buts_cam)
891 };
892
893 /* Keying Context Enumeration - Must keep in sync with definitions*/
894 typedef enum eKS_Contexts {
895         KSC_V3D_OBJECT = 0,
896         KSC_V3D_PCHAN,
897         
898         KSC_BUTS_MAT,
899         KSC_BUTS_WO,
900         KSC_BUTS_LA,
901         KSC_BUTS_TEX,
902         
903         KSC_BUTS_OB,
904         KSC_BUTS_CAM,
905         
906                 /* make sure this last one remains untouched! */
907         KSC_TOT_TYPES
908 } eKS_Contexts;
909
910
911 #endif // XXX old keyingsets code based on adrcodes... to be restored in due course
912
913 /* Macros for Declaring KeyingSets ------------------- */
914
915 /* A note about this system for declaring built-in Keying Sets:
916  *      One may ask, "What is the purpose of all of these macros and static arrays?" and 
917  *      "Why not call the KeyingSets API defined in BKE_animsys.h?". The answer is two-fold.
918  *      
919  *      1) Firstly, we use static arrays of struct definitions instead of function calls, as
920  *         it reduces the start-up overhead and allocated-memory footprint of Blender. If we called
921  *         the KeyingSets API to build these sets, the overhead of checking for unique names, allocating
922  *         memory for each and every path and KeyingSet, scattered around in RAM, all of which would increase
923  *         the startup time (which is totally unacceptable) and could lead to fragmentation+slower access times.
924  *      2) Since we aren't using function calls, we need a nice way of defining these KeyingSets in a way which
925  *         is easily readable and less prone to breakage from changes to the underlying struct definitions. Further,
926  *         adding additional entries SHOULD NOT require custom code to be written to access these new entries/sets. 
927  *         Therefore, here we have a system with nice, human-readable statements via macros, and static arrays which
928  *         are linked together using more special macros + struct definitions, allowing for such a generic + simple
929  *         initialisation function (init_builtin_keyingsets()) compared with that of something like the Nodes system.
930  *
931  * -- Joshua Leung, April 2009
932  */
933
934 /* Struct type for declaring builtin KeyingSets in as entries in static arrays*/
935 typedef struct bBuiltinKeyingSet {
936         KeyingSet ks;                   /* the KeyingSet to build */
937         int tot;                                /* the total number of paths defined */
938         KS_Path paths[64];              /* the paths for the KeyingSet to use */
939 } bBuiltinKeyingSet;
940
941         /* WARNING: the following macros must be kept in sync with the 
942          * struct definitions in DNA_anim_types.h! 
943          */
944
945 /* macro for defining a builtin KeyingSet */
946 #define BI_KS_DEFINE_BEGIN(name, keyingflag) \
947         {{NULL, NULL, {NULL, NULL}, name, KEYINGSET_BUILTIN, keyingflag},
948         
949 /* macro to finish defining a builtin KeyingSet */
950 #define BI_KS_DEFINE_END \
951         }
952         
953 /* macro to start defining paths for a builtin KeyingSet */
954 #define BI_KS_PATHS_BEGIN(tot) \
955         tot, {
956         
957 /* macro to finish defining paths for a builtin KeyingSet */
958 #define BI_KS_PATHS_END \
959         }
960         
961 /* macro for defining a builtin KeyingSet's path */
962 #define BI_KSP_DEFINE(id_type, templates, prop_path, array_index, flag, groupflag) \
963         {NULL, NULL, NULL, "", id_type, templates, prop_path, array_index, flag, groupflag}
964         
965 /* macro for defining a builtin KeyingSet with no paths (use in place of BI_KS_PAHTS_BEGIN/END block) */
966 #define BI_KS_PATHS_NONE \
967         0, {0}
968         
969 /* ---- */
970
971 /* Struct type for finding all the arrays of builtin KeyingSets */
972 typedef struct bBuiltinKSContext {
973         bBuiltinKeyingSet *bks;         /* array of KeyingSet definitions */
974         int tot;                                        /* number of KeyingSets in this array */
975 } bBuiltinKSContext;
976
977 /* macro for defining builtin KeyingSet sets 
978  * NOTE: all the arrays of sets must follow this naming convention!
979  */
980 #define BKSC_TEMPLATE(ctx_name) {&def_builtin_keyingsets_##ctx_name[0], sizeof(def_builtin_keyingsets_##ctx_name)/sizeof(bBuiltinKeyingSet)}
981
982
983 /* 3D-View Builtin KeyingSets ------------------------ */
984
985 static bBuiltinKeyingSet def_builtin_keyingsets_v3d[] =
986 {
987         /* Simple Keying Sets ************************************* */
988         /* Keying Set - "Location" ---------- */
989         BI_KS_DEFINE_BEGIN("Location", 0)
990                 BI_KS_PATHS_BEGIN(1)
991                         BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN, "location", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM) 
992                 BI_KS_PATHS_END
993         BI_KS_DEFINE_END,
994
995         /* Keying Set - "Rotation" ---------- */
996         BI_KS_DEFINE_BEGIN("Rotation", 0)
997                 BI_KS_PATHS_BEGIN(1)
998                         BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN|KSP_TEMPLATE_ROT, "rotation", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM) 
999                 BI_KS_PATHS_END
1000         BI_KS_DEFINE_END,
1001         
1002         /* Keying Set - "Scaling" ---------- */
1003         BI_KS_DEFINE_BEGIN("Scaling", 0)
1004                 BI_KS_PATHS_BEGIN(1)
1005                         BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN, "scale", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM) 
1006                 BI_KS_PATHS_END
1007         BI_KS_DEFINE_END,
1008         
1009         /* Compound Keying Sets *********************************** */
1010         /* Keying Set - "LocRot" ---------- */
1011         BI_KS_DEFINE_BEGIN("LocRot", 0)
1012                 BI_KS_PATHS_BEGIN(2)
1013                         BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN, "location", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM), 
1014                         BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN|KSP_TEMPLATE_ROT, "rotation", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM) 
1015                 BI_KS_PATHS_END
1016         BI_KS_DEFINE_END,
1017         
1018         /* Keying Set - "LocRotScale" ---------- */
1019         BI_KS_DEFINE_BEGIN("LocRotScale", 0)
1020                 BI_KS_PATHS_BEGIN(3)
1021                         BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN, "location", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM), 
1022                         BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN|KSP_TEMPLATE_ROT, "rotation", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM), 
1023                         BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN, "scale", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM) 
1024                 BI_KS_PATHS_END
1025         BI_KS_DEFINE_END,
1026         
1027         /* Keying Sets with Keying Flags ************************* */
1028         /* Keying Set - "VisualLoc" ---------- */
1029         BI_KS_DEFINE_BEGIN("VisualLoc", INSERTKEY_MATRIX)
1030                 BI_KS_PATHS_BEGIN(1)
1031                         BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN, "location", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM) 
1032                 BI_KS_PATHS_END
1033         BI_KS_DEFINE_END,
1034
1035         /* Keying Set - "Rotation" ---------- */
1036         BI_KS_DEFINE_BEGIN("VisualRot", INSERTKEY_MATRIX)
1037                 BI_KS_PATHS_BEGIN(1)
1038                         BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN|KSP_TEMPLATE_ROT, "rotation", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM) 
1039                 BI_KS_PATHS_END
1040         BI_KS_DEFINE_END,
1041         
1042         /* Keying Set - "VisualLocRot" ---------- */
1043         BI_KS_DEFINE_BEGIN("VisualLocRot", INSERTKEY_MATRIX)
1044                 BI_KS_PATHS_BEGIN(2)
1045                         BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN, "location", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM), 
1046                         BI_KSP_DEFINE(ID_OB, KSP_TEMPLATE_OBJECT|KSP_TEMPLATE_PCHAN|KSP_TEMPLATE_ROT, "rotation", 0, KSP_FLAG_WHOLE_ARRAY, KSP_GROUP_TEMPLATE_ITEM) 
1047                 BI_KS_PATHS_END
1048         BI_KS_DEFINE_END
1049 };
1050
1051 /* All Builtin KeyingSets ------------------------ */
1052
1053 /* total number of builtin KeyingSet contexts */
1054 #define MAX_BKSC_TYPES  1
1055
1056 /* array containing all the available builtin KeyingSets definition sets 
1057  *      - size of this is MAX_BKSC_TYPES+1 so that we don't smash the stack
1058  */
1059 static bBuiltinKSContext def_builtin_keyingsets[MAX_BKSC_TYPES+1] =
1060 {
1061         BKSC_TEMPLATE(v3d)
1062         /* add more contexts above this line... */
1063 };
1064
1065
1066 /* ListBase of these KeyingSets chained up ready for usage 
1067  * NOTE: this is exported to keyframing.c for use...
1068  */
1069 ListBase builtin_keyingsets = {NULL, NULL};
1070
1071 /* Utility API ------------------------ */
1072
1073 /* Link up all of the builtin Keying Sets when starting up Blender
1074  * This is called from WM_init() in wm_init_exit.c
1075  */
1076 void init_builtin_keyingsets (void)
1077 {
1078         bBuiltinKSContext *bksc;
1079         bBuiltinKeyingSet *bks;
1080         int bksc_i, bks_i;
1081         
1082         /* loop over all the sets of KeyingSets, setting them up, and chaining them to the builtins list */
1083         for (bksc_i= 0, bksc= &def_builtin_keyingsets[0]; bksc_i < MAX_BKSC_TYPES; bksc_i++, bksc++)
1084         {
1085                 /* for each set definitions for a builtin KeyingSet, chain the paths to that KeyingSet and add */
1086                 for (bks_i= 0, bks= bksc->bks; bks_i < bksc->tot; bks_i++, bks++)
1087                 {
1088                         KeyingSet *ks= &bks->ks;
1089                         KS_Path *ksp;
1090                         int pIndex;
1091                         
1092                         /* loop over paths, linking them to the KeyingSet and each other */
1093                         for (pIndex= 0, ksp= &bks->paths[0]; pIndex < bks->tot; pIndex++, ksp++)
1094                                 BLI_addtail(&ks->paths, ksp);
1095                                 
1096                         /* add KeyingSet to builtin sets list */
1097                         BLI_addtail(&builtin_keyingsets, ks);
1098                 }
1099         }
1100 }
1101
1102
1103 /* Get the first builtin KeyingSet with the given name, which occurs after the given one (or start of list if none given) */
1104 KeyingSet *ANIM_builtin_keyingset_get_named (KeyingSet *prevKS, char name[])
1105 {
1106         KeyingSet *ks, *first=NULL;
1107         
1108         /* sanity checks - any name to check? */
1109         if (name[0] == 0)
1110                 return NULL;
1111         
1112         /* get first KeyingSet to use */
1113         if (prevKS && prevKS->next)
1114                 first= prevKS->next;
1115         else
1116                 first= builtin_keyingsets.first;
1117                 
1118         /* loop over KeyingSets checking names */
1119         for (ks= first; ks; ks= ks->next) {
1120                 if (strcmp(name, ks->name) == 0)
1121                         return ks;
1122         }
1123         
1124         /* no matches found */
1125         return NULL;
1126 }
1127
1128
1129 /* Get the active Keying Set for the Scene provided */
1130 KeyingSet *ANIM_scene_get_active_keyingset (Scene *scene)
1131 {
1132         if (ELEM(NULL, scene, scene->keyingsets.first))
1133                 return NULL;
1134         
1135         /* currently, there are several possibilities here:
1136          *      -   0: no active keying set
1137          *      - > 0: one of the user-defined Keying Sets, but indices start from 0 (hence the -1)
1138          *      - < 0: a builtin keying set (XXX this isn't enabled yet so that we don't get errors on reading back files)
1139          */
1140         if (scene->active_keyingset > 0)
1141                 return BLI_findlink(&scene->keyingsets, scene->active_keyingset-1);
1142         else // for now...
1143                 return NULL; 
1144 }
1145
1146 /* ******************************************* */
1147 /* KEYFRAME MODIFICATION */
1148
1149 /* KeyingSet Menu Helpers ------------ */
1150
1151 /* Extract the maximum set of requirements from the KeyingSet */
1152 static int keyingset_relative_get_templates (KeyingSet *ks)
1153 {
1154         KS_Path *ksp;
1155         int templates= 0;
1156         
1157         /* loop over the paths (could be slow to do for a number of KeyingSets)? */
1158         for (ksp= ks->paths.first; ksp; ksp= ksp->next) {
1159                 /* add the destination's templates to the set of templates required for the set */
1160                 templates |= ksp->templates;
1161         }
1162         
1163         return templates;
1164 }
1165
1166 /* Check if context data is suitable for the given absolute Keying Set */
1167 short keyingset_context_ok_poll (bContext *C, KeyingSet *ks)
1168 {
1169         ScrArea *sa= CTX_wm_area(C);
1170         
1171         /* data retrieved from context depends on active editor */
1172         if (sa == NULL) return 0;
1173                 
1174         switch (sa->spacetype) {
1175                 case SPACE_VIEW3D:
1176                 {
1177                         Object *obact= CTX_data_active_object(C);
1178                         
1179                         /* if in posemode, check if 'pose-channels' requested for in KeyingSet */
1180                         if ((obact && obact->pose) && (obact->mode & OB_MODE_POSE)) {
1181                                 /* check for posechannels */
1182                                 
1183                         }
1184                         else {
1185                                 /* check for selected object */
1186                                 
1187                         }
1188                 }
1189                         break;
1190         }
1191         
1192         
1193         return 1;
1194 }
1195
1196 /* KeyingSet Context Operations ------------ */
1197
1198 /* Get list of data-sources from context (in 3D-View) for inserting keyframes using the given relative Keying Set */
1199 static short modifykey_get_context_v3d_data (bContext *C, ListBase *dsources, KeyingSet *ks)
1200 {
1201         bCommonKeySrc *cks;
1202         Object *obact= CTX_data_active_object(C);
1203         int templates; 
1204         short ok= 0;
1205         
1206         /* get the templates in use in this KeyingSet which we should supply data for */
1207         templates = keyingset_relative_get_templates(ks);
1208         
1209         /* check if the active object is in PoseMode (i.e. only deal with bones) */
1210         // TODO: check with the templates to see what we really need to store 
1211         if ((obact && obact->pose) && (obact->mode & OB_MODE_POSE)) {
1212                 /* Pose Mode: Selected bones */
1213 #if 0
1214                 //set_pose_keys(ob);  /* sets pchan->flag to POSE_KEY if bone selected, and clears if not */
1215                 
1216                 /* loop through posechannels */
1217                 //for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next) {
1218                 //      if (pchan->flag & POSE_KEY) {
1219                 //      }
1220                 //}
1221 #endif
1222                 
1223                 CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pose_bones)
1224                 {
1225                         /* add a new keying-source */
1226                         cks= MEM_callocN(sizeof(bCommonKeySrc), "bCommonKeySrc");
1227                         BLI_addtail(dsources, cks);
1228                         
1229                         /* set necessary info */
1230                         cks->id= &obact->id;
1231                         cks->pchan= pchan;
1232                         
1233                         if (templates & KSP_TEMPLATE_CONSTRAINT)
1234                                 cks->con= constraints_get_active(&pchan->constraints);
1235                         
1236                         ok= 1;
1237                 }
1238                 CTX_DATA_END;
1239         }
1240         else {
1241                 /* Object Mode: Selected objects */
1242                 CTX_DATA_BEGIN(C, Object*, ob, selected_objects) 
1243                 {                       
1244                         /* add a new keying-source */
1245                         cks= MEM_callocN(sizeof(bCommonKeySrc), "bCommonKeySrc");
1246                         BLI_addtail(dsources, cks);
1247                         
1248                         /* set necessary info */
1249                         cks->id= &ob->id;
1250                         
1251                         if (templates & KSP_TEMPLATE_CONSTRAINT)
1252                                 cks->con= constraints_get_active(&ob->constraints);
1253                         
1254                         ok= 1;
1255                 }
1256                 CTX_DATA_END;
1257         }
1258         
1259         /* return whether any data was extracted */
1260         return ok;
1261 }
1262
1263 /* Get list of data-sources from context for inserting keyframes using the given relative Keying Set */
1264 short modifykey_get_context_data (bContext *C, ListBase *dsources, KeyingSet *ks)
1265 {
1266         ScrArea *sa= CTX_wm_area(C);
1267         
1268         /* for now, the active area is used to determine what set of contexts apply */
1269         if (sa == NULL)
1270                 return 0;
1271
1272 #if 0
1273         switch (sa->spacetype) {
1274                 case SPACE_VIEW3D:      /* 3D-View: Selected Objects or Bones */
1275                         return modifykey_get_context_v3d_data(C, dsources, ks);
1276         }
1277         
1278         /* nothing happened */
1279         return 0;
1280 #endif
1281
1282         /* looking into this code, it doesnt use the 3D view - Campbell */
1283         return modifykey_get_context_v3d_data(C, dsources, ks);
1284
1285
1286 /* KeyingSet Operations (Insert/Delete Keyframes) ------------ */
1287
1288 /* Given a KeyingSet and context info (if required), modify keyframes for the channels specified
1289  * by the KeyingSet. This takes into account many of the different combinations of using KeyingSets.
1290  * Returns the number of channels that keyframes were added to
1291  */
1292 int modify_keyframes (Scene *scene, ListBase *dsources, bAction *act, KeyingSet *ks, short mode, float cfra)
1293 {
1294         KS_Path *ksp;
1295         int kflag=0, success= 0;
1296         char *groupname= NULL;
1297         
1298         /* sanity checks */
1299         if (ks == NULL)
1300                 return 0;
1301         
1302         /* get flags to use */
1303         if (mode == MODIFYKEY_MODE_INSERT) {
1304                 /* use KeyingSet's flags as base */
1305                 kflag= ks->keyingflag;
1306                 
1307                 /* suppliment with info from the context */
1308                 kflag |= ANIM_get_keyframing_flags(scene, 1);
1309         }
1310         else if (mode == MODIFYKEY_MODE_DELETE)
1311                 kflag= 0;
1312         
1313         /* check if the KeyingSet is absolute or not (i.e. does it requires sources info) */
1314         if (ks->flag & KEYINGSET_ABSOLUTE) {
1315                 /* Absolute KeyingSets are simpler to use, as all the destination info has already been
1316                  * provided by the user, and is stored, ready to use, in the KeyingSet paths.
1317                  */
1318                 for (ksp= ks->paths.first; ksp; ksp= ksp->next) {
1319                         int arraylen, i;
1320                         
1321                         /* get pointer to name of group to add channels to */
1322                         if (ksp->groupmode == KSP_GROUP_NONE)
1323                                 groupname= NULL;
1324                         else if (ksp->groupmode == KSP_GROUP_KSNAME)
1325                                 groupname= ks->name;
1326                         else
1327                                 groupname= ksp->group;
1328                         
1329                         /* init arraylen and i - arraylen should be greater than i so that
1330                          * normal non-array entries get keyframed correctly
1331                          */
1332                         i= ksp->array_index;
1333                         arraylen= i;
1334                         
1335                         /* get length of array if whole array option is enabled */
1336                         if (ksp->flag & KSP_FLAG_WHOLE_ARRAY) {
1337                                 PointerRNA id_ptr, ptr;
1338                                 PropertyRNA *prop;
1339                                 
1340                                 RNA_id_pointer_create(ksp->id, &id_ptr);
1341                                 if (RNA_path_resolve(&id_ptr, ksp->rna_path, &ptr, &prop) && prop)
1342                                         arraylen= RNA_property_array_length(&ptr, prop);
1343                         }
1344                         
1345                         /* we should do at least one step */
1346                         if (arraylen == i)
1347                                 arraylen++;
1348                         
1349                         /* for each possible index, perform operation 
1350                          *      - assume that arraylen is greater than index
1351                          */
1352                         for (; i < arraylen; i++) {
1353                                 /* action to take depends on mode */
1354                                 if (mode == MODIFYKEY_MODE_INSERT)
1355                                         success += insert_keyframe(ksp->id, act, groupname, ksp->rna_path, i, cfra, kflag);
1356                                 else if (mode == MODIFYKEY_MODE_DELETE)
1357                                         success += delete_keyframe(ksp->id, act, groupname, ksp->rna_path, i, cfra, kflag);
1358                         }
1359                         
1360                         /* set recalc-flags */
1361                         if (ksp->id) {
1362                                 switch (GS(ksp->id->name)) {
1363                                         case ID_OB: /* Object (or Object-Related) Keyframes */
1364                                         {
1365                                                 Object *ob= (Object *)ksp->id;
1366                                                 
1367                                                 ob->recalc |= OB_RECALC;
1368                                         }
1369                                                 break;
1370                                 }
1371                                 
1372                                 /* send notifiers for updates (this doesn't require context to work!) */
1373                                 WM_main_add_notifier(NC_ANIMATION|ND_KEYFRAME_EDIT, NULL);
1374                         }
1375                 }
1376         }
1377         else if (dsources && dsources->first) {
1378                 /* for each one of the 'sources', resolve the template markers and expand arrays, then insert keyframes */
1379                 bCommonKeySrc *cks;
1380                 
1381                 /* for each 'source' for keyframe data, resolve each of the paths from the KeyingSet */
1382                 for (cks= dsources->first; cks; cks= cks->next) {
1383                         /* for each path in KeyingSet, construct a path using the templates */
1384                         for (ksp= ks->paths.first; ksp; ksp= ksp->next) {
1385                                 DynStr *pathds= BLI_dynstr_new();
1386                                 char *path = NULL;
1387                                 int arraylen, i;
1388                                 
1389                                 /* set initial group name */
1390                                 if (cks->id == NULL) {
1391                                         printf("ERROR: Skipping 'Common-Key' Source. No valid ID present.\n");
1392                                         continue;
1393                                 }
1394                                 else
1395                                         groupname= cks->id->name+2;
1396                                 
1397                                 /* construct the path */
1398                                 // FIXME: this currently only works with a few hardcoded cases
1399                                 if ((ksp->templates & KSP_TEMPLATE_PCHAN) && (cks->pchan)) {
1400                                         /* add basic pose-channel path access */
1401                                         BLI_dynstr_append(pathds, "pose.bones[\"");
1402                                         BLI_dynstr_append(pathds, cks->pchan->name);
1403                                         BLI_dynstr_append(pathds, "\"]");
1404                                         
1405                                         /* override default group name */
1406                                         groupname= cks->pchan->name;
1407                                 }
1408                                 if ((ksp->templates & KSP_TEMPLATE_CONSTRAINT) && (cks->con)) {
1409                                         /* add basic constraint path access */
1410                                         BLI_dynstr_append(pathds, "constraints[\"");
1411                                         BLI_dynstr_append(pathds, cks->con->name);
1412                                         BLI_dynstr_append(pathds, "\"]");
1413                                         
1414                                         /* override default group name */
1415                                         groupname= cks->con->name;
1416                                 }
1417                                 {
1418                                         /* add property stored in KeyingSet Path */
1419                                         if (BLI_dynstr_get_len(pathds))
1420                                                 BLI_dynstr_append(pathds, ".");
1421                                                 
1422                                         /* apply some further templates? */
1423                                         if (ksp->templates & KSP_TEMPLATE_ROT) {
1424                                                 /* for builtin Keying Sets, this template makes the best fitting path for the 
1425                                                  * current rotation mode of the Object / PoseChannel to be used
1426                                                  */
1427                                                 if (strcmp(ksp->rna_path, "rotation")==0) {
1428                                                         /* get rotation mode */
1429                                                         short rotmode= (cks->pchan)? (cks->pchan->rotmode) : 
1430                                                                                    (GS(cks->id->name)==ID_OB)? ( ((Object *)cks->id)->rotmode ) :
1431                                                                                    (0);
1432                                                         
1433                                                         /* determine path to build */
1434                                                         if (rotmode == ROT_MODE_QUAT)
1435                                                                 BLI_dynstr_append(pathds, "rotation_quaternion");
1436                                                         else if (rotmode == ROT_MODE_AXISANGLE)
1437                                                                 BLI_dynstr_append(pathds, "rotation_axis_angle");
1438                                                         else
1439                                                                 BLI_dynstr_append(pathds, "rotation_euler");
1440                                                 }
1441                                         }
1442                                         else {
1443                                                 /* just directly use the path */
1444                                                 BLI_dynstr_append(pathds, ksp->rna_path);
1445                                         }
1446                                         
1447                                         /* convert to C-string */
1448                                         path= BLI_dynstr_get_cstring(pathds);
1449                                         BLI_dynstr_free(pathds);
1450                                 }
1451                                 
1452                                 /* get pointer to name of group to add channels to 
1453                                  *      - KSP_GROUP_TEMPLATE_ITEM is handled above while constructing the paths 
1454                                  */
1455                                 if (ksp->groupmode == KSP_GROUP_NONE)
1456                                         groupname= NULL;
1457                                 else if (ksp->groupmode == KSP_GROUP_KSNAME)
1458                                         groupname= ks->name;
1459                                 else if (ksp->groupmode == KSP_GROUP_NAMED)
1460                                         groupname= ksp->group;
1461                                 
1462                                 /* init arraylen and i - arraylen should be greater than i so that
1463                                  * normal non-array entries get keyframed correctly
1464                                  */
1465                                 i= ksp->array_index;
1466                                 arraylen= i+1;
1467                                 
1468                                 /* get length of array if whole array option is enabled */
1469                                 if (ksp->flag & KSP_FLAG_WHOLE_ARRAY) {
1470                                         PointerRNA id_ptr, ptr;
1471                                         PropertyRNA *prop;
1472                                         
1473                                         RNA_id_pointer_create(cks->id, &id_ptr);
1474                                         if (RNA_path_resolve(&id_ptr, path, &ptr, &prop) && prop)
1475                                                 arraylen= RNA_property_array_length(&ptr, prop);
1476                                 }
1477                                 
1478                                 /* for each possible index, perform operation 
1479                                  *      - assume that arraylen is greater than index
1480                                  */
1481                                 for (; i < arraylen; i++) {
1482                                         /* action to take depends on mode */
1483                                         if (mode == MODIFYKEY_MODE_INSERT)
1484                                                 success+= insert_keyframe(cks->id, act, groupname, path, i, cfra, kflag);
1485                                         else if (mode == MODIFYKEY_MODE_DELETE)
1486                                                 success+= delete_keyframe(cks->id, act, groupname, path, i, cfra, kflag);
1487                                 }
1488                                 
1489                                 /* free the path */
1490                                 MEM_freeN(path);
1491                         }
1492                         
1493                         /* set recalc-flags */
1494                         if (cks->id) {
1495                                 switch (GS(cks->id->name)) {
1496                                         case ID_OB: /* Object (or Object-Related) Keyframes */
1497                                         {
1498                                                 Object *ob= (Object *)cks->id;
1499                                                 
1500                                                 ob->recalc |= OB_RECALC;
1501                                         }
1502                                                 break;
1503                                 }
1504                                 
1505                                 /* send notifiers for updates (this doesn't require context to work!) */
1506                                 WM_main_add_notifier(NC_ANIMATION|ND_KEYFRAME_EDIT, NULL);
1507                         }
1508                 }
1509         }
1510         
1511         /* return the number of channels successfully affected */
1512         return success;
1513 }
1514
1515 /* ************************************************** */