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