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