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