2.5 Action Editor - Big WIP Commit
[blender-staging.git] / source / blender / editors / animation / keyframing.c
1 /**
2  * $Id: keyframing.c 17745 2008-12-08 09:16:09Z aligorith $
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) 2008, Blender Foundation
21  * This is a new part of Blender (with some old code)
22  *
23  * Contributor(s): Joshua Leung
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28
29
30 #include <stdio.h>
31 #include <string.h>
32 #include <stdlib.h>
33 #include <stddef.h>
34 #include <math.h>
35 #include <float.h>
36
37 #ifdef HAVE_CONFIG_H
38 #include <config.h>
39 #endif
40
41 #include "MEM_guardedalloc.h"
42
43 #include "BLI_arithb.h"
44 #include "BLI_blenlib.h"
45 #include "BLI_dynstr.h"
46
47 #include "DNA_listBase.h"
48 #include "DNA_ID.h"
49 #include "DNA_action_types.h"
50 #include "DNA_armature_types.h"
51 #include "DNA_camera_types.h"
52 #include "DNA_constraint_types.h"
53 #include "DNA_curve_types.h"
54 #include "DNA_ipo_types.h"
55 #include "DNA_key_types.h"
56 #include "DNA_lamp_types.h"
57 #include "DNA_object_types.h"
58 #include "DNA_material_types.h"
59 #include "DNA_screen_types.h"
60 #include "DNA_scene_types.h"
61 #include "DNA_space_types.h"
62 #include "DNA_texture_types.h"
63 #include "DNA_userdef_types.h"
64 #include "DNA_vec_types.h"
65 #include "DNA_view3d_types.h"
66 #include "DNA_world_types.h"
67
68 #include "BKE_global.h"
69 #include "BKE_utildefines.h"
70 #include "BKE_blender.h"
71 #include "BKE_main.h"  // XXX not needed old cruft?
72 #include "BKE_action.h"
73 #include "BKE_armature.h"
74 #include "BKE_constraint.h"
75 #include "BKE_curve.h"
76 #include "BKE_depsgraph.h"
77 #include "BKE_ipo.h"
78 #include "BKE_key.h"
79 #include "BKE_object.h"
80 #include "BKE_material.h"
81
82 #include "ED_keyframing.h"
83
84 #if 0 // XXX resolve these old dependencies!
85 #include "BIF_butspace.h"
86 #include "BIF_editaction.h"
87 #include "BIF_editkey.h"
88 #include "BIF_interface.h"
89 #include "BIF_mywindow.h"
90 #include "BIF_poseobject.h"
91 #include "BIF_screen.h"
92 #include "BIF_space.h"
93 #include "BIF_toolbox.h"
94 #include "BIF_toets.h"
95
96 #include "BSE_editipo.h"
97 #include "BSE_node.h"
98 #include "BSE_time.h"
99 #include "BSE_view.h"
100
101 #include "blendef.h"
102
103 #include "PIL_time.h"                   /* sleep                                */
104 #include "mydevice.h"
105 #endif // XXX resolve these old dependencies!
106
107
108
109 /* ************************************************** */
110 /* LOCAL TYPES AND DEFINES */
111
112 /* ----------- Common KeyData Sources ------------ */
113
114 /* temporary struct to gather data combos to keyframe */
115 typedef struct bCommonKeySrc {
116         struct bCommonKeySrc *next, *prev;
117                 
118                 /* general data/destination-source settings */
119         ID *id;                                 /* id-block this comes from */
120         char *actname;                  /* name of action channel */
121         char *constname;                /* name of constraint channel */
122         
123                 /* general destination source settings */
124         Ipo *ipo;                               /* ipo-block that id-block has (optional) */
125         bAction *act;                   /* action-block that id-block has (optional) */
126         
127                 /* pose-level settings */
128         bPoseChannel *pchan;    /* pose channel */
129                 
130                 /* buttons-window settings */
131         int map;                                /* offset to apply to certain adrcodes */
132 } bCommonKeySrc;
133
134 /* -------------- Keying Sets ------------------- */
135
136 /* storage for iterator for looping over keyingset channels */
137 typedef struct bKS_AdrcodeGetter {
138         struct bKeyingSet *ks;          /* keyingset this applies to */
139         struct bCommonKeySrc *cks;      /* data to insert/delete keyframes... */
140         
141         short index;                            /* index of current channel to resume from */
142         short tot;                                      /* index after which we start returning from some special collection */
143 } bKS_AdrcodeGetter;
144
145 /* flags to look out for in keyingset channels... */
146 #define KAG_CHAN_EXTEND         (-1)
147
148
149 /* keying set - a set of channels that will be keyframed together  */
150 // TODO: move this to a header to allow custom sets someday?
151 typedef struct bKeyingSet {
152                 /* callback func to consider if keyingset should be included 
153                  * (by default, if this is undefined, item will be shown) 
154                  */
155         short (*include_cb)(struct bKeyingSet *, const char *);
156         
157         char name[48];                          /* name of keyingset */
158         int blocktype;                          /* blocktype that all channels belong to */  // in future, this may be eliminated
159         short flag;                                     /* flags to use when setting keyframes */
160         
161         short chan_num;                         /* number of channels to insert keyframe in */
162         short adrcodes[32];                     /* adrcodes for channels to insert keys for (ideally would be variable-len, but limit of 32 will suffice) */
163 } bKeyingSet;
164
165 /* keying set context - an array of keying sets and the number of them */
166 typedef struct bKeyingContext {
167         bKeyingSet *keyingsets;         /* array containing the keyingsets of interest */
168         bKeyingSet *lastused;           /* item that was chosen last time*/
169         int tot;                                        /* number of keyingsets in */
170 } bKeyingContext;
171
172 /* ************************************************** */
173 /* KEYFRAME INSERTION */
174
175 /* -------------- BezTriple Insertion -------------------- */
176
177 /* threshold for inserting keyframes - threshold here should be good enough for now, but should become userpref */
178 #define BEZT_INSERT_THRESH      0.00001
179
180 /* Binary search algorithm for finding where to insert BezTriple. (for use by insert_bezt_icu)
181  * Returns the index to insert at (data already at that index will be offset if replace is 0)
182  */
183 static int binarysearch_bezt_index (BezTriple array[], float frame, int arraylen, short *replace)
184 {
185         int start=0, end=arraylen;
186         int loopbreaker= 0, maxloop= arraylen * 2;
187         
188         /* initialise replace-flag first */
189         *replace= 0;
190         
191         /* sneaky optimisations (don't go through searching process if...):
192          *      - keyframe to be added is to be added out of current bounds
193          *      - keyframe to be added would replace one of the existing ones on bounds
194          */
195         if ((arraylen <= 0) || (array == NULL)) {
196                 printf("Warning: binarysearch_bezt_index() encountered invalid array \n");
197                 return 0;
198         }
199         else {
200                 /* check whether to add before/after/on */
201                 float framenum;
202                 
203                 /* 'First' Keyframe (when only one keyframe, this case is used) */
204                 framenum= array[0].vec[1][0];
205                 if (IS_EQT(frame, framenum, BEZT_INSERT_THRESH)) {
206                         *replace = 1;
207                         return 0;
208                 }
209                 else if (frame < framenum)
210                         return 0;
211                         
212                 /* 'Last' Keyframe */
213                 framenum= array[(arraylen-1)].vec[1][0];
214                 if (IS_EQT(frame, framenum, BEZT_INSERT_THRESH)) {
215                         *replace= 1;
216                         return (arraylen - 1);
217                 }
218                 else if (frame > framenum)
219                         return arraylen;
220         }
221         
222         
223         /* most of the time, this loop is just to find where to put it
224          * 'loopbreaker' is just here to prevent infinite loops 
225          */
226         for (loopbreaker=0; (start <= end) && (loopbreaker < maxloop); loopbreaker++) {
227                 /* compute and get midpoint */
228                 int mid = (start + end) / 2;
229                 float midfra= array[mid].vec[1][0];
230                 
231                 /* check if exactly equal to midpoint */
232                 if (IS_EQT(frame, midfra, BEZT_INSERT_THRESH)) {
233                         *replace = 1;
234                         return mid;
235                 }
236                 
237                 /* repeat in upper/lower half */
238                 if (frame > midfra)
239                         start= mid + 1;
240                 else if (frame < midfra)
241                         end= mid - 1;
242         }
243         
244         /* print error if loop-limit exceeded */
245         if (loopbreaker == (maxloop-1)) {
246                 printf("Error: binarysearch_bezt_index() was taking too long \n");
247                 
248                 // include debug info 
249                 printf("\tround = %d: start = %d, end = %d, arraylen = %d \n", loopbreaker, start, end, arraylen);
250         }
251         
252         /* not found, so return where to place it */
253         return start;
254 }
255
256 /* This function adds a given BezTriple to an IPO-Curve. It will allocate 
257  * memory for the array if needed, and will insert the BezTriple into a
258  * suitable place in chronological order.
259  * 
260  * NOTE: any recalculate of the IPO-Curve that needs to be done will need to 
261  *              be done by the caller.
262  */
263 int insert_bezt_icu (IpoCurve *icu, BezTriple *bezt)
264 {
265         BezTriple *newb;
266         int i= 0;
267         
268         if (icu->bezt) {
269                 short replace = -1;
270                 i = binarysearch_bezt_index(icu->bezt, bezt->vec[1][0], icu->totvert, &replace);
271                 
272                 if (replace) {                  
273                         /* sanity check: 'i' may in rare cases exceed arraylen */
274                         // FIXME: do not overwrite handletype if just replacing...?
275                         if ((i >= 0) && (i < icu->totvert))
276                                 *(icu->bezt + i) = *bezt;
277                 }
278                 else {
279                         /* add new */
280                         newb= MEM_callocN((icu->totvert+1)*sizeof(BezTriple), "beztriple");
281                         
282                         /* add the beztriples that should occur before the beztriple to be pasted (originally in ei->icu) */
283                         if (i > 0)
284                                 memcpy(newb, icu->bezt, i*sizeof(BezTriple));
285                         
286                         /* add beztriple to paste at index i */
287                         *(newb + i)= *bezt;
288                         
289                         /* add the beztriples that occur after the beztriple to be pasted (originally in icu) */
290                         if (i < icu->totvert) 
291                                 memcpy(newb+i+1, icu->bezt+i, (icu->totvert-i)*sizeof(BezTriple));
292                         
293                         /* replace (+ free) old with new */
294                         MEM_freeN(icu->bezt);
295                         icu->bezt= newb;
296                         
297                         icu->totvert++;
298                 }
299         }
300         else {
301                 icu->bezt= MEM_callocN(sizeof(BezTriple), "beztriple");
302                 *(icu->bezt)= *bezt;
303                 icu->totvert= 1;
304         }
305         
306         
307         /* we need to return the index, so that some tools which do post-processing can 
308          * detect where we added the BezTriple in the array
309          */
310         return i;
311 }
312
313 /* This function is a wrapper for insert_bezt_icu, and should be used when
314  * adding a new keyframe to a curve, when the keyframe doesn't exist anywhere
315  * else yet. 
316  * 
317  * 'fast' - is only for the python API where importing BVH's would take an extreamly long time.
318  */
319 void insert_vert_icu (IpoCurve *icu, float x, float y, short fast)
320 {
321         BezTriple beztr;
322         int a, h1, h2;
323         
324         /* set all three points, for nicer start position */
325         memset(&beztr, 0, sizeof(BezTriple));
326         beztr.vec[0][0]= x; 
327         beztr.vec[0][1]= y;
328         beztr.vec[1][0]= x;
329         beztr.vec[1][1]= y;
330         beztr.vec[2][0]= x;
331         beztr.vec[2][1]= y;
332         beztr.hide= IPO_BEZ;
333         beztr.f1= beztr.f2= beztr.f3= SELECT;
334         beztr.h1= beztr.h2= HD_AUTO;
335         
336         /* add temp beztriple to keyframes */
337         a= insert_bezt_icu(icu, &beztr);
338         
339         /* what if 'a' is a negative index? 
340          * for now, just exit to prevent any segfaults
341          */
342         if (a < 0) return;
343         
344         /* don't recalculate handles if fast is set
345          *      - this is a hack to make importers faster
346          *      - we may calculate twice (see editipo_changed(), due to autohandle needing two calculations)
347          */
348         if (!fast) calchandles_ipocurve(icu);
349         
350         /* set handletype and interpolation */
351         if (icu->totvert > 2) {
352                 BezTriple *bezt= (icu->bezt + a);
353                 
354                 /* set handles (autohandles by default) */
355                 h1= h2= HD_AUTO;
356                 
357                 if (a > 0) h1= (bezt-1)->h2;
358                 if (a < icu->totvert-1) h2= (bezt+1)->h1;
359                 
360                 bezt->h1= h1;
361                 bezt->h2= h2;
362                 
363                 /* set interpolation (if curve is using IPO_MIXED, then take from previous) */
364                 if (icu->ipo == IPO_MIXED) {
365                         if (a > 0) bezt->ipo= (bezt-1)->ipo;
366                         else if (a < icu->totvert-1) bezt->ipo= (bezt+1)->ipo;
367                 }
368                 else
369                         bezt->ipo= icu->ipo;
370                         
371                 /* don't recalculate handles if fast is set
372                  *      - this is a hack to make importers faster
373                  *      - we may calculate twice (see editipo_changed(), due to autohandle needing two calculations)
374                  */
375                 if (!fast) calchandles_ipocurve(icu);
376         }
377         else {
378                 BezTriple *bezt= (icu->bezt + a);
379                 
380                 /* set interpolation directly from ipo-curve */
381                 bezt->ipo= icu->ipo;
382         }
383 }
384
385 #if 0 // XXX code to clean up
386
387 /* ------------------- Get Data ------------------------ */
388
389 /* Get pointer to use to get values from */
390 // FIXME: this should not be possible with Data-API
391 static void *get_context_ipo_poin (ID *id, int blocktype, char *actname, char *constname, IpoCurve *icu, int *vartype)
392 {
393         switch (blocktype) {
394                 case ID_PO:  /* posechannel */
395                         if (GS(id->name)==ID_OB) {
396                                 Object *ob= (Object *)id;
397                                 bPoseChannel *pchan= get_pose_channel(ob->pose, actname);
398                                 
399                                 if (pchan) {
400                                         if (ELEM3(icu->adrcode, AC_EUL_X, AC_EUL_Y, AC_EUL_Z))
401                                                 *vartype= IPO_FLOAT_DEGR;
402                                         else
403                                                 *vartype= IPO_FLOAT;
404                                         return get_pchan_ipo_poin(pchan, icu->adrcode);
405                                 }
406                         }
407                         break;
408                         
409                 case ID_CO: /* constraint */
410                         if ((GS(id->name)==ID_OB) && (constname && constname[0])) {
411                                 Object *ob= (Object *)id;
412                                 bConstraint *con;
413                                 
414                                 /* assume that we only want the influence (as only used for Constraint Channels) */
415                                 if ((ob->ipoflag & OB_ACTION_OB) && !strcmp(actname, "Object")) {
416                                         for (con= ob->constraints.first; con; con= con->next) {
417                                                 if (strcmp(constname, con->name)==0) {
418                                                         *vartype= IPO_FLOAT;
419                                                         return &con->enforce;
420                                                 }
421                                         }
422                                 }
423                                 else if (ob->pose) {
424                                         bPoseChannel *pchan= get_pose_channel(ob->pose, actname);
425                                         
426                                         if (pchan) {
427                                                 for (con= pchan->constraints.first; con; con= con->next) {
428                                                         if (strcmp(constname, con->name)==0) {
429                                                                 *vartype= IPO_FLOAT;
430                                                                 return &con->enforce;
431                                                         }
432                                                 }
433                                         }
434                                 }
435                         }
436                         break;
437                         
438                 case ID_OB: /* object */
439                         /* hack: layer channels for object need to be keyed WITHOUT localview flag...
440                          * tsk... tsk... why must we just dump bitflags upon users :/
441                          */
442                         if ((GS(id->name)==ID_OB) && (icu->adrcode==OB_LAY)) {
443                                 Object *ob= (Object *)id;
444                                 static int layer = 0;
445                                 
446                                 /* init layer to be the object's layer var, then remove local view from it */
447                                 layer = ob->lay;
448                                 layer &= 0xFFFFFF;
449                                 *vartype= IPO_INT_BIT;
450                                 
451                                 /* return pointer to this static var 
452                                  *      - assumes that this pointer won't be stored for use later, so may not be threadsafe
453                                  *        if multiple keyframe calls are made, but that is unlikely to happen in the near future
454                                  */
455                                 return (void *)(&layer);
456                         }
457                         /* no break here for other ob channel-types - as they can be done normally */
458                 
459                 default: /* normal data-source */
460                         return get_ipo_poin(id, icu, vartype);
461         }
462
463         /* not valid... */
464         return NULL;
465 }
466
467
468 /* -------------- 'Smarter' Keyframing Functions -------------------- */
469 /* return codes for new_key_needed */
470 enum {
471         KEYNEEDED_DONTADD = 0,
472         KEYNEEDED_JUSTADD,
473         KEYNEEDED_DELPREV,
474         KEYNEEDED_DELNEXT
475 } eKeyNeededStatus;
476
477 /* This helper function determines whether a new keyframe is needed */
478 /* Cases where keyframes should not be added:
479  *      1. Keyframe to be added bewteen two keyframes with similar values
480  *      2. Keyframe to be added on frame where two keyframes are already situated
481  *      3. Keyframe lies at point that intersects the linear line between two keyframes
482  */
483 static short new_key_needed (IpoCurve *icu, float cFrame, float nValue) 
484 {
485         BezTriple *bezt=NULL, *prev=NULL;
486         int totCount, i;
487         float valA = 0.0f, valB = 0.0f;
488         
489         /* safety checking */
490         if (icu == NULL) return KEYNEEDED_JUSTADD;
491         totCount= icu->totvert;
492         if (totCount == 0) return KEYNEEDED_JUSTADD;
493         
494         /* loop through checking if any are the same */
495         bezt= icu->bezt;
496         for (i=0; i<totCount; i++) {
497                 float prevPosi=0.0f, prevVal=0.0f;
498                 float beztPosi=0.0f, beztVal=0.0f;
499                         
500                 /* get current time+value */    
501                 beztPosi= bezt->vec[1][0];
502                 beztVal= bezt->vec[1][1];
503                         
504                 if (prev) {
505                         /* there is a keyframe before the one currently being examined */               
506                         
507                         /* get previous time+value */
508                         prevPosi= prev->vec[1][0];
509                         prevVal= prev->vec[1][1];
510                         
511                         /* keyframe to be added at point where there are already two similar points? */
512                         if (IS_EQ(prevPosi, cFrame) && IS_EQ(beztPosi, cFrame) && IS_EQ(beztPosi, prevPosi)) {
513                                 return KEYNEEDED_DONTADD;
514                         }
515                         
516                         /* keyframe between prev+current points ? */
517                         if ((prevPosi <= cFrame) && (cFrame <= beztPosi)) {
518                                 /* is the value of keyframe to be added the same as keyframes on either side ? */
519                                 if (IS_EQ(prevVal, nValue) && IS_EQ(beztVal, nValue) && IS_EQ(prevVal, beztVal)) {
520                                         return KEYNEEDED_DONTADD;
521                                 }
522                                 else {
523                                         float realVal;
524                                         
525                                         /* get real value of curve at that point */
526                                         realVal= eval_icu(icu, cFrame);
527                                         
528                                         /* compare whether it's the same as proposed */
529                                         if (IS_EQ(realVal, nValue)) 
530                                                 return KEYNEEDED_DONTADD;
531                                         else 
532                                                 return KEYNEEDED_JUSTADD;
533                                 }
534                         }
535                         
536                         /* new keyframe before prev beztriple? */
537                         if (cFrame < prevPosi) {
538                                 /* A new keyframe will be added. However, whether the previous beztriple
539                                  * stays around or not depends on whether the values of previous/current
540                                  * beztriples and new keyframe are the same.
541                                  */
542                                 if (IS_EQ(prevVal, nValue) && IS_EQ(beztVal, nValue) && IS_EQ(prevVal, beztVal))
543                                         return KEYNEEDED_DELNEXT;
544                                 else 
545                                         return KEYNEEDED_JUSTADD;
546                         }
547                 }
548                 else {
549                         /* just add a keyframe if there's only one keyframe 
550                          * and the new one occurs before the exisiting one does.
551                          */
552                         if ((cFrame < beztPosi) && (totCount==1))
553                                 return KEYNEEDED_JUSTADD;
554                 }
555                 
556                 /* continue. frame to do not yet passed (or other conditions not met) */
557                 if (i < (totCount-1)) {
558                         prev= bezt;
559                         bezt++;
560                 }
561                 else
562                         break;
563         }
564         
565         /* Frame in which to add a new-keyframe occurs after all other keys
566          * -> If there are at least two existing keyframes, then if the values of the
567          *       last two keyframes and the new-keyframe match, the last existing keyframe
568          *       gets deleted as it is no longer required.
569          * -> Otherwise, a keyframe is just added. 1.0 is added so that fake-2nd-to-last
570          *       keyframe is not equal to last keyframe.
571          */
572         bezt= (icu->bezt + (icu->totvert - 1));
573         valA= bezt->vec[1][1];
574         
575         if (prev)
576                 valB= prev->vec[1][1];
577         else 
578                 valB= bezt->vec[1][1] + 1.0f; 
579                 
580         if (IS_EQ(valA, nValue) && IS_EQ(valA, valB)) 
581                 return KEYNEEDED_DELPREV;
582         else 
583                 return KEYNEEDED_JUSTADD;
584 }
585
586 /* ------------------ 'Visual' Keyframing Functions ------------------ */
587
588 /* internal status codes for visualkey_can_use */
589 enum {
590         VISUALKEY_NONE = 0,
591         VISUALKEY_LOC,
592         VISUALKEY_ROT
593 };
594
595 /* This helper function determines if visual-keyframing should be used when  
596  * inserting keyframes for the given channel. As visual-keyframing only works
597  * on Object and Pose-Channel blocks, this should only get called for those 
598  * blocktypes, when using "standard" keying but 'Visual Keying' option in Auto-Keying 
599  * settings is on.
600  */
601 static short visualkey_can_use (ID *id, int blocktype, char *actname, char *constname, int adrcode)
602 {
603         Object *ob= NULL;
604         bConstraint *con= NULL;
605         short searchtype= VISUALKEY_NONE;
606         
607         /* validate data */
608         if ((id == NULL) || (GS(id->name)!=ID_OB) || !(ELEM(blocktype, ID_OB, ID_PO))) 
609                 return 0;
610         
611         /* get first constraint and determine type of keyframe constraints to check for*/
612         ob= (Object *)id;
613         
614         if (blocktype == ID_OB) {
615                 con= ob->constraints.first;
616                 
617                 if (ELEM3(adrcode, OB_LOC_X, OB_LOC_Y, OB_LOC_Z))
618                         searchtype= VISUALKEY_LOC;
619                 else if (ELEM3(adrcode, OB_ROT_X, OB_ROT_Y, OB_ROT_Z))
620                         searchtype= VISUALKEY_ROT;
621         }
622         else if (blocktype == ID_PO) {
623                 bPoseChannel *pchan= get_pose_channel(ob->pose, actname);
624                 con= pchan->constraints.first;
625                 
626                 if (ELEM3(adrcode, AC_LOC_X, AC_LOC_Y, AC_LOC_Z))
627                         searchtype= VISUALKEY_LOC;
628                 else if (ELEM4(adrcode, AC_QUAT_W, AC_QUAT_X, AC_QUAT_Y, AC_QUAT_Z))
629                         searchtype= VISUALKEY_ROT;
630         }
631         
632         /* only search if a searchtype and initial constraint are available */
633         if (searchtype && con) {
634                 for (; con; con= con->next) {
635                         /* only consider constraint if it is not disabled, and has influence */
636                         if (con->flag & CONSTRAINT_DISABLE) continue;
637                         if (con->enforce == 0.0f) continue;
638                         
639                         /* some constraints may alter these transforms */
640                         switch (con->type) {
641                                 /* multi-transform constraints */
642                                 case CONSTRAINT_TYPE_CHILDOF:
643                                         return 1;
644                                 case CONSTRAINT_TYPE_TRANSFORM:
645                                         return 1;
646                                 case CONSTRAINT_TYPE_FOLLOWPATH:
647                                         return 1;
648                                 case CONSTRAINT_TYPE_KINEMATIC:
649                                         return 1;
650                                         
651                                 /* single-transform constraits  */
652                                 case CONSTRAINT_TYPE_TRACKTO:
653                                         if (searchtype==VISUALKEY_ROT) return 1;
654                                         break;
655                                 case CONSTRAINT_TYPE_ROTLIMIT:
656                                         if (searchtype==VISUALKEY_ROT) return 1;
657                                         break;
658                                 case CONSTRAINT_TYPE_LOCLIMIT:
659                                         if (searchtype==VISUALKEY_LOC) return 1;
660                                         break;
661                                 case CONSTRAINT_TYPE_ROTLIKE:
662                                         if (searchtype==VISUALKEY_ROT) return 1;
663                                         break;
664                                 case CONSTRAINT_TYPE_DISTLIMIT:
665                                         if (searchtype==VISUALKEY_LOC) return 1;
666                                         break;
667                                 case CONSTRAINT_TYPE_LOCLIKE:
668                                         if (searchtype==VISUALKEY_LOC) return 1;
669                                         break;
670                                 case CONSTRAINT_TYPE_LOCKTRACK:
671                                         if (searchtype==VISUALKEY_ROT) return 1;
672                                         break;
673                                 case CONSTRAINT_TYPE_MINMAX:
674                                         if (searchtype==VISUALKEY_LOC) return 1;
675                                         break;
676                                 
677                                 default:
678                                         break;
679                         }
680                 }
681         }
682         
683         /* when some condition is met, this function returns, so here it can be 0 */
684         return 0;
685 }
686
687 /* This helper function extracts the value to use for visual-keyframing 
688  * In the event that it is not possible to perform visual keying, try to fall-back
689  * to using the poin method. Assumes that all data it has been passed is valid.
690  */
691 static float visualkey_get_value (ID *id, int blocktype, char *actname, char *constname, int adrcode, IpoCurve *icu)
692 {
693         Object *ob;
694         void *poin = NULL;
695         int index, vartype;
696         
697         /* validate situtation */
698         if ((id==NULL) || (GS(id->name)!=ID_OB) || (ELEM(blocktype, ID_OB, ID_PO)==0))
699                 return 0.0f;
700                 
701         /* get object */
702         ob= (Object *)id;
703         
704         /* only valid for objects or posechannels */
705         if (blocktype == ID_OB) {
706                 /* parented objects are not supported, as the effects of the parent
707                  * are included in the matrix, which kindof beats the point
708                  */
709                 if (ob->parent == NULL) {
710                         /* only Location or Rotation keyframes are supported now */
711                         if (ELEM3(adrcode, OB_LOC_X, OB_LOC_Y, OB_LOC_Z)) {
712                                 /* assumes that OB_LOC_Z > OB_LOC_Y > OB_LOC_X */
713                                 index= adrcode - OB_LOC_X;
714                                 
715                                 return ob->obmat[3][index];
716                         }
717                         else if (ELEM3(adrcode, OB_ROT_X, OB_ROT_Y, OB_ROT_Z)) {
718                                 float eul[3];
719                                 
720                                 /* assumes that OB_ROT_Z > OB_ROT_Y > OB_ROT_X */
721                                 index= adrcode - OB_ROT_X;
722                                 
723                                 Mat4ToEul(ob->obmat, eul);
724                                 return eul[index]*(5.72958f);
725                         }
726                 }
727         }
728         else if (blocktype == ID_PO) {
729                 bPoseChannel *pchan;
730                 float tmat[4][4];
731                 
732                 /* get data to use */
733                 pchan= get_pose_channel(ob->pose, actname);
734                 
735                 /* Although it is not strictly required for this particular space conversion, 
736                  * arg1 must not be null, as there is a null check for the other conversions to
737                  * be safe. Therefore, the active object is passed here, and in many cases, this
738                  * will be what owns the pose-channel that is getting this anyway.
739                  */
740                 Mat4CpyMat4(tmat, pchan->pose_mat);
741                 constraint_mat_convertspace(ob, pchan, tmat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL);
742                 
743                 /* Loc, Rot/Quat keyframes are supported... */
744                 if (ELEM3(adrcode, AC_LOC_X, AC_LOC_Y, AC_LOC_Z)) {
745                         /* assumes that AC_LOC_Z > AC_LOC_Y > AC_LOC_X */
746                         index= adrcode - AC_LOC_X;
747                         
748                         /* only use for non-connected bones */
749                         if ((pchan->bone->parent) && !(pchan->bone->flag & BONE_CONNECTED))
750                                 return tmat[3][index];
751                         else if (pchan->bone->parent == NULL)
752                                 return tmat[3][index];
753                 }
754                 else if (ELEM4(adrcode, AC_QUAT_W, AC_QUAT_X, AC_QUAT_Y, AC_QUAT_Z)) {
755                         float trimat[3][3], quat[4];
756                         
757                         /* assumes that AC_QUAT_Z > AC_QUAT_Y > AC_QUAT_X > AC_QUAT_W */
758                         index= adrcode - AC_QUAT_W;
759                         
760                         Mat3CpyMat4(trimat, tmat);
761                         Mat3ToQuat_is_ok(trimat, quat);
762                         
763                         return quat[index];
764                 }
765         }
766         
767         /* as the function hasn't returned yet, try reading from poin */
768         poin= get_context_ipo_poin(id, blocktype, actname, constname, icu, &vartype);
769         if (poin)
770                 return read_ipo_poin(poin, vartype);
771         else
772                 return 0.0;
773 }
774
775 /* ------------------------- Insert Key API ------------------------- */
776
777 /* Main Keyframing API call:
778  *      Use this when validation of necessary animation data isn't necessary as it
779  *      already exists. It will insert a keyframe using the current value being keyframed.
780  *      
781  *      The flag argument is used for special settings that alter the behaviour of
782  *      the keyframe insertion. These include the 'visual' keyframing modes, quick refresh,
783  *      and extra keyframe filtering.
784  */
785 short insertkey (ID *id, int blocktype, char *actname, char *constname, int adrcode, short flag)
786 {       
787         IpoCurve *icu;
788         
789         /* get ipo-curve */
790         //icu= verify_ipocurve(id, blocktype, actname, constname, NULL, adrcode, 1); // XXX this call needs to be in blenkernel
791         
792         /* only continue if we have an ipo-curve to add keyframe to */
793         if (icu) {
794                 float cfra = frame_to_float(CFRA);
795                 float curval= 0.0f;
796                 
797                 /* apply special time tweaking */
798                 if (GS(id->name) == ID_OB) {
799                         Object *ob= (Object *)id;
800                         
801                         /* apply NLA-scaling (if applicable) */
802                         if (actname && actname[0]) 
803                                 cfra= get_action_frame(ob, cfra);
804                         
805                         /* ancient time-offset cruft */
806                         if ( (ob->ipoflag & OB_OFFS_OB) && (give_timeoffset(ob)) ) {
807                                 /* actually frametofloat calc again! */
808                                 cfra-= give_timeoffset(ob)*G.scene->r.framelen;
809                         }
810                 }
811                 
812                 /* obtain value to give keyframe */
813                 if ( (flag & INSERTKEY_MATRIX) && 
814                          (visualkey_can_use(id, blocktype, actname, constname, adrcode)) ) 
815                 {
816                         /* visual-keying is only available for object and pchan datablocks, as 
817                          * it works by keyframing using a value extracted from the final matrix 
818                          * instead of using the kt system to extract a value.
819                          */
820                         curval= visualkey_get_value(id, blocktype, actname, constname, adrcode, icu);
821                 }
822                 else {
823                         void *poin;
824                         int vartype;
825                         
826                         /* get pointer to data to read from */
827                         poin = get_context_ipo_poin(id, blocktype, actname, constname, icu, &vartype);
828                         if (poin == NULL) {
829                                 printf("Insert Key: No pointer to variable obtained \n");
830                                 return 0;
831                         }
832                         
833                         /* use kt's read_poin function to extract value (kt->read_poin should 
834                          * exist in all cases, but it never hurts to check)
835                          */
836                         curval= read_ipo_poin(poin, vartype);
837                 }
838                 
839                 /* only insert keyframes where they are needed */
840                 if (flag & INSERTKEY_NEEDED) {
841                         short insert_mode;
842                         
843                         /* check whether this curve really needs a new keyframe */
844                         insert_mode= new_key_needed(icu, cfra, curval);
845                         
846                         /* insert new keyframe at current frame */
847                         if (insert_mode)
848                                 insert_vert_icu(icu, cfra, curval, (flag & INSERTKEY_FAST));
849                         
850                         /* delete keyframe immediately before/after newly added */
851                         switch (insert_mode) {
852                                 case KEYNEEDED_DELPREV:
853                                         delete_icu_key(icu, icu->totvert-2, 1);
854                                         break;
855                                 case KEYNEEDED_DELNEXT:
856                                         delete_icu_key(icu, 1, 1);
857                                         break;
858                         }
859                         
860                         /* only return success if keyframe added */
861                         if (insert_mode)
862                                 return 1;
863                 }
864                 else {
865                         /* just insert keyframe */
866                         insert_vert_icu(icu, cfra, curval, (flag & INSERTKEY_FAST));
867                         
868                         /* return success */
869                         return 1;
870                 }
871         }
872         
873         /* return failure */
874         return 0;
875 }
876
877
878 /* ************************************************** */
879 /* KEYFRAME DELETION */
880
881 /* Main Keyframing API call:
882  *      Use this when validation of necessary animation data isn't necessary as it
883  *      already exists. It will delete a keyframe at the current frame.
884  *      
885  *      The flag argument is used for special settings that alter the behaviour of
886  *      the keyframe deletion. These include the quick refresh options.
887  */
888 short deletekey (ID *id, int blocktype, char *actname, char *constname, int adrcode, short flag)
889 {
890         Ipo *ipo;
891         IpoCurve *icu;
892         
893         /* get ipo-curve 
894          * Note: here is one of the places where we don't want new ipo + ipo-curve added!
895          *              so 'add' var must be 0
896          */
897                 // XXX funcs here need to be recoded in blenkernel...
898         //ipo= verify_ipo(id, blocktype, actname, constname, NULL, 0);
899         //icu= verify_ipocurve(id, blocktype, actname, constname, NULL, adrcode, 0);
900         
901         /* only continue if we have an ipo-curve to remove keyframes from */
902         if (icu) {
903                 float cfra = frame_to_float(CFRA);
904                 short found = -1;
905                 int i;
906                 
907                 /* apply special time tweaking */
908                 if (GS(id->name) == ID_OB) {
909                         Object *ob= (Object *)id;
910                         
911                         /* apply NLA-scaling (if applicable) */
912                         if (actname && actname[0]) 
913                                 cfra= get_action_frame(ob, cfra);
914                         
915                         /* ancient time-offset cruft */
916                         if ( (ob->ipoflag & OB_OFFS_OB) && (give_timeoffset(ob)) ) {
917                                 /* actually frametofloat calc again! */
918                                 cfra-= give_timeoffset(ob)*G.scene->r.framelen;
919                         }
920                 }
921                 
922                 /* try to find index of beztriple to get rid of */
923                 i = binarysearch_bezt_index(icu->bezt, cfra, icu->totvert, &found);
924                 if (found) {                    
925                         /* delete the key at the index (will sanity check + do recalc afterwards ) */
926                         delete_icu_key(icu, i, 1);
927                         
928                         /* Only delete curve too if there isn't an ipo-driver still hanging around on an empty curve */
929                         if (icu->totvert==0 && icu->driver==NULL) {
930                                 BLI_remlink(&ipo->curve, icu);
931                                 free_ipo_curve(icu);
932                         }
933                         
934                         /* return success */
935                         return 1;
936                 }
937         }
938         
939         /* return failure */
940         return 0;
941 }
942
943 /* ************************************************** */
944 /* COMMON KEYFRAME MANAGEMENT (common_insertkey/deletekey) */
945
946 /* mode for common_modifykey */
947 enum {
948         COMMONKEY_MODE_INSERT = 0,
949         COMMONKEY_MODE_DELETE,
950 } eCommonModifyKey_Modes;
951
952 /* --------- KeyingSet Adrcode Getters ------------ */
953
954 /* initialise a channel-getter storage */
955 static void ks_adrcodegetter_init (bKS_AdrcodeGetter *kag, bKeyingSet *ks, bCommonKeySrc *cks)
956 {
957         /* error checking */
958         if (kag == NULL)
959                 return;
960         
961         if (ELEM(NULL, ks, cks)) {
962                 /* set invalid settings that won't cause harm */
963                 kag->ks= NULL;
964                 kag->cks= NULL;
965                 kag->index= -2;
966                 kag->tot= 0;
967         }
968         else {
969                 /* store settings */
970                 kag->ks= ks;
971                 kag->cks= cks;
972                 
973                 /* - index is -1, as that allows iterators to return first element
974                  * - tot is chan_num by default, but may get overriden if -1 is encountered (for extension-type getters)
975                  */
976                 kag->index= -1;
977                 kag->tot= ks->chan_num;
978         }
979 }
980
981 /* 'default' channel-getter that will be used when iterating through keyingset's channels 
982  *       - iteration will stop when adrcode <= 0 is encountered, so we use that as escape
983  */
984 static short ks_getnextadrcode_default (bKS_AdrcodeGetter *kag)
985 {       
986         bKeyingSet *ks= (kag)? kag->ks : NULL;
987         
988         /* error checking */
989         if (ELEM(NULL, kag, ks)) return 0;
990         if (kag->tot <= 0) return 0;
991         
992         kag->index++;
993         if ((kag->index < 0) || (kag->index >= kag->tot)) return 0;
994         
995         /* return the adrcode stored at index then */
996         return ks->adrcodes[kag->index];
997 }
998
999 /* add map flag (for MTex channels, as certain ones need special offset) */
1000 static short ks_getnextadrcode_addmap (bKS_AdrcodeGetter *kag)
1001 {
1002         short adrcode= ks_getnextadrcode_default(kag);
1003         
1004         /* if there was an adrcode returned, assume that kag stuff is set ok */
1005         if (adrcode) {
1006                 bCommonKeySrc *cks= kag->cks;
1007                 bKeyingSet *ks= kag->ks;
1008                 
1009                 if (ELEM3(ks->blocktype, ID_MA, ID_LA, ID_WO)) {
1010                         switch (adrcode) {
1011                                 case MAP_OFS_X: case MAP_OFS_Y: case MAP_OFS_Z:
1012                                 case MAP_SIZE_X: case MAP_SIZE_Y: case MAP_SIZE_Z:
1013                                 case MAP_R: case MAP_G: case MAP_B: case MAP_DVAR:
1014                                 case MAP_COLF: case MAP_NORF: case MAP_VARF: case MAP_DISP:
1015                                         adrcode += cks->map;
1016                                         break;
1017                         }
1018                 }
1019         }
1020         
1021         /* adrcode must be returned! */
1022         return adrcode;
1023 }
1024
1025 /* extend posechannel keyingsets with rotation info (when KAG_CHAN_EXTEND is encountered) 
1026  *      - iteration will stop when adrcode <= 0 is encountered, so we use that as escape
1027  *      - when we encounter KAG_CHAN_EXTEND as adrcode, start returning our own
1028  */
1029 static short ks_getnextadrcode_pchanrot (bKS_AdrcodeGetter *kag)
1030 {       
1031         /* hardcoded adrcode channels used here only 
1032          *      - length is keyed-channels + 1 (last item must be 0 to escape)
1033          */
1034         static short quat_adrcodes[5] = {AC_QUAT_W, AC_QUAT_X, AC_QUAT_Y, AC_QUAT_Z, 0};
1035         static short eul_adrcodes[4] = {AC_EUL_X, AC_EUL_Y, AC_EUL_Z, 0};
1036                 
1037         /* useful variables */
1038         bKeyingSet *ks= (kag)? kag->ks : NULL;
1039         bCommonKeySrc *cks= (kag) ? kag->cks : NULL;
1040         short index, adrcode;
1041         
1042         /* error checking */
1043         if (ELEM3(NULL, kag, ks, cks)) return 0;
1044         if (ks->chan_num <= 0) return 0;
1045         
1046         /* get index 
1047          *      - if past the last item (kag->tot), return stuff from our static arrays
1048          *      - otherwise, just keep returning stuff from the keyingset (but check out for -1!) 
1049          */
1050         kag->index++;
1051         if (kag->index < 0)
1052                 return 0;
1053         
1054         /* normal (static stuff) */
1055         if (kag->index < kag->tot) {
1056                 /* get adrcode, and return if not KAG_CHAN_EXTEND (i.e. point for start of iteration) */
1057                 adrcode= ks->adrcodes[kag->index];
1058                 
1059                 if (adrcode != KAG_CHAN_EXTEND) 
1060                         return adrcode;
1061                 else    
1062                         kag->tot= kag->index;
1063         }
1064                 
1065         /* based on current rotation-mode
1066          *      - index can be at most 5, if we are to prevent segfaults
1067          */
1068         index= kag->index - kag->tot;
1069         if ((index < 0) || (index > 5))
1070                 return 0;
1071         
1072         if (cks->pchan && cks->pchan->rotmode)
1073                 return eul_adrcodes[index];
1074         else
1075                 return quat_adrcodes[index];
1076 }
1077
1078 /* ------------- KeyingSet Defines ------------ */
1079 /* Note: these must all be named with the defks_* prefix, otherwise the template macro will not work! */
1080
1081 /* macro for defining keyingset contexts */
1082 #define KSC_TEMPLATE(ctx_name) {&defks_##ctx_name[0], NULL, sizeof(defks_##ctx_name)/sizeof(bKeyingSet)}
1083
1084 /* --- */
1085
1086 /* check if option not available for deleting keys */
1087 static short incl_non_del_keys (bKeyingSet *ks, const char mode[])
1088 {
1089         /* as optimisation, assume that it is sufficient to check only first letter
1090          * of mode (int comparison should be faster than string!)
1091          */
1092         //if (strcmp(mode, "Delete")==0)
1093         if (mode && mode[0]=='D')
1094                 return 0;
1095         
1096         return 1;
1097 }
1098
1099 /* Object KeyingSets  ------ */
1100
1101 /* check if include shapekey entry  */
1102 static short incl_v3d_ob_shapekey (bKeyingSet *ks, const char mode[])
1103 {
1104         Object *ob= (G.obedit)? (G.obedit) : (OBACT);
1105         char *newname= NULL;
1106         
1107         if(ob==NULL)
1108                 return 0;
1109         
1110         /* not available for delete mode */
1111         if (strcmp(mode, "Delete")==0)
1112                 return 0;
1113         
1114         /* check if is geom object that can get shapekeys */
1115         switch (ob->type) {
1116                 /* geometry? */
1117                 case OB_MESH:           newname= "Mesh";                break;
1118                 case OB_CURVE:          newname= "Curve";               break;
1119                 case OB_SURF:           newname= "Surface";             break;
1120                 case OB_LATTICE:        newname= "Lattice";             break;
1121                 
1122                 /* not geometry! */
1123                 default:
1124                         return 0;
1125         }
1126         
1127         /* if ks is shapekey entry (this could be callled for separator before too!) */
1128         if (ks->flag == -3)
1129                 sprintf(ks->name, newname);
1130         
1131         /* if it gets here, it's ok */
1132         return 1;
1133 }
1134
1135 /* array for object keyingset defines */
1136 bKeyingSet defks_v3d_object[] = 
1137 {
1138         /* include_cb, adrcode-getter, name, blocktype, flag, chan_num, adrcodes */
1139         {NULL, "Loc", ID_OB, 0, 3, {OB_LOC_X,OB_LOC_Y,OB_LOC_Z}},
1140         {NULL, "Rot", ID_OB, 0, 3, {OB_ROT_X,OB_ROT_Y,OB_ROT_Z}},
1141         {NULL, "Scale", ID_OB, 0, 3, {OB_SIZE_X,OB_SIZE_Y,OB_SIZE_Z}},
1142         
1143         {NULL, "%l", 0, -1, 0, {0}}, // separator
1144         
1145         {NULL, "LocRot", ID_OB, 0, 6, 
1146                 {OB_LOC_X,OB_LOC_Y,OB_LOC_Z,
1147                  OB_ROT_X,OB_ROT_Y,OB_ROT_Z}},
1148                  
1149         {NULL, "LocScale", ID_OB, 0, 6, 
1150                 {OB_LOC_X,OB_LOC_Y,OB_LOC_Z,
1151                  OB_SIZE_X,OB_SIZE_Y,OB_SIZE_Z}},
1152                  
1153         {NULL, "LocRotScale", ID_OB, 0, 9, 
1154                 {OB_LOC_X,OB_LOC_Y,OB_LOC_Z,
1155                  OB_ROT_X,OB_ROT_Y,OB_ROT_Z,
1156                  OB_SIZE_X,OB_SIZE_Y,OB_SIZE_Z}},
1157                  
1158         {NULL, "RotScale", ID_OB, 0, 6, 
1159                 {OB_ROT_X,OB_ROT_Y,OB_ROT_Z,
1160                  OB_SIZE_X,OB_SIZE_Y,OB_SIZE_Z}},
1161         
1162         {incl_non_del_keys, "%l", 0, -1, 0, {0}}, // separator
1163         
1164         {incl_non_del_keys, "VisualLoc", ID_OB, INSERTKEY_MATRIX, 3, {OB_LOC_X,OB_LOC_Y,OB_LOC_Z}},
1165         {incl_non_del_keys, "VisualRot", ID_OB, INSERTKEY_MATRIX, 3, {OB_ROT_X,OB_ROT_Y,OB_ROT_Z}},
1166         
1167         {incl_non_del_keys, "VisualLocRot", ID_OB, INSERTKEY_MATRIX, 6, 
1168                 {OB_LOC_X,OB_LOC_Y,OB_LOC_Z,
1169                  OB_ROT_X,OB_ROT_Y,OB_ROT_Z}},
1170         
1171         {NULL, "%l", 0, -1, 0, {0}}, // separator
1172         
1173         {NULL, "Layer", ID_OB, 0, 1, {OB_LAY}}, // icky option...
1174         {NULL, "Available", ID_OB, -2, 0, {0}},
1175         
1176         {incl_v3d_ob_shapekey, "%l%l", 0, -1, 0, {0}}, // separator (linked to shapekey entry)
1177         {incl_v3d_ob_shapekey, "<ShapeKey>", ID_OB, -3, 0, {0}}
1178 };
1179
1180 /* PoseChannel KeyingSets  ------ */
1181
1182 /* array for posechannel keyingset defines */
1183 bKeyingSet defks_v3d_pchan[] = 
1184 {
1185         /* include_cb, name, blocktype, flag, chan_num, adrcodes */
1186         {NULL, "Loc", ID_PO, 0, 3, {AC_LOC_X,AC_LOC_Y,AC_LOC_Z}},
1187         {NULL, "Rot", ID_PO, COMMONKEY_PCHANROT, 1, {KAG_CHAN_EXTEND}},
1188         {NULL, "Scale", ID_PO, 0, 3, {AC_SIZE_X,AC_SIZE_Y,AC_SIZE_Z}},
1189         
1190         {NULL, "%l", 0, -1, 0, {0}}, // separator
1191         
1192         {NULL, "LocRot", ID_PO, COMMONKEY_PCHANROT, 4, 
1193                 {AC_LOC_X,AC_LOC_Y,AC_LOC_Z,
1194                  KAG_CHAN_EXTEND}},
1195                  
1196         {NULL, "LocScale", ID_PO, 0, 6, 
1197                 {AC_LOC_X,AC_LOC_Y,AC_LOC_Z,
1198                  AC_SIZE_X,AC_SIZE_Y,AC_SIZE_Z}},
1199                  
1200         {NULL, "LocRotScale", ID_PO, COMMONKEY_PCHANROT, 7, 
1201                 {AC_LOC_X,AC_LOC_Y,AC_LOC_Z,AC_SIZE_X,AC_SIZE_Y,AC_SIZE_Z, 
1202                  KAG_CHAN_EXTEND}},
1203                  
1204         {NULL, "RotScale", ID_PO, 0, 4, 
1205                 {AC_SIZE_X,AC_SIZE_Y,AC_SIZE_Z, 
1206                  KAG_CHAN_EXTEND}},
1207         
1208         {incl_non_del_keys, "%l", 0, -1, 0, {0}}, // separator
1209         
1210         {incl_non_del_keys, "VisualLoc", ID_PO, INSERTKEY_MATRIX, 3, {AC_LOC_X,AC_LOC_Y,AC_LOC_Z}},
1211         {incl_non_del_keys, "VisualRot", ID_PO, INSERTKEY_MATRIX|COMMONKEY_PCHANROT, 1, {KAG_CHAN_EXTEND}},
1212         
1213         {incl_non_del_keys, "VisualLocRot", ID_PO, INSERTKEY_MATRIX|COMMONKEY_PCHANROT, 4, 
1214                 {AC_LOC_X,AC_LOC_Y,AC_LOC_Z, KAG_CHAN_EXTEND}},
1215         
1216         {NULL, "%l", 0, -1, 0, {0}}, // separator
1217         
1218         {NULL, "Available", ID_PO, -2, 0, {0}}
1219 };
1220
1221 /* Material KeyingSets  ------ */
1222
1223 /* array for material keyingset defines */
1224 bKeyingSet defks_buts_shading_mat[] = 
1225 {
1226         /* include_cb, name, blocktype, flag, chan_num, adrcodes */
1227         {NULL, "RGB", ID_MA, 0, 3, {MA_COL_R,MA_COL_G,MA_COL_B}},
1228         {NULL, "Alpha", ID_MA, 0, 1, {MA_ALPHA}},
1229         {NULL, "Halo Size", ID_MA, 0, 1, {MA_HASIZE}},
1230         {NULL, "Mode", ID_MA, 0, 1, {MA_MODE}}, // evil bitflags
1231         
1232         {NULL, "%l", 0, -1, 0, {0}}, // separator
1233         
1234         {NULL, "All Color", ID_MA, 0, 18, 
1235                 {MA_COL_R,MA_COL_G,MA_COL_B,
1236                  MA_ALPHA,MA_HASIZE, MA_MODE,
1237                  MA_SPEC_R,MA_SPEC_G,MA_SPEC_B,
1238                  MA_REF,MA_EMIT,MA_AMB,MA_SPEC,MA_HARD,
1239                  MA_MODE,MA_TRANSLU,MA_ADD}},
1240                  
1241         {NULL, "All Mirror", ID_MA, 0, 5, 
1242                 {MA_RAYM,MA_FRESMIR,MA_FRESMIRI,
1243                  MA_FRESTRA,MA_FRESTRAI}},
1244         
1245         {NULL, "%l", 0, -1, 0, {0}}, // separator
1246         
1247         {NULL, "Ofs", ID_MA, COMMONKEY_ADDMAP, 3, {MAP_OFS_X,MAP_OFS_Y,MAP_OFS_Z}},
1248         {NULL, "Size", ID_MA, COMMONKEY_ADDMAP, 3, {MAP_SIZE_X,MAP_SIZE_Y,MAP_SIZE_Z}},
1249         
1250         {NULL, "All Mapping", ID_MA, COMMONKEY_ADDMAP, 14, 
1251                 {MAP_OFS_X,MAP_OFS_Y,MAP_OFS_Z,
1252                  MAP_SIZE_X,MAP_SIZE_Y,MAP_SIZE_Z,
1253                  MAP_R,MAP_G,MAP_B,MAP_DVAR,
1254                  MAP_COLF,MAP_NORF,MAP_VARF,MAP_DISP}},
1255         
1256         {NULL, "%l", 0, -1, 0, {0}}, // separator
1257         
1258         {NULL, "Available", ID_MA, -2, 0, {0}}
1259 };
1260
1261 /* World KeyingSets  ------ */
1262
1263 /* array for world keyingset defines */
1264 bKeyingSet defks_buts_shading_wo[] = 
1265 {
1266         /* include_cb, name, blocktype, flag, chan_num, adrcodes */
1267         {NULL, "Zenith RGB", ID_WO, 0, 3, {WO_ZEN_R,WO_ZEN_G,WO_ZEN_B}},
1268         {NULL, "Horizon RGB", ID_WO, 0, 3, {WO_HOR_R,WO_HOR_G,WO_HOR_B}},
1269         
1270         {NULL, "%l", 0, -1, 0, {0}}, // separator
1271         
1272         {NULL, "Mist", ID_WO, 0, 4, {WO_MISI,WO_MISTDI,WO_MISTSTA,WO_MISTHI}},
1273         {NULL, "Stars", ID_WO, 0, 5, {WO_STAR_R,WO_STAR_G,WO_STAR_B,WO_STARDIST,WO_STARSIZE}},
1274         
1275         
1276         {NULL, "%l", 0, -1, 0, {0}}, // separator
1277         
1278         {NULL, "Ofs", ID_WO, COMMONKEY_ADDMAP, 3, {MAP_OFS_X,MAP_OFS_Y,MAP_OFS_Z}},
1279         {NULL, "Size", ID_WO, COMMONKEY_ADDMAP, 3, {MAP_SIZE_X,MAP_SIZE_Y,MAP_SIZE_Z}},
1280         
1281         {NULL, "All Mapping", ID_WO, COMMONKEY_ADDMAP, 14, 
1282                 {MAP_OFS_X,MAP_OFS_Y,MAP_OFS_Z,
1283                  MAP_SIZE_X,MAP_SIZE_Y,MAP_SIZE_Z,
1284                  MAP_R,MAP_G,MAP_B,MAP_DVAR,
1285                  MAP_COLF,MAP_NORF,MAP_VARF,MAP_DISP}},
1286         
1287         {NULL, "%l", 0, -1, 0, {0}}, // separator
1288         
1289         {NULL, "Available", ID_WO, -2, 0, {0}}
1290 };
1291
1292 /* Lamp KeyingSets  ------ */
1293
1294 /* array for lamp keyingset defines */
1295 bKeyingSet defks_buts_shading_la[] = 
1296 {
1297         /* include_cb, name, blocktype, flag, chan_num, adrcodes */
1298         {NULL, "RGB", ID_LA, 0, 3, {LA_COL_R,LA_COL_G,LA_COL_B}},
1299         {NULL, "Energy", ID_LA, 0, 1, {LA_ENERGY}},
1300         {NULL, "Spot Size", ID_LA, 0, 1, {LA_SPOTSI}},
1301         
1302         {NULL, "%l", 0, -1, 0, {0}}, // separator
1303         
1304         {NULL, "Ofs", ID_LA, COMMONKEY_ADDMAP, 3, {MAP_OFS_X,MAP_OFS_Y,MAP_OFS_Z}},
1305         {NULL, "Size", ID_LA, COMMONKEY_ADDMAP, 3, {MAP_SIZE_X,MAP_SIZE_Y,MAP_SIZE_Z}},
1306         
1307         {NULL, "All Mapping", ID_LA, COMMONKEY_ADDMAP, 14, 
1308                 {MAP_OFS_X,MAP_OFS_Y,MAP_OFS_Z,
1309                  MAP_SIZE_X,MAP_SIZE_Y,MAP_SIZE_Z,
1310                  MAP_R,MAP_G,MAP_B,MAP_DVAR,
1311                  MAP_COLF,MAP_NORF,MAP_VARF,MAP_DISP}},
1312         
1313         {NULL, "%l", 0, -1, 0, {0}}, // separator
1314         
1315         {NULL, "Available", ID_LA, -2, 0, {0}}
1316 };
1317
1318 /* Texture KeyingSets  ------ */
1319
1320 /* array for texture keyingset defines */
1321 bKeyingSet defks_buts_shading_tex[] = 
1322 {
1323         /* include_cb, name, blocktype, flag, chan_num, adrcodes */
1324         {NULL, "Clouds", ID_TE, 0, 5, 
1325                 {TE_NSIZE,TE_NDEPTH,TE_NTYPE,
1326                  TE_MG_TYP,TE_N_BAS1}},
1327         
1328         {NULL, "Marble", ID_TE, 0, 7, 
1329                 {TE_NSIZE,TE_NDEPTH,TE_NTYPE,
1330                  TE_TURB,TE_MG_TYP,TE_N_BAS1,TE_N_BAS2}},
1331                  
1332         {NULL, "Stucci", ID_TE, 0, 5, 
1333                 {TE_NSIZE,TE_NTYPE,TE_TURB,
1334                  TE_MG_TYP,TE_N_BAS1}},
1335                  
1336         {NULL, "Wood", ID_TE, 0, 6, 
1337                 {TE_NSIZE,TE_NTYPE,TE_TURB,
1338                  TE_MG_TYP,TE_N_BAS1,TE_N_BAS2}},
1339                  
1340         {NULL, "Magic", ID_TE, 0, 2, {TE_NDEPTH,TE_TURB}},
1341         
1342         {NULL, "Blend", ID_TE, 0, 1, {TE_MG_TYP}},      
1343                 
1344         {NULL, "Musgrave", ID_TE, 0, 6, 
1345                 {TE_MG_TYP,TE_MGH,TE_MG_LAC,
1346                  TE_MG_OCT,TE_MG_OFF,TE_MG_GAIN}},
1347                  
1348         {NULL, "Voronoi", ID_TE, 0, 9, 
1349                 {TE_VNW1,TE_VNW2,TE_VNW3,TE_VNW4,
1350                 TE_VNMEXP,TE_VN_DISTM,TE_VN_COLT,
1351                 TE_ISCA,TE_NSIZE}},
1352                 
1353         {NULL, "Distorted Noise", ID_TE, 0, 4, 
1354                 {TE_MG_OCT,TE_MG_OFF,TE_MG_GAIN,TE_DISTA}},
1355         
1356         {NULL, "Color Filter", ID_TE, 0, 5, 
1357                 {TE_COL_R,TE_COL_G,TE_COL_B,TE_BRIGHT,TE_CONTRA}},
1358         
1359         {NULL, "%l", 0, -1, 0, {0}}, // separator
1360         
1361         {NULL, "Available", ID_TE, -2, 0, {0}}
1362 };
1363
1364 /* Object Buttons KeyingSets  ------ */
1365
1366 /* check if include particles entry  */
1367 static short incl_buts_ob (bKeyingSet *ks, const char mode[])
1368 {
1369         Object *ob= OBACT;
1370         /* only if object is mesh type */
1371         
1372         if(ob==NULL) return 0;
1373         return (ob->type == OB_MESH);
1374 }
1375
1376 /* array for texture keyingset defines */
1377 bKeyingSet defks_buts_object[] = 
1378 {
1379         /* include_cb, name, blocktype, flag, chan_num, adrcodes */
1380         {incl_buts_ob, "Surface Damping", ID_OB, 0, 1, {OB_PD_SDAMP}},
1381         {incl_buts_ob, "Random Damping", ID_OB, 0, 1, {OB_PD_RDAMP}},
1382         {incl_buts_ob, "Permeability", ID_OB, 0, 1, {OB_PD_PERM}},
1383         
1384         {NULL, "%l", 0, -1, 0, {0}}, // separator
1385         
1386         {NULL, "Force Strength", ID_OB, 0, 1, {OB_PD_FSTR}},
1387         {NULL, "Force Falloff", ID_OB, 0, 1, {OB_PD_FFALL}},
1388         
1389         {NULL, "%l", 0, -1, 0, {0}}, // separator
1390         
1391         {NULL, "Available", ID_OB, -2, 0, {0}}  // this will include ob-transforms too!
1392 };
1393
1394 /* Camera Buttons KeyingSets  ------ */
1395
1396 /* check if include internal-renderer entry  */
1397 static short incl_buts_cam1 (bKeyingSet *ks, const char mode[])
1398 {
1399         /* only if renderer is internal renderer */
1400         return (G.scene->r.renderer==R_INTERN);
1401 }
1402
1403 /* check if include external-renderer entry  */
1404 static short incl_buts_cam2 (bKeyingSet *ks, const char mode[])
1405 {
1406         /* only if renderer is internal renderer */
1407         return (G.scene->r.renderer!=R_INTERN);
1408 }
1409
1410 /* array for camera keyingset defines */
1411 bKeyingSet defks_buts_cam[] = 
1412 {
1413         /* include_cb, name, blocktype, flag, chan_num, adrcodes */
1414         {NULL, "Lens", ID_CA, 0, 1, {CAM_LENS}},
1415         {NULL, "Clipping", ID_CA, 0, 2, {CAM_STA,CAM_END}},
1416         {NULL, "Focal Distance", ID_CA, 0, 1, {CAM_YF_FDIST}},
1417         
1418         {NULL, "%l", 0, -1, 0, {0}}, // separator
1419         
1420         
1421         {incl_buts_cam2, "Aperture", ID_CA, 0, 1, {CAM_YF_APERT}},
1422         {incl_buts_cam1, "Viewplane Shift", ID_CA, 0, 2, {CAM_SHIFT_X,CAM_SHIFT_Y}},
1423         
1424         {NULL, "%l", 0, -1, 0, {0}}, // separator
1425         
1426         {NULL, "Available", ID_CA, -2, 0, {0}}
1427 };
1428
1429 /* --- */
1430
1431 /* Keying Context Defines - Must keep in sync with enumeration (eKS_Contexts) */
1432 bKeyingContext ks_contexts[] = 
1433 {
1434         KSC_TEMPLATE(v3d_object),
1435         KSC_TEMPLATE(v3d_pchan),
1436         
1437         KSC_TEMPLATE(buts_shading_mat),
1438         KSC_TEMPLATE(buts_shading_wo),
1439         KSC_TEMPLATE(buts_shading_la),
1440         KSC_TEMPLATE(buts_shading_tex),
1441
1442         KSC_TEMPLATE(buts_object),
1443         KSC_TEMPLATE(buts_cam)
1444 };
1445
1446 /* Keying Context Enumeration - Must keep in sync with definitions*/
1447 typedef enum eKS_Contexts {
1448         KSC_V3D_OBJECT = 0,
1449         KSC_V3D_PCHAN,
1450         
1451         KSC_BUTS_MAT,
1452         KSC_BUTS_WO,
1453         KSC_BUTS_LA,
1454         KSC_BUTS_TEX,
1455         
1456         KSC_BUTS_OB,
1457         KSC_BUTS_CAM,
1458         
1459                 /* make sure this last one remains untouched! */
1460         KSC_TOT_TYPES
1461 } eKS_Contexts;
1462
1463
1464 /* ---------------- KeyingSet Tools ------------------- */
1465
1466 /* helper for commonkey_context_get() -  get keyingsets for 3d-view */
1467 static void commonkey_context_getv3d (ListBase *sources, bKeyingContext **ksc)
1468 {
1469         Object *ob;
1470         IpoCurve *icu;
1471         
1472         if ((OBACT) && (OBACT->flag & OB_POSEMODE)) {
1473                 bPoseChannel *pchan;
1474                 
1475                 /* pose-level */
1476                 ob= OBACT;
1477                 *ksc= &ks_contexts[KSC_V3D_PCHAN];
1478                 set_pose_keys(ob);  /* sets pchan->flag to POSE_KEY if bone selected, and clears if not */
1479                 
1480                 /* loop through posechannels */
1481                 for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next) {
1482                         if (pchan->flag & POSE_KEY) {
1483                                 bCommonKeySrc *cks;
1484                                 
1485                                 /* add new keyframing destination */
1486                                 cks= MEM_callocN(sizeof(bCommonKeySrc), "bCommonKeySrc");
1487                                 BLI_addtail(sources, cks);
1488                                 
1489                                 /* set id-block to key to, and action */
1490                                 cks->id= (ID *)ob;
1491                                 cks->act= ob->action;
1492                                 
1493                                 /* set pchan */
1494                                 cks->pchan= pchan;
1495                                 cks->actname= pchan->name;
1496                         }
1497                 }
1498         }
1499         else {
1500                 Base *base;
1501                 
1502                 /* object-level */
1503                 *ksc= &ks_contexts[KSC_V3D_OBJECT];
1504                 
1505                 /* loop through bases */
1506                 for (base= FIRSTBASE; base; base= base->next) {
1507                         if (TESTBASELIB(base)) {
1508                                 bCommonKeySrc *cks;
1509                                 
1510                                 /* add new keyframing destination */
1511                                 cks= MEM_callocN(sizeof(bCommonKeySrc), "bCommonKeySrc");
1512                                 BLI_addtail(sources, cks);
1513                                 
1514                                 /* set id-block to key to */
1515                                 ob= base->object;
1516                                 cks->id= (ID *)ob;
1517                                 
1518                                 /* when ob's keyframes are in an action, default to using 'Object' as achan name */
1519                                 if (ob->ipoflag & OB_ACTION_OB)
1520                                         cks->actname= "Object";
1521                                 
1522                                 /* set ipo-flags */
1523                                 // TODO: add checks for lib-linked data
1524                                 if ((ob->ipo) || (ob->action)) {
1525                                         if (ob->ipo) {
1526                                                 cks->ipo= ob->ipo;
1527                                         }
1528                                         else {
1529                                                 bActionChannel *achan;
1530                                                 
1531                                                 cks->act= ob->action;
1532                                                 achan= get_action_channel(ob->action, cks->actname);
1533                                                 
1534                                                 if (achan && achan->ipo)
1535                                                         cks->ipo= achan->ipo;
1536                                         }
1537                                         /* cks->ipo can be NULL while editing */
1538                                         if(cks->ipo) {
1539                                                 /* deselect all ipo-curves */
1540                                                 for (icu= cks->ipo->curve.first; icu; icu= icu->next) {
1541                                                         icu->flag &= ~IPO_SELECT;
1542                                                 }
1543                                         }
1544                                 }
1545                         }
1546                 }
1547         }
1548 }
1549
1550 /* helper for commonkey_context_get() -  get keyingsets for buttons window */
1551 static void commonkey_context_getsbuts (ListBase *sources, bKeyingContext **ksc)
1552 {
1553         bCommonKeySrc *cks;
1554
1555 #if 0 // XXX dunno what's the future of this stuff...   
1556         /* check on tab-type */
1557         switch (G.buts->mainb) {
1558         case CONTEXT_SHADING:   /* ------------- Shading buttons ---------------- */
1559                 /* subtabs include "Material", "Texture", "Lamp", "World"*/
1560                 switch (G.buts->tab[CONTEXT_SHADING]) {
1561                         case TAB_SHADING_MAT: /* >------------- Material Tab -------------< */
1562                         {
1563                                 Material *ma= editnode_get_active_material(G.buts->lockpoin);
1564                                 
1565                                 if (ma) {
1566                                         /* add new keyframing destination */
1567                                         cks= MEM_callocN(sizeof(bCommonKeySrc), "bCommonKeySrc");
1568                                         BLI_addtail(sources, cks); 
1569                                         
1570                                         /* set data */
1571                                         cks->id= (ID *)ma;
1572                                         cks->ipo= ma->ipo;
1573                                         cks->map= texchannel_to_adrcode(ma->texact);
1574                                         
1575                                         /* set keyingsets */
1576                                         *ksc= &ks_contexts[KSC_BUTS_MAT];
1577                                         return;
1578                                 }
1579                         }
1580                                 break;
1581                         case TAB_SHADING_WORLD: /* >------------- World Tab -------------< */
1582                         {
1583                                 World *wo= G.buts->lockpoin;
1584                                 
1585                                 if (wo) {
1586                                         /* add new keyframing destination */
1587                                         cks= MEM_callocN(sizeof(bCommonKeySrc), "bCommonKeySrc");
1588                                         BLI_addtail(sources, cks); 
1589                                         
1590                                         /* set data */
1591                                         cks->id= (ID *)wo;
1592                                         cks->ipo= wo->ipo;
1593                                         cks->map= texchannel_to_adrcode(wo->texact);
1594                                         
1595                                         /* set keyingsets */
1596                                         *ksc= &ks_contexts[KSC_BUTS_WO];
1597                                         return;
1598                                 }
1599                         }
1600                                 break;
1601                         case TAB_SHADING_LAMP: /* >------------- Lamp Tab -------------< */
1602                         {
1603                                 Lamp *la= G.buts->lockpoin;
1604                                 
1605                                 if (la) {
1606                                         /* add new keyframing destination */
1607                                         cks= MEM_callocN(sizeof(bCommonKeySrc), "bCommonKeySrc");
1608                                         BLI_addtail(sources, cks); 
1609                                         
1610                                         /* set data */
1611                                         cks->id= (ID *)la;
1612                                         cks->ipo= la->ipo;
1613                                         cks->map= texchannel_to_adrcode(la->texact);
1614                                         
1615                                         /* set keyingsets */
1616                                         *ksc= &ks_contexts[KSC_BUTS_LA];
1617                                         return;
1618                                 }
1619                         }
1620                                 break;
1621                         case TAB_SHADING_TEX: /* >------------- Texture Tab -------------< */
1622                         {
1623                                 Tex *tex= G.buts->lockpoin;
1624                                 
1625                                 if (tex) {
1626                                         /* add new keyframing destination */
1627                                         cks= MEM_callocN(sizeof(bCommonKeySrc), "bCommonKeySrc");
1628                                         BLI_addtail(sources, cks); 
1629                                         
1630                                         /* set data */
1631                                         cks->id= (ID *)tex;
1632                                         cks->ipo= tex->ipo;
1633                                         
1634                                         /* set keyingsets */
1635                                         *ksc= &ks_contexts[KSC_BUTS_TEX];
1636                                         return;
1637                                 }
1638                         }
1639                                 break;
1640                 }
1641                 break;
1642         
1643         case CONTEXT_OBJECT:    /* ------------- Object buttons ---------------- */
1644                 {
1645                         Object *ob= OBACT;
1646                         
1647                         if (ob) {
1648                                 /* add new keyframing destination */
1649                                 cks= MEM_callocN(sizeof(bCommonKeySrc), "bCommonKeySrc");
1650                                 BLI_addtail(sources, cks);
1651                                 
1652                                 /* set id-block to key to */
1653                                 cks->id= (ID *)ob;
1654                                 cks->ipo= ob->ipo;
1655                                 
1656                                 /* set keyingsets */
1657                                 *ksc= &ks_contexts[KSC_BUTS_OB];
1658                                 return;
1659                         }
1660                 }
1661                 break;
1662         
1663         case CONTEXT_EDITING:   /* ------------- Editing buttons ---------------- */
1664                 {
1665                         Object *ob= OBACT;
1666                         
1667                         if ((ob) && (ob->type==OB_CAMERA) && (G.buts->lockpoin)) { /* >---------------- camera buttons ---------------< */
1668                                 Camera *ca= G.buts->lockpoin;
1669                                 
1670                                 /* add new keyframing destination */
1671                                 cks= MEM_callocN(sizeof(bCommonKeySrc), "bCommonKeySrc");
1672                                 BLI_addtail(sources, cks);
1673                                 
1674                                 /* set id-block to key to */
1675                                 cks->id= (ID *)ca;
1676                                 cks->ipo= ca->ipo;
1677                                 
1678                                 /* set keyingsets */
1679                                 *ksc= &ks_contexts[KSC_BUTS_CAM];
1680                                 return;
1681                         }
1682                 }
1683                 break;
1684         }
1685 #endif // XXX end of buttons stuff to port...
1686         
1687         /* if nothing happened... */
1688         *ksc= NULL;
1689 }
1690
1691
1692 /* get keyingsets for appropriate context */
1693 static void commonkey_context_get (ScrArea *sa, short mode, ListBase *sources, bKeyingContext **ksc)
1694 {
1695         /* check view type */
1696         switch (sa->spacetype) {
1697                 /* 3d view - first one tested as most often used */
1698                 case SPACE_VIEW3D:
1699                 {
1700                         commonkey_context_getv3d(sources, ksc);
1701                 }
1702                         break;
1703                         
1704                 /* buttons view */
1705                 case SPACE_BUTS:
1706                 {
1707                         commonkey_context_getsbuts(sources, ksc);
1708                 }
1709                         break;
1710                         
1711                 /* spaces with their own methods */
1712                 case SPACE_IPO:
1713                         //if (mode == COMMONKEY_MODE_INSERT)
1714                         //      insertkey_editipo(); // XXX old calls...
1715                         return;
1716                 case SPACE_ACTION:
1717                         //if (mode == COMMONKEY_MODE_INSERT)
1718                         //      insertkey_action(); // XXX old calls...
1719                         return;
1720                         
1721                 /* timeline view - keyframe buttons */
1722                 case SPACE_TIME:
1723                 {
1724                         ScrArea *sab;
1725                         int bigarea= 0;
1726                         
1727                         /* try to find largest 3d-view available 
1728                          * (mostly of the time, this is what when user will want this,
1729                          *  as it's a standard feature in all other apps) 
1730                          */
1731                         //sab= find_biggest_area_of_type(SPACE_VIEW3D);
1732                         sab= NULL; // XXX for now...
1733                         if (sab) {
1734                                 commonkey_context_getv3d(sources, ksc);
1735                                 return;
1736                         }
1737                         
1738                         /* if not found, sab is now NULL, so perform own biggest area test */
1739                         for (sa= G.curscreen->areabase.first; sa; sa= sa->next) { // XXX this has changed!
1740                                 int area= sa->winx * sa->winy;
1741                                 
1742                                 if (sa->spacetype != SPACE_TIME) {
1743                                         if ( (!sab) || (area > bigarea) ) {
1744                                                 sab= sa;
1745                                                 bigarea= area;
1746                                         }
1747                                 }
1748                         }
1749                         
1750                         /* use whichever largest area was found (it shouldn't be a time window) */
1751                         if (sab)
1752                                 commonkey_context_get(sab, mode, sources, ksc);
1753                 }
1754                         break;
1755         }
1756 }
1757
1758 /* flush updates after all operations */
1759 static void commonkey_context_finish (ListBase *sources)
1760 {
1761         /* check view type */
1762         switch (curarea->spacetype) {
1763                 /* 3d view - first one tested as most often used */
1764                 case SPACE_VIEW3D:
1765                 {
1766                         /* either pose or object level */
1767                         if (OBACT && (OBACT->pose)) {   
1768                                 Object *ob= OBACT;
1769                                 
1770                                 /* recalculate ipo handles, etc. */
1771                                 if (ob->action)
1772                                         remake_action_ipos(ob->action);
1773                                 
1774                                 /* recalculate bone-paths on adding new keyframe? */
1775                                 // TODO: currently, there is no setting to turn this on/off globally
1776                                 if (ob->pose->flag & POSE_RECALCPATHS)
1777                                         pose_recalculate_paths(ob);
1778                         }
1779                         else {
1780                                 bCommonKeySrc *cks;
1781                                 
1782                                 /* loop over bases (as seen in sources) */
1783                                 for (cks= sources->first; cks; cks= cks->next) {
1784                                         Object *ob= (Object *)cks->id;
1785                                         
1786                                         /* simply set recalc flag */
1787                                         ob->recalc |= OB_RECALC_OB;
1788                                 }
1789                         }
1790                 }
1791                         break;
1792         }
1793 }
1794
1795 /* flush refreshes after undo */
1796 static void commonkey_context_refresh (void)
1797 {
1798         /* check view type */
1799         switch (curarea->spacetype) {
1800                 /* 3d view - first one tested as most often used */
1801                 case SPACE_VIEW3D:
1802                 {
1803                         /* do refreshes */
1804                         DAG_scene_flush_update(G.scene, screen_view3d_layers(), 0);
1805                         
1806                         //allspace(REMAKEIPO, 0);
1807                         //allqueue(REDRAWVIEW3D, 0);
1808                         //allqueue(REDRAWMARKER, 0);
1809                 }
1810                         break;
1811                         
1812                 /* buttons window */
1813                 case SPACE_BUTS:
1814                 {
1815                         //allspace(REMAKEIPO, 0);
1816                         //allqueue(REDRAWVIEW3D, 0);
1817                         //allqueue(REDRAWMARKER, 0);
1818                 }
1819                         break;
1820         }
1821 }
1822
1823 /* --- */
1824
1825 /* Build menu-string of available keying-sets (allocates memory for string)
1826  * NOTE: mode must not be longer than 64 chars
1827  */
1828 static char *build_keyingsets_menu (bKeyingContext *ksc, const char mode[48])
1829 {
1830         DynStr *pupds= BLI_dynstr_new();
1831         bKeyingSet *ks;
1832         char buf[64];
1833         char *str;
1834         int i, n;
1835         
1836         /* add title first */
1837         BLI_snprintf(buf, 64, "%s Key %%t|", mode);
1838         BLI_dynstr_append(pupds, buf);
1839         
1840         /* loop through keyingsets, adding them */
1841         for (ks=ksc->keyingsets, i=0, n=1; i < ksc->tot; ks++, i++, n++) {
1842                 /* check if keyingset can be used */
1843                 if (ks->flag == -1) {
1844                         /* optional separator? */
1845                         if (ks->include_cb) {
1846                                 if (ks->include_cb(ks, mode)) {
1847                                         BLI_snprintf( buf, 64, "%s%s", ks->name, ((n < ksc->tot)?"|":"") );
1848                                         BLI_dynstr_append(pupds, buf);
1849                                 }
1850                         }
1851                         else {
1852                                 BLI_snprintf( buf, 64, "%%l%s", ((n < ksc->tot)?"|":"") );
1853                                 BLI_dynstr_append(pupds, buf);
1854                         }
1855                 }
1856                 else if ( (ks->include_cb==NULL) || (ks->include_cb(ks, mode)) ) {
1857                         /* entry can be included */
1858                         BLI_dynstr_append(pupds, ks->name);
1859                         
1860                         /* check if special "shapekey" entry */
1861                         if (ks->flag == -3)
1862                                 BLI_snprintf( buf, 64, "%%x0%s", ((n < ksc->tot)?"|":"") );
1863                         else
1864                                 BLI_snprintf( buf, 64, "%%x%d%s", n, ((n < ksc->tot)?"|":"") );
1865                         BLI_dynstr_append(pupds, buf);
1866                 }
1867         }
1868         
1869         /* convert to normal MEM_malloc'd string */
1870         str= BLI_dynstr_get_cstring(pupds);
1871         BLI_dynstr_free(pupds);
1872         
1873         return str;
1874 }
1875
1876 /* Get the keying set that was chosen by the user from the menu */
1877 static bKeyingSet *get_keyingset_fromcontext (bKeyingContext *ksc, short index)
1878 {
1879         /* check if index is valid */
1880         if (ELEM(NULL, ksc, ksc->keyingsets))
1881                 return NULL;
1882         if ((index < 1) || (index > ksc->tot))
1883                 return NULL;
1884                 
1885         /* index starts from 1, and should directly correspond to keyingset in array */
1886         return (bKeyingSet *)(ksc->keyingsets + (index - 1));
1887 }
1888
1889 /* ---------------- Keyframe Management API -------------------- */
1890
1891 /* Display a menu for handling the insertion of keyframes based on the active view */
1892 // TODO: add back an option for repeating last keytype
1893 void common_modifykey (short mode)
1894 {
1895         ListBase dsources = {NULL, NULL};
1896         bKeyingContext *ksc= NULL;
1897         bCommonKeySrc *cks;
1898         bKeyingSet *ks = NULL;
1899         char *menustr, buf[64];
1900         short menu_nr;
1901         
1902         /* check if mode is valid */
1903         if (ELEM(mode, COMMONKEY_MODE_INSERT, COMMONKEY_MODE_DELETE)==0)
1904                 return;
1905         
1906         /* delegate to other functions or get keyingsets to use 
1907          *      - if the current area doesn't have its own handling, there will be data returned...
1908          */
1909         commonkey_context_get(curarea, mode, &dsources, &ksc);
1910         
1911         /* check that there is data to operate on */
1912         if (ELEM(NULL, dsources.first, ksc)) {
1913                 BLI_freelistN(&dsources);
1914                 return;
1915         }
1916         
1917         /* get menu and process it */
1918         if (mode == COMMONKEY_MODE_DELETE)
1919                 menustr= build_keyingsets_menu(ksc, "Delete");
1920         else
1921                 menustr= build_keyingsets_menu(ksc, "Insert");
1922         menu_nr= pupmenu(menustr);
1923         if (menustr) MEM_freeN(menustr);
1924         
1925         /* no item selected or shapekey entry? */
1926         if (menu_nr < 1) {
1927                 /* free temp sources */
1928                 BLI_freelistN(&dsources);
1929                 
1930                 /* check if insert new shapekey */
1931                 if ((menu_nr == 0) && (mode == COMMONKEY_MODE_INSERT))
1932                         insert_shapekey(OBACT);
1933                 else 
1934                         ksc->lastused= NULL;
1935                         
1936                 return;
1937         }
1938         else {
1939                 /* try to get keyingset */
1940                 ks= get_keyingset_fromcontext(ksc, menu_nr);
1941                 
1942                 if (ks == NULL) {
1943                         BLI_freelistN(&dsources);
1944                         return;
1945                 }
1946         }
1947         
1948         /* loop over each destination, applying the keying set */
1949         for (cks= dsources.first; cks; cks= cks->next) {
1950                 short success= 0;
1951                 
1952                 /* special hacks for 'available' option */
1953                 if (ks->flag == -2) {
1954                         IpoCurve *icu= NULL, *icn= NULL;
1955                         
1956                         /* get first IPO-curve */
1957                         if (cks->act && cks->actname) {
1958                                 bActionChannel *achan= get_action_channel(cks->act, cks->actname);
1959                                 
1960                                 // FIXME: what about constraint channels?
1961                                 if (achan && achan->ipo)
1962                                         icu= achan->ipo->curve.first; 
1963                         }
1964                         else if(cks->ipo)
1965                                 icu= cks->ipo->curve.first;
1966                                 
1967                         /* we get adrcodes directly from IPO curves (see method below...) */
1968                         for (; icu; icu= icn) {
1969                                 short flag;
1970                                 
1971                                 /* get next ipo-curve in case current is deleted */
1972                                 icn= icu->next;
1973                                 
1974                                 /* insert mode or delete mode */
1975                                 if (mode == COMMONKEY_MODE_DELETE) {
1976                                         /* local flags only add on to global flags */
1977                                         flag = 0;
1978                                         
1979                                         /* delete keyframe */
1980                                         success += deletekey(cks->id, ks->blocktype, cks->actname, cks->constname, icu->adrcode, flag);
1981                                 }
1982                                 else {
1983                                         /* local flags only add on to global flags */
1984                                         flag = ks->flag;
1985                                         if (IS_AUTOKEY_FLAG(AUTOMATKEY)) flag |= INSERTKEY_MATRIX;
1986                                         if (IS_AUTOKEY_FLAG(INSERTNEEDED)) flag |= INSERTKEY_NEEDED;
1987                                         // if (IS_AUTOKEY_MODE(EDITKEYS)) flag |= INSERTKEY_REPLACE;
1988                                         
1989                                         /* insert keyframe */
1990                                         success += insertkey(cks->id, ks->blocktype, cks->actname, cks->constname, icu->adrcode, flag);
1991                                 }
1992                         }
1993                 }
1994                 else {
1995                         bKS_AdrcodeGetter kag;
1996                         short (*get_next_adrcode)(bKS_AdrcodeGetter *);
1997                         int adrcode;
1998                         
1999                         /* initialise keyingset channel iterator */
2000                         ks_adrcodegetter_init(&kag, ks, cks);
2001                         
2002                         /* get iterator - only one can be in use at a time... the flags should be mutually exclusive in this regard */
2003                         if (ks->flag & COMMONKEY_PCHANROT)
2004                                 get_next_adrcode= ks_getnextadrcode_pchanrot;
2005                         else if (ks->flag & COMMONKEY_ADDMAP)
2006                                 get_next_adrcode= ks_getnextadrcode_addmap;
2007                         else
2008                                 get_next_adrcode= ks_getnextadrcode_default;
2009                         
2010                         /* loop over channels available in keyingset */
2011                         for (adrcode= get_next_adrcode(&kag); adrcode > 0; adrcode= get_next_adrcode(&kag)) {
2012                                 short flag;
2013                                 
2014                                 /* insert mode or delete mode */
2015                                 if (mode == COMMONKEY_MODE_DELETE) {
2016                                         /* local flags only add on to global flags */
2017                                         flag = 0;
2018                                         //flag &= ~COMMONKEY_MODES;
2019                                         
2020                                         /* delete keyframe */
2021                                         success += deletekey(cks->id, ks->blocktype, cks->actname, cks->constname, adrcode, flag);
2022                                 }
2023                                 else {
2024                                         /* local flags only add on to global flags */
2025                                         flag = ks->flag;
2026                                         if (IS_AUTOKEY_FLAG(AUTOMATKEY)) flag |= INSERTKEY_MATRIX;
2027                                         if (IS_AUTOKEY_FLAG(INSERTNEEDED)) flag |= INSERTKEY_NEEDED;
2028                                         // if (IS_AUTOKEY_MODE(EDITKEYS)) flag |= INSERTKEY_REPLACE;
2029                                         flag &= ~COMMONKEY_MODES;
2030                                         
2031                                         /* insert keyframe */
2032                                         success += insertkey(cks->id, ks->blocktype, cks->actname, cks->constname, adrcode, flag);
2033                                 }
2034                         }
2035                 }
2036                 
2037                 /* special handling for some key-sources */
2038                 if (success) {
2039                         /* set pose recalc-paths flag */
2040                         if (cks->pchan) {
2041                                 Object *ob= (Object *)cks->id;
2042                                 bPoseChannel *pchan= cks->pchan;
2043                                 
2044                                 /* set flag to trigger path recalc */
2045                                 if (pchan->path) 
2046                                         ob->pose->flag |= POSE_RECALCPATHS;
2047                                         
2048                                 /* clear unkeyed flag (it doesn't matter if it's set or not) */
2049                                 if (pchan->bone)
2050                                         pchan->bone->flag &= ~BONE_UNKEYED;
2051                         }
2052                 }
2053         }
2054         
2055         /* apply post-keying flushes for this data sources */
2056         commonkey_context_finish(&dsources);
2057         ksc->lastused= ks;
2058         
2059         /* free temp data */
2060         BLI_freelistN(&dsources);
2061         
2062         /* undo pushes */
2063         if (mode == COMMONKEY_MODE_DELETE)
2064                 BLI_snprintf(buf, 64, "Delete %s Key", ks->name);
2065         else
2066                 BLI_snprintf(buf, 64, "Insert %s Key", ks->name);
2067         BIF_undo_push(buf);
2068         
2069         /* queue updates for contexts */
2070         commonkey_context_refresh();
2071 }
2072
2073 /* ---- */
2074
2075 /* used to insert keyframes from any view */
2076 void common_insertkey (void)
2077 {
2078         common_modifykey(COMMONKEY_MODE_INSERT);
2079 }
2080
2081 /* used to insert keyframes from any view */
2082 void common_deletekey (void)
2083 {
2084         common_modifykey(COMMONKEY_MODE_DELETE);
2085 }
2086
2087 #endif // XXX reenable this file again later...
2088
2089 /* ************************************************** */
2090 /* KEYFRAME DETECTION */
2091
2092 /* --------------- API/Per-Datablock Handling ------------------- */
2093
2094 /* Checks whether an IPO-block has a keyframe for a given frame 
2095  * Since we're only concerned whether a keyframe exists, we can simply loop until a match is found...
2096  */
2097 short ipo_frame_has_keyframe (Ipo *ipo, float frame, short filter)
2098 {
2099         IpoCurve *icu;
2100         
2101         /* can only find if there is data */
2102         if (ipo == NULL)
2103                 return 0;
2104                 
2105         /* if only check non-muted, check if muted */
2106         if ((filter & ANIMFILTER_KEYS_MUTED) || (ipo->muteipo))
2107                 return 0;
2108         
2109         /* loop over IPO-curves, using binary-search to try to find matches 
2110          *      - this assumes that keyframes are only beztriples
2111          */
2112         for (icu= ipo->curve.first; icu; icu= icu->next) {
2113                 /* only check if there are keyframes (currently only of type BezTriple) */
2114                 if (icu->bezt) {
2115                         /* we either include all regardless of muting, or only non-muted  */
2116                         if ((filter & ANIMFILTER_KEYS_MUTED) || (icu->flag & IPO_MUTE)==0) {
2117                                 short replace = -1;
2118                                 int i = binarysearch_bezt_index(icu->bezt, frame, icu->totvert, &replace);
2119                                 
2120                                 /* binarysearch_bezt_index will set replace to be 0 or 1
2121                                  *      - obviously, 1 represents a match
2122                                  */
2123                                 if (replace) {                  
2124                                         /* sanity check: 'i' may in rare cases exceed arraylen */
2125                                         if ((i >= 0) && (i < icu->totvert))
2126                                                 return 1;
2127                                 }
2128                         }
2129                 }
2130         }
2131         
2132         /* nothing found */
2133         return 0;
2134 }
2135
2136 /* Checks whether an action-block has a keyframe for a given frame 
2137  * Since we're only concerned whether a keyframe exists, we can simply loop until a match is found...
2138  */
2139 short action_frame_has_keyframe (bAction *act, float frame, short filter)
2140 {
2141         bActionChannel *achan;
2142         
2143         /* error checking */
2144         if (act == NULL)
2145                 return 0;
2146                 
2147         /* check thorugh action-channels for match */
2148         for (achan= act->chanbase.first; achan; achan= achan->next) {
2149                 /* we either include all regardless of muting, or only non-muted 
2150                  *      - here we include 'hidden' channels in the muted definition
2151                  */
2152                 if ((filter & ANIMFILTER_KEYS_MUTED) || (achan->flag & ACHAN_HIDDEN)==0) {
2153                         if (ipo_frame_has_keyframe(achan->ipo, frame, filter))
2154                                 return 1;
2155                 }
2156         }
2157         
2158         /* nothing found */
2159         return 0;
2160 }
2161
2162 /* Checks whether an Object has a keyframe for a given frame */
2163 short object_frame_has_keyframe (Object *ob, float frame, short filter)
2164 {
2165         /* error checking */
2166         if (ob == NULL)
2167                 return 0;
2168         
2169         /* check for an action - actions take priority over normal IPO's */
2170         if (ob->action) {
2171                 float aframe;
2172                 
2173                 /* apply nla-action scaling if needed */
2174                 if ((ob->nlaflag & OB_NLA_OVERRIDE) && (ob->nlastrips.first))
2175                         aframe= get_action_frame(ob, frame);
2176                 else
2177                         aframe= frame;
2178                 
2179                 /* priority check here goes to pose-channel checks (for armatures) */
2180                 if ((ob->pose) && (ob->flag & OB_POSEMODE)) {
2181                         /* only relevant check here is to only show active... */
2182                         if (filter & ANIMFILTER_KEYS_ACTIVE) {
2183                                 bPoseChannel *pchan= get_active_posechannel(ob);
2184                                 bActionChannel *achan= (pchan) ? get_action_channel(ob->action, pchan->name) : NULL;
2185                                 
2186                                 /* since we're only interested in whether the selected one has any keyframes... */
2187                                 return (achan && ipo_frame_has_keyframe(achan->ipo, aframe, filter));
2188                         }
2189                 }
2190                 
2191                 /* for everything else, just use the standard test (only return if success) */
2192                 if (action_frame_has_keyframe(ob->action, aframe, filter))
2193                         return 1;
2194         }
2195         else if (ob->ipo) {
2196                 /* only return if success */
2197                 if (ipo_frame_has_keyframe(ob->ipo, frame, filter))
2198                         return 1;
2199         }
2200         
2201         /* try shapekey keyframes (if available, and allowed by filter) */
2202         if ( !(filter & ANIMFILTER_KEYS_LOCAL) && !(filter & ANIMFILTER_KEYS_NOSKEY) ) {
2203                 Key *key= ob_get_key(ob);
2204                 
2205                 /* shapekeys can have keyframes ('Relative Shape Keys') 
2206                  * or depend on time (old 'Absolute Shape Keys') 
2207                  */
2208                  
2209                         /* 1. test for relative (with keyframes) */
2210                 if (id_frame_has_keyframe((ID *)key, frame, filter))
2211                         return 1;
2212                         
2213                         /* 2. test for time */
2214                 // TODO... yet to be implemented (this feature may evolve before then anyway)
2215         }
2216         
2217         /* try materials */
2218         if ( !(filter & ANIMFILTER_KEYS_LOCAL) && !(filter & ANIMFILTER_KEYS_NOMAT) ) {
2219                 /* if only active, then we can skip a lot of looping */
2220                 if (filter & ANIMFILTER_KEYS_ACTIVE) {
2221                         Material *ma= give_current_material(ob, (ob->actcol + 1));
2222                         
2223                         /* we only retrieve the active material... */
2224                         if (id_frame_has_keyframe((ID *)ma, frame, filter))
2225                                 return 1;
2226                 }
2227                 else {
2228                         int a;
2229                         
2230                         /* loop over materials */
2231                         for (a=0; a<ob->totcol; a++) {
2232                                 Material *ma= give_current_material(ob, a+1);
2233                                 
2234                                 if (id_frame_has_keyframe((ID *)ma, frame, filter))
2235                                         return 1;
2236                         }
2237                 }
2238         }
2239         
2240         /* nothing found */
2241         return 0;
2242 }
2243
2244 /* --------------- API ------------------- */
2245
2246 /* Checks whether a keyframe exists for the given ID-block one the given frame */
2247 short id_frame_has_keyframe (ID *id, float frame, short filter)
2248 {
2249         /* error checking */
2250         if (id == NULL)
2251                 return 0;
2252         
2253         /* check for a valid id-type */
2254         switch (GS(id->name)) {
2255                         /* animation data-types */
2256                 case ID_IP:     /* ipo */
2257                         return ipo_frame_has_keyframe((Ipo *)id, frame, filter);
2258                 case ID_AC: /* action */
2259                         return action_frame_has_keyframe((bAction *)id, frame, filter);
2260                         
2261                 case ID_OB: /* object */
2262                         return object_frame_has_keyframe((Object *)id, frame, filter);
2263                         
2264                 case ID_MA: /* material */
2265                 {
2266                         Material *ma= (Material *)id;
2267                         
2268                         /* currently, material's only have an ipo-block */
2269                         return ipo_frame_has_keyframe(ma->ipo, frame, filter);
2270                 }
2271                         break;
2272                         
2273                 case ID_KE: /* shapekey */
2274                 {
2275                         Key *key= (Key *)id;
2276                         
2277                         /* currently, shapekey's only have an ipo-block */
2278                         return ipo_frame_has_keyframe(key->ipo, frame, filter);
2279                 }
2280                         break;
2281         }
2282         
2283         /* no keyframe found */
2284         return 0;
2285 }
2286
2287 /* ************************************************** */