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