this someone didn't get committed
[blender-staging.git] / source / blender / blenkernel / intern / key.c
1
2 /*  key.c      
3  *  
4  * 
5  * $Id$
6  *
7  * ***** BEGIN GPL LICENSE BLOCK *****
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL LICENSE BLOCK *****
31  */
32
33 #include <math.h>
34 #include <string.h>
35
36 #include "MEM_guardedalloc.h"
37
38 #include "BLI_blenlib.h"
39 #include "BLI_editVert.h"
40
41 #include "DNA_anim_types.h"
42 #include "DNA_curve_types.h"
43 #include "DNA_key_types.h"
44 #include "DNA_lattice_types.h"
45 #include "DNA_mesh_types.h"
46 #include "DNA_meshdata_types.h"
47 #include "DNA_object_types.h"
48 #include "DNA_scene_types.h"
49
50 #include "BKE_animsys.h"
51 #include "BKE_action.h"
52 #include "BKE_blender.h"
53 #include "BKE_curve.h"
54 #include "BKE_global.h"
55 #include "BKE_key.h"
56 #include "BKE_lattice.h"
57 #include "BKE_library.h"
58 #include "BKE_mesh.h"
59 #include "BKE_tessmesh.h"
60 #include "BKE_main.h"
61 #include "BKE_object.h"
62 #include "BKE_utildefines.h"
63
64 #include "RNA_access.h"
65 #include "BLI_cellalloc.h"
66
67
68 #ifdef HAVE_CONFIG_H
69 #include <config.h>
70 #endif
71
72 #define KEY_BPOINT              1
73 #define KEY_BEZTRIPLE   2
74
75         // old defines from DNA_ipo_types.h for data-type
76 #define IPO_FLOAT               4
77 #define IPO_BEZTRIPLE   100
78 #define IPO_BPOINT              101
79
80 int slurph_opt= 1;
81
82
83 void free_key(Key *key)
84 {
85         KeyBlock *kb;
86         
87         BKE_free_animdata((ID *)key);
88         
89         while( (kb= key->block.first) ) {
90                 
91                 if(kb->data) MEM_freeN(kb->data);
92                 
93                 BLI_remlink(&key->block, kb);
94                 MEM_freeN(kb);
95         }
96         
97 }
98
99 void free_key_nolib(Key *key)
100 {
101         KeyBlock *kb;
102         
103         while( (kb= key->block.first) ) {
104                 
105                 if(kb->data) MEM_freeN(kb->data);
106                 
107                 BLI_remlink(&key->block, kb);
108                 MEM_freeN(kb);
109         }
110         
111 }
112
113 /* GS reads the memory pointed at in a specific ordering. There are,
114  * however two definitions for it. I have jotted them down here, both,
115  * but I think the first one is actually used. The thing is that
116  * big-endian systems might read this the wrong way round. OTOH, we
117  * constructed the IDs that are read out with this macro explicitly as
118  * well. I expect we'll sort it out soon... */
119
120 /* from blendef: */
121 #define GS(a)   (*((short *)(a)))
122
123 /* from misc_util: flip the bytes from x  */
124 /*  #define GS(x) (((unsigned char *)(x))[0] << 8 | ((unsigned char *)(x))[1]) */
125
126 Key *add_key(ID *id)    /* common function */
127 {
128         Key *key;
129         char *el;
130         
131         key= alloc_libblock(&G.main->key, ID_KE, "Key");
132         
133         key->type= KEY_NORMAL;
134         key->from= id;
135
136         key->uidgen = 1;
137         
138         // XXX the code here uses some defines which will soon be depreceated...
139         if( GS(id->name)==ID_ME) {
140                 el= key->elemstr;
141                 
142                 el[0]= 3;
143                 el[1]= IPO_FLOAT;
144                 el[2]= 0;
145                 
146                 key->elemsize= 12;
147         }
148         else if( GS(id->name)==ID_LT) {
149                 el= key->elemstr;
150                 
151                 el[0]= 3;
152                 el[1]= IPO_FLOAT;
153                 el[2]= 0;
154                 
155                 key->elemsize= 12;
156         }
157         else if( GS(id->name)==ID_CU) {
158                 el= key->elemstr;
159                 
160                 el[0]= 4;
161                 el[1]= IPO_BPOINT;
162                 el[2]= 0;
163                 
164                 key->elemsize= 16;
165         }
166         
167         return key;
168 }
169
170 Key *copy_key(Key *key)
171 {
172         Key *keyn;
173         KeyBlock *kbn, *kb;
174         
175         if(key==0) return 0;
176         
177         keyn= copy_libblock(key);
178         
179 #if 0 // XXX old animation system
180         keyn->ipo= copy_ipo(key->ipo);
181 #endif // XXX old animation system
182         
183         BLI_duplicatelist(&keyn->block, &key->block);
184         
185         kb= key->block.first;
186         kbn= keyn->block.first;
187         while(kbn) {
188                 
189                 if(kbn->data) kbn->data= MEM_dupallocN(kbn->data);
190                 if(kb==key->refkey) keyn->refkey= kbn;
191                 
192                 kbn= kbn->next;
193                 kb= kb->next;
194         }
195         
196         return keyn;
197 }
198
199
200 Key *copy_key_nolib(Key *key)
201 {
202         Key *keyn;
203         KeyBlock *kbn, *kb;
204         
205         if(key==0) return 0;
206         
207         keyn= MEM_dupallocN(key);
208         
209         BLI_duplicatelist(&keyn->block, &key->block);
210         
211         kb= key->block.first;
212         kbn= keyn->block.first;
213         while(kbn) {
214                 
215                 if(kbn->data) kbn->data= MEM_dupallocN(kbn->data);
216                 if(kb==key->refkey) keyn->refkey= kbn;
217                 
218                 kbn= kbn->next;
219                 kb= kb->next;
220         }
221         
222         return keyn;
223 }
224
225 void make_local_key(Key *key)
226 {
227
228     /* - only lib users: do nothing
229     * - only local users: set flag
230     * - mixed: make copy
231     */
232     if(key==0) return;
233         
234         key->id.lib= 0;
235         new_id(0, (ID *)key, 0);
236
237 #if 0 // XXX old animation system
238         make_local_ipo(key->ipo);
239 #endif // XXX old animation system
240 }
241
242 /* Sort shape keys and Ipo curves after a change.  This assumes that at most
243  * one key was moved, which is a valid assumption for the places it's
244  * currently being called.
245  */
246
247 void sort_keys(Key *key)
248 {
249         KeyBlock *kb;
250         //short i, adrcode;
251         //IpoCurve *icu = NULL;
252         KeyBlock *kb2;
253
254         /* locate the key which is out of position */ 
255         for (kb= key->block.first; kb; kb= kb->next)
256                 if ((kb->next) && (kb->pos > kb->next->pos))
257                         break;
258
259         /* if we find a key, move it */
260         if (kb) {
261                 kb = kb->next; /* next key is the out-of-order one */
262                 BLI_remlink(&key->block, kb);
263                 
264                 /* find the right location and insert before */
265                 for (kb2=key->block.first; kb2; kb2= kb2->next) {
266                         if (kb2->pos > kb->pos) {
267                                 BLI_insertlink(&key->block, kb2->prev, kb);
268                                 break;
269                         }
270                 }
271                 
272                 /* if more than one Ipo curve, see if this key had a curve */
273 #if 0 // XXX old animation system
274                 if(key->ipo && key->ipo->curve.first != key->ipo->curve.last ) {
275                         for(icu= key->ipo->curve.first; icu; icu= icu->next) {
276                                 /* if we find the curve, remove it and reinsert in the 
277                                  right place */
278                                 if(icu->adrcode==kb->adrcode) {
279                                         IpoCurve *icu2;
280                                         BLI_remlink(&key->ipo->curve, icu);
281                                         for(icu2= key->ipo->curve.first; icu2; icu2= icu2->next) {
282                                                 if(icu2->adrcode >= kb2->adrcode) {
283                                                         BLI_insertlink(&key->ipo->curve, icu2->prev, icu);
284                                                         break;
285                                                 }
286                                         }
287                                         break;
288                                 }
289                         }
290                 }
291                 
292                 /* kb points at the moved key, icu at the moved ipo (if it exists).
293                  * go back now and renumber adrcodes */
294
295                 /* first new code */
296                 adrcode = kb2->adrcode;
297                 for (i = kb->adrcode - adrcode; i >= 0; i--, adrcode++) {
298                         /* if the next ipo curve matches the current key, renumber it */
299                         if(icu && icu->adrcode == kb->adrcode ) {
300                                 icu->adrcode = adrcode;
301                                 icu = icu->next;
302                         }
303                         /* renumber the shape key */
304                         kb->adrcode = adrcode;
305                         kb = kb->next;
306                 }
307 #endif // XXX old animation system
308         }
309
310         /* new rule; first key is refkey, this to match drawing channels... */
311         key->refkey= key->block.first;
312 }
313
314 /**************** do the key ****************/
315
316 void key_curve_position_weights(float t, float *data, int type)
317 {
318         float t2, t3, fc;
319         
320         if(type==KEY_LINEAR) {
321                 data[0]=                  0.0f;
322                 data[1]= -t             + 1.0f;
323                 data[2]= t;
324                 data[3]=                  0.0f;
325         }
326         else if(type==KEY_CARDINAL) {
327                 t2= t*t;
328                 t3= t2*t;
329                 fc= 0.71f;
330                 
331                 data[0]= -fc*t3                 + 2.0f*fc*t2            - fc*t;
332                 data[1]= (2.0f-fc)*t3   + (fc-3.0f)*t2                                  + 1.0f;
333                 data[2]= (fc-2.0f)*t3   + (3.0f-2.0f*fc)*t2     + fc*t;
334                 data[3]= fc*t3                  - fc*t2;
335         }
336         else if(type==KEY_BSPLINE) {
337                 t2= t*t;
338                 t3= t2*t;
339
340                 data[0]= -0.16666666f*t3        + 0.5f*t2       - 0.5f*t        + 0.16666666f;
341                 data[1]= 0.5f*t3                        - t2                                    + 0.6666666f;
342                 data[2]= -0.5f*t3                       + 0.5f*t2       + 0.5f*t        + 0.16666666f;
343                 data[3]= 0.16666666f*t3;
344         }
345 }
346
347 /* first derivative */
348 void key_curve_tangent_weights(float t, float *data, int type)
349 {
350         float t2, fc;
351         
352         if(type==KEY_LINEAR) {
353                 data[0]= 0.0f;
354                 data[1]= -1.0f;
355                 data[2]= 1.0f;
356                 data[3]= 0.0f;
357         }
358         else if(type==KEY_CARDINAL) {
359                 t2= t*t;
360                 fc= 0.71f;
361                 
362                 data[0]= -3.0f*fc*t2            +4.0f*fc*t                              - fc;
363                 data[1]= 3.0f*(2.0f-fc)*t2      +2.0f*(fc-3.0f)*t;
364                 data[2]= 3.0f*(fc-2.0f)*t2      +2.0f*(3.0f-2.0f*fc)*t  + fc;
365                 data[3]= 3.0f*fc*t2                     -2.0f*fc*t;
366         }
367         else if(type==KEY_BSPLINE) {
368                 t2= t*t;
369
370                 data[0]= -0.5f*t2       + t                     - 0.5f;
371                 data[1]= 1.5f*t2        - 2.0f*t;
372                 data[2]= -1.5f*t2       + t                     + 0.5f;
373                 data[3]= 0.5f*t2;
374         }
375 }
376
377 /* second derivative */
378 void key_curve_normal_weights(float t, float *data, int type)
379 {
380         float fc;
381         
382         if(type==KEY_LINEAR) {
383                 data[0]= 0.0f;
384                 data[1]= 0.0f;
385                 data[2]= 0.0f;
386                 data[3]= 0.0f;
387         }
388         else if(type==KEY_CARDINAL) {
389                 fc= 0.71f;
390                 
391                 data[0]= -6.0f*fc*t                     + 4.0f*fc;
392                 data[1]= 6.0f*(2.0f-fc)*t       + 2.0f*(fc-3.0f);
393                 data[2]= 6.0f*(fc-2.0f)*t       + 2.0f*(3.0f-2.0f*fc);
394                 data[3]= 6.0f*fc*t                      - 2.0f*fc;
395         }
396         else if(type==KEY_BSPLINE) {
397                 data[0]= -1.0f*t        + 1.0f;
398                 data[1]= 3.0f*t         - 2.0f;
399                 data[2]= -3.0f*t        + 1.0f;
400                 data[3]= 1.0f*t;
401         }
402 }
403
404 static int setkeys(float fac, ListBase *lb, KeyBlock *k[], float *t, int cycl)
405 {
406         /* return 1 means k[2] is the position, return 0 means interpolate */
407         KeyBlock *k1, *firstkey;
408         float d, dpos, ofs=0, lastpos, temp, fval[4];
409         short bsplinetype;
410
411         firstkey= lb->first;
412         k1= lb->last;
413         lastpos= k1->pos;
414         dpos= lastpos - firstkey->pos;
415
416         if(fac < firstkey->pos) fac= firstkey->pos;
417         else if(fac > k1->pos) fac= k1->pos;
418
419         k1=k[0]=k[1]=k[2]=k[3]= firstkey;
420         t[0]=t[1]=t[2]=t[3]= k1->pos;
421
422         /* if(fac<0.0 || fac>1.0) return 1; */
423
424         if(k1->next==0) return 1;
425
426         if(cycl) {      /* pre-sort */
427                 k[2]= k1->next;
428                 k[3]= k[2]->next;
429                 if(k[3]==0) k[3]=k1;
430                 while(k1) {
431                         if(k1->next==0) k[0]=k1;
432                         k1=k1->next;
433                 }
434                 k1= k[1];
435                 t[0]= k[0]->pos;
436                 t[1]+= dpos;
437                 t[2]= k[2]->pos + dpos;
438                 t[3]= k[3]->pos + dpos;
439                 fac+= dpos;
440                 ofs= dpos;
441                 if(k[3]==k[1]) { 
442                         t[3]+= dpos; 
443                         ofs= 2.0f*dpos;
444                 }
445                 if(fac<t[1]) fac+= dpos;
446                 k1= k[3];
447         }
448         else {          /* pre-sort */
449                 k[2]= k1->next;
450                 t[2]= k[2]->pos;
451                 k[3]= k[2]->next;
452                 if(k[3]==0) k[3]= k[2];
453                 t[3]= k[3]->pos;
454                 k1= k[3];
455         }
456         
457         while( t[2]<fac ) {     /* find correct location */
458                 if(k1->next==0) {
459                         if(cycl) {
460                                 k1= firstkey;
461                                 ofs+= dpos;
462                         }
463                         else if(t[2]==t[3]) break;
464                 }
465                 else k1= k1->next;
466
467                 t[0]= t[1]; 
468                 k[0]= k[1];
469                 t[1]= t[2]; 
470                 k[1]= k[2];
471                 t[2]= t[3]; 
472                 k[2]= k[3];
473                 t[3]= k1->pos+ofs; 
474                 k[3]= k1;
475
476                 if(ofs>2.1+lastpos) break;
477         }
478         
479         bsplinetype= 0;
480         if(k[1]->type==KEY_BSPLINE || k[2]->type==KEY_BSPLINE) bsplinetype= 1;
481
482
483         if(cycl==0) {
484                 if(bsplinetype==0) {    /* B spline doesn't go through the control points */
485                         if(fac<=t[1]) {         /* fac for 1st key */
486                                 t[2]= t[1];
487                                 k[2]= k[1];
488                                 return 1;
489                         }
490                         if(fac>=t[2] ) {        /* fac after 2nd key */
491                                 return 1;
492                         }
493                 }
494                 else if(fac>t[2]) {     /* last key */
495                         fac= t[2];
496                         k[3]= k[2];
497                         t[3]= t[2];
498                 }
499         }
500
501         d= t[2]-t[1];
502         if(d==0.0) {
503                 if(bsplinetype==0) {
504                         return 1;       /* both keys equal */
505                 }
506         }
507         else d= (fac-t[1])/d;
508
509         /* interpolation */
510         
511         key_curve_position_weights(d, t, k[1]->type);
512
513         if(k[1]->type != k[2]->type) {
514                 key_curve_position_weights(d, fval, k[2]->type);
515                 
516                 temp= 1.0f-d;
517                 t[0]= temp*t[0]+ d*fval[0];
518                 t[1]= temp*t[1]+ d*fval[1];
519                 t[2]= temp*t[2]+ d*fval[2];
520                 t[3]= temp*t[3]+ d*fval[3];
521         }
522
523         return 0;
524
525 }
526
527 static void flerp(int aantal, float *in, float *f0, float *f1, float *f2, float *f3, float *t)  
528 {
529         int a;
530
531         for(a=0; a<aantal; a++) {
532                 in[a]= t[0]*f0[a]+t[1]*f1[a]+t[2]*f2[a]+t[3]*f3[a];
533         }
534 }
535
536 static void rel_flerp(int aantal, float *in, float *ref, float *out, float fac)
537 {
538         int a;
539         
540         for(a=0; a<aantal; a++) {
541                 in[a]-= fac*(ref[a]-out[a]);
542         }
543 }
544
545 static char *key_block_get_data(Key *key, KeyBlock *actkb, KeyBlock *kb, char **freedata)
546 {
547         if(kb == actkb) {
548                 /* this hack makes it possible to edit shape keys in
549                    edit mode with shape keys blending applied */
550                 if(GS(key->from->name) == ID_ME) {
551                         Mesh *me;
552                         BMVert *eve;
553                         BMIter iter;
554                         float (*co)[3];
555                         int a;
556
557                         me= (Mesh*)key->from;
558
559                         if(me->edit_btmesh && me->edit_btmesh->bm->totvert == kb->totelem) {
560                                 a= 0;
561                                 co= MEM_callocN(sizeof(float)*3*me->edit_btmesh->bm->totvert, "key_block_get_data");
562
563                                 BM_ITER(eve, &iter, me->edit_btmesh->bm, BM_VERTS_OF_MESH, NULL) {
564                                         VECCOPY(co[a], eve->co);
565                                         a++;
566                                 }
567
568                                 *freedata= (char*)co;
569                                 return (char*)co;
570                         }
571                 }
572         }
573
574         *freedata= NULL;
575         return kb->data;
576 }
577
578 static void cp_key(int start, int end, int tot, char *poin, Key *key, KeyBlock *actkb, KeyBlock *kb, float *weights, int mode)
579 {
580         float ktot = 0.0, kd = 0.0;
581         int elemsize, poinsize = 0, a, *ofsp, ofs[32], flagflo=0;
582         char *k1, *kref, *freek1, *freekref;
583         char *cp, elemstr[8];
584
585         if(key->from==NULL) return;
586
587         if( GS(key->from->name)==ID_ME ) {
588                 ofs[0]= sizeof(float)*3;
589                 ofs[1]= 0;
590                 poinsize= ofs[0];
591         }
592         else if( GS(key->from->name)==ID_LT ) {
593                 ofs[0]= sizeof(float)*3;
594                 ofs[1]= 0;
595                 poinsize= ofs[0];
596         }
597         else if( GS(key->from->name)==ID_CU ) {
598                 if(mode==KEY_BPOINT) ofs[0]= sizeof(float)*4;
599                 else ofs[0]= sizeof(float)*10;
600                 
601                 ofs[1]= 0;
602                 poinsize= ofs[0];
603         }
604
605         if(end>tot) end= tot;
606         
607         if(tot != kb->totelem) {
608                 ktot= 0.0;
609                 flagflo= 1;
610                 if(kb->totelem) {
611                         kd= kb->totelem/(float)tot;
612                 }
613                 else return;
614         }
615
616         k1= key_block_get_data(key, actkb, kb, &freek1);
617         kref= key_block_get_data(key, actkb, key->refkey, &freekref);
618
619         /* this exception is needed for slurphing */
620         if(start!=0) {
621                 
622                 poin+= poinsize*start;
623                 
624                 if(flagflo) {
625                         ktot+= start*kd;
626                         a= (int)floor(ktot);
627                         if(a) {
628                                 ktot-= a;
629                                 k1+= a*key->elemsize;
630                         }
631                 }
632                 else k1+= start*key->elemsize;
633         }       
634         
635         if(mode==KEY_BEZTRIPLE) {
636                 elemstr[0]= 1;
637                 elemstr[1]= IPO_BEZTRIPLE;
638                 elemstr[2]= 0;
639         }
640         
641         /* just do it here, not above! */
642         elemsize= key->elemsize;
643         if(mode==KEY_BEZTRIPLE) elemsize*= 3;
644
645         for(a=start; a<end; a++) {
646                 cp= key->elemstr;
647                 if(mode==KEY_BEZTRIPLE) cp= elemstr;
648
649                 ofsp= ofs;
650                 
651                 while( cp[0] ) {
652                         
653                         switch(cp[1]) {
654                         case IPO_FLOAT:
655                                 if(weights) {
656                                         memcpy(poin, kref, sizeof(float)*3);
657                                         if(*weights!=0.0f)
658                                                 rel_flerp(cp[0], (float *)poin, (float *)kref, (float *)k1, *weights);
659                                         weights++;
660                                 }
661                                 else 
662                                         memcpy(poin, k1, sizeof(float)*3);
663                                 break;
664                         case IPO_BPOINT:
665                                 memcpy(poin, k1, sizeof(float)*4);
666                                 break;
667                         case IPO_BEZTRIPLE:
668                                 memcpy(poin, k1, sizeof(float)*10);
669                                 break;
670                         }
671                         
672                         poin+= ofsp[0]; 
673                         cp+= 2; ofsp++;
674                 }
675                 
676                 /* are we going to be nasty? */
677                 if(flagflo) {
678                         ktot+= kd;
679                         while(ktot>=1.0) {
680                                 ktot-= 1.0;
681                                 k1+= elemsize;
682                                 kref+= elemsize;
683                         }
684                 }
685                 else {
686                         k1+= elemsize;
687                         kref+= elemsize;
688                 }
689                 
690                 if(mode==KEY_BEZTRIPLE) a+=2;
691         }
692
693         if(freek1) MEM_freeN(freek1);
694         if(freekref) MEM_freeN(freekref);
695 }
696
697 static void cp_cu_key(Curve *cu, Key *key, KeyBlock *actkb, KeyBlock *kb, int start, int end, char *out, int tot)
698 {
699         Nurb *nu;
700         char *poin;
701         int a, step, a1, a2;
702
703         for(a=0, nu=cu->nurb.first; nu; nu=nu->next, a+=step) {
704                 if(nu->bp) {
705                         step= nu->pntsu*nu->pntsv;
706                         
707                         /* exception because keys prefer to work with complete blocks */
708                         poin= out - a*sizeof(float)*4;
709                         a1= MAX2(a, start);
710                         a2= MIN2(a+step, end);
711                         
712                         if(a1<a2) cp_key(a1, a2, tot, poin, key, actkb, kb, NULL, KEY_BPOINT);
713                 }
714                 else if(nu->bezt) {
715                         step= 3*nu->pntsu;
716                         
717                         poin= out - a*sizeof(float)*10;
718                         a1= MAX2(a, start);
719                         a2= MIN2(a+step, end);
720
721                         if(a1<a2) cp_key(a1, a2, tot, poin, key, actkb, kb, NULL, KEY_BEZTRIPLE);
722                 }
723                 else
724                         step= 0;
725         }
726 }
727
728
729 void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, KeyBlock *actkb, int mode)
730 {
731         KeyBlock *kb;
732         int *ofsp, ofs[3], elemsize, b;
733         char *cp, *poin, *reffrom, *from, elemstr[8];
734         char *freefrom, *freereffrom;
735         
736         if(key->from==NULL) return;
737         
738         if( GS(key->from->name)==ID_ME ) {
739                 ofs[0]= sizeof(float)*3;
740                 ofs[1]= 0;
741         }
742         else if( GS(key->from->name)==ID_LT ) {
743                 ofs[0]= sizeof(float)*3;
744                 ofs[1]= 0;
745         }
746         else if( GS(key->from->name)==ID_CU ) {
747                 if(mode==KEY_BPOINT) ofs[0]= sizeof(float)*4;
748                 else ofs[0]= sizeof(float)*10;
749                 
750                 ofs[1]= 0;
751         }
752         
753         if(end>tot) end= tot;
754         
755         /* in case of beztriple */
756         elemstr[0]= 1;                          /* nr of ipofloats */
757         elemstr[1]= IPO_BEZTRIPLE;
758         elemstr[2]= 0;
759
760         /* just here, not above! */
761         elemsize= key->elemsize;
762         if(mode==KEY_BEZTRIPLE) elemsize*= 3;
763
764         /* step 1 init */
765         cp_key(start, end, tot, basispoin, key, actkb, key->refkey, NULL, mode);
766         
767         /* step 2: do it */
768         
769         for(kb=key->block.first; kb; kb=kb->next) {
770                 if(kb!=key->refkey) {
771                         float icuval= kb->curval;
772                         
773                         /* only with value, and no difference allowed */
774                         if(!(kb->flag & KEYBLOCK_MUTE) && icuval!=0.0f && kb->totelem==tot) {
775                                 KeyBlock *refb;
776                                 float weight, *weights= kb->weights;
777
778                                 /* reference now can be any block */
779                                 refb= BLI_findlink(&key->block, kb->relative);
780                                 if(refb==NULL) continue;
781                                 
782                                 poin= basispoin;
783                                 from= key_block_get_data(key, actkb, kb, &freefrom);
784                                 reffrom= key_block_get_data(key, actkb, refb, &freereffrom);
785                                 
786                                 poin+= start*ofs[0];
787                                 reffrom+= key->elemsize*start;  // key elemsize yes!
788                                 from+= key->elemsize*start;
789                                 
790                                 for(b=start; b<end; b++) {
791                                 
792                                         if(weights) 
793                                                 weight= *weights * icuval;
794                                         else
795                                                 weight= icuval;
796                                         
797                                         cp= key->elemstr;       
798                                         if(mode==KEY_BEZTRIPLE) cp= elemstr;
799                                         
800                                         ofsp= ofs;
801                                         
802                                         while( cp[0] ) {        /* cp[0]==amount */
803                                                 
804                                                 switch(cp[1]) {
805                                                 case IPO_FLOAT:
806                                                         rel_flerp(3, (float *)poin, (float *)reffrom, (float *)from, weight);
807                                                         break;
808                                                 case IPO_BPOINT:
809                                                         rel_flerp(4, (float *)poin, (float *)reffrom, (float *)from, weight);
810                                                         break;
811                                                 case IPO_BEZTRIPLE:
812                                                         rel_flerp(10, (float *)poin, (float *)reffrom, (float *)from, weight);
813                                                         break;
814                                                 }
815                                                 
816                                                 poin+= ofsp[0];                         
817                                                 
818                                                 cp+= 2;
819                                                 ofsp++;
820                                         }
821                                         
822                                         reffrom+= elemsize;
823                                         from+= elemsize;
824                                         
825                                         if(mode==KEY_BEZTRIPLE) b+= 2;
826                                         if(weights) weights++;
827                                 }
828
829                                 if(freefrom) MEM_freeN(freefrom);
830                                 if(freereffrom) MEM_freeN(freereffrom);
831                         }
832                 }
833         }
834 }
835
836
837 static void do_key(int start, int end, int tot, char *poin, Key *key, KeyBlock *actkb, KeyBlock **k, float *t, int mode)
838 {
839         float k1tot = 0.0, k2tot = 0.0, k3tot = 0.0, k4tot = 0.0;
840         float k1d = 0.0, k2d = 0.0, k3d = 0.0, k4d = 0.0;
841         int a, ofs[32], *ofsp;
842         int flagdo= 15, flagflo=0, elemsize, poinsize=0;
843         char *k1, *k2, *k3, *k4, *freek1, *freek2, *freek3, *freek4;
844         char *cp, elemstr[8];;
845
846         if(key->from==0) return;
847
848         if( GS(key->from->name)==ID_ME ) {
849                 ofs[0]= sizeof(float)*3;
850                 ofs[1]= 0;
851                 poinsize= ofs[0];
852         }
853         else if( GS(key->from->name)==ID_LT ) {
854                 ofs[0]= sizeof(float)*3;
855                 ofs[1]= 0;
856                 poinsize= ofs[0];
857         }
858         else if( GS(key->from->name)==ID_CU ) {
859                 if(mode==KEY_BPOINT) ofs[0]= sizeof(float)*4;
860                 else ofs[0]= sizeof(float)*10;
861                 
862                 ofs[1]= 0;
863                 poinsize= ofs[0];
864         }
865         
866         if(end>tot) end= tot;
867
868         k1= key_block_get_data(key, actkb, k[0], &freek1);
869         k2= key_block_get_data(key, actkb, k[1], &freek2);
870         k3= key_block_get_data(key, actkb, k[2], &freek3);
871         k4= key_block_get_data(key, actkb, k[3], &freek4);
872
873         /*  test for more or less points (per key!) */
874         if(tot != k[0]->totelem) {
875                 k1tot= 0.0;
876                 flagflo |= 1;
877                 if(k[0]->totelem) {
878                         k1d= k[0]->totelem/(float)tot;
879                 }
880                 else flagdo -= 1;
881         }
882         if(tot != k[1]->totelem) {
883                 k2tot= 0.0;
884                 flagflo |= 2;
885                 if(k[0]->totelem) {
886                         k2d= k[1]->totelem/(float)tot;
887                 }
888                 else flagdo -= 2;
889         }
890         if(tot != k[2]->totelem) {
891                 k3tot= 0.0;
892                 flagflo |= 4;
893                 if(k[0]->totelem) {
894                         k3d= k[2]->totelem/(float)tot;
895                 }
896                 else flagdo -= 4;
897         }
898         if(tot != k[3]->totelem) {
899                 k4tot= 0.0;
900                 flagflo |= 8;
901                 if(k[0]->totelem) {
902                         k4d= k[3]->totelem/(float)tot;
903                 }
904                 else flagdo -= 8;
905         }
906
907                 /* this exception needed for slurphing */
908         if(start!=0) {
909
910                 poin+= poinsize*start;
911                 
912                 if(flagdo & 1) {
913                         if(flagflo & 1) {
914                                 k1tot+= start*k1d;
915                                 a= (int)floor(k1tot);
916                                 if(a) {
917                                         k1tot-= a;
918                                         k1+= a*key->elemsize;
919                                 }
920                         }
921                         else k1+= start*key->elemsize;
922                 }
923                 if(flagdo & 2) {
924                         if(flagflo & 2) {
925                                 k2tot+= start*k2d;
926                                 a= (int)floor(k2tot);
927                                 if(a) {
928                                         k2tot-= a;
929                                         k2+= a*key->elemsize;
930                                 }
931                         }
932                         else k2+= start*key->elemsize;
933                 }
934                 if(flagdo & 4) {
935                         if(flagflo & 4) {
936                                 k3tot+= start*k3d;
937                                 a= (int)floor(k3tot);
938                                 if(a) {
939                                         k3tot-= a;
940                                         k3+= a*key->elemsize;
941                                 }
942                         }
943                         else k3+= start*key->elemsize;
944                 }
945                 if(flagdo & 8) {
946                         if(flagflo & 8) {
947                                 k4tot+= start*k4d;
948                                 a= (int)floor(k4tot);
949                                 if(a) {
950                                         k4tot-= a;
951                                         k4+= a*key->elemsize;
952                                 }
953                         }
954                         else k4+= start*key->elemsize;
955                 }
956
957         }
958
959         /* in case of beztriple */
960         elemstr[0]= 1;                          /* nr of ipofloats */
961         elemstr[1]= IPO_BEZTRIPLE;
962         elemstr[2]= 0;
963
964         /* only here, not above! */
965         elemsize= key->elemsize;
966         if(mode==KEY_BEZTRIPLE) elemsize*= 3;
967
968         for(a=start; a<end; a++) {
969         
970                 cp= key->elemstr;       
971                 if(mode==KEY_BEZTRIPLE) cp= elemstr;
972                 
973                 ofsp= ofs;
974                 
975                 while( cp[0] ) {        /* cp[0]==amount */
976                         
977                         switch(cp[1]) {
978                         case IPO_FLOAT:
979                                 flerp(3, (float *)poin, (float *)k1, (float *)k2, (float *)k3, (float *)k4, t);
980                                 break;
981                         case IPO_BPOINT:
982                                 flerp(4, (float *)poin, (float *)k1, (float *)k2, (float *)k3, (float *)k4, t);
983                                 break;
984                         case IPO_BEZTRIPLE:
985                                 flerp(10, (void *)poin, (void *)k1, (void *)k2, (void *)k3, (void *)k4, t);
986                                 break;
987                         }
988                         
989                         poin+= ofsp[0];                         
990                         cp+= 2;
991                         ofsp++;
992                 }
993                 /* lets do it the difficult way: when keys have a different size */
994                 if(flagdo & 1) {
995                         if(flagflo & 1) {
996                                 k1tot+= k1d;
997                                 while(k1tot>=1.0) {
998                                         k1tot-= 1.0;
999                                         k1+= elemsize;
1000                                 }
1001                         }
1002                         else k1+= elemsize;
1003                 }
1004                 if(flagdo & 2) {
1005                         if(flagflo & 2) {
1006                                 k2tot+= k2d;
1007                                 while(k2tot>=1.0) {
1008                                         k2tot-= 1.0;
1009                                         k2+= elemsize;
1010                                 }
1011                         }
1012                         else k2+= elemsize;
1013                 }
1014                 if(flagdo & 4) {
1015                         if(flagflo & 4) {
1016                                 k3tot+= k3d;
1017                                 while(k3tot>=1.0) {
1018                                         k3tot-= 1.0;
1019                                         k3+= elemsize;
1020                                 }
1021                         }
1022                         else k3+= elemsize;
1023                 }
1024                 if(flagdo & 8) {
1025                         if(flagflo & 8) {
1026                                 k4tot+= k4d;
1027                                 while(k4tot>=1.0) {
1028                                         k4tot-= 1.0;
1029                                         k4+= elemsize;
1030                                 }
1031                         }
1032                         else k4+= elemsize;
1033                 }
1034                 
1035                 if(mode==KEY_BEZTRIPLE) a+= 2;
1036         }
1037
1038         if(freek1) MEM_freeN(freek1);
1039         if(freek2) MEM_freeN(freek2);
1040         if(freek3) MEM_freeN(freek3);
1041         if(freek4) MEM_freeN(freek4);
1042 }
1043
1044 static float *get_weights_array(Object *ob, char *vgroup)
1045 {
1046         bDeformGroup *curdef;
1047         MDeformVert *dvert= NULL;
1048         int totvert= 0, index= 0;
1049         
1050         /* no vgroup string set? */
1051         if(vgroup[0]==0) return NULL;
1052         
1053         /* gather dvert and totvert */
1054         if(ob->type==OB_MESH) {
1055                 Mesh *me= ob->data;
1056                 dvert= me->dvert;
1057                 totvert= me->totvert;
1058         }
1059         else if(ob->type==OB_LATTICE) {
1060                 Lattice *lt= ob->data;
1061                 dvert= lt->dvert;
1062                 totvert= lt->pntsu*lt->pntsv*lt->pntsw;
1063         }
1064         
1065         if(dvert==NULL) return NULL;
1066         
1067         /* find the group (weak loop-in-loop) */
1068         for (curdef = ob->defbase.first; curdef; curdef=curdef->next, index++)
1069                 if (!strcmp(curdef->name, vgroup))
1070                         break;
1071
1072         if(curdef) {
1073                 float *weights;
1074                 int i, j;
1075                 
1076                 weights= MEM_callocN(totvert*sizeof(float), "weights");
1077                 
1078                 for (i=0; i < totvert; i++, dvert++) {
1079                         for(j=0; j<dvert->totweight; j++) {
1080                                 if (dvert->dw[j].def_nr == index) {
1081                                         weights[i]= dvert->dw[j].weight;
1082                                         break;
1083                                 }
1084                         }
1085                 }
1086                 return weights;
1087         }
1088         return NULL;
1089 }
1090
1091 static void do_mesh_key(Scene *scene, Object *ob, Key *key, char *out, int tot)
1092 {
1093         KeyBlock *k[4], *actkb= ob_get_keyblock(ob);
1094         float cfra, ctime, t[4], delta;
1095         int a, flag = 0, step;
1096         
1097         if(key->slurph && key->type!=KEY_RELATIVE ) {
1098                 delta= key->slurph;
1099                 delta/= tot;
1100                 
1101                 step= 1;
1102                 if(tot>100 && slurph_opt) {
1103                         step= tot/50;
1104                         delta*= step;
1105                         /* in do_key and cp_key the case a>tot is handled */
1106                 }
1107                 
1108                 cfra= (float)scene->r.cfra;
1109                 
1110                 for(a=0; a<tot; a+=step, cfra+= delta) {
1111                         
1112                         ctime= bsystem_time(scene, 0, cfra, 0.0); // xxx  ugly cruft!
1113 #if 0 // XXX old animation system
1114                         if(calc_ipo_spec(key->ipo, KEY_SPEED, &ctime)==0) {
1115                                 ctime /= 100.0;
1116                                 CLAMP(ctime, 0.0, 1.0);
1117                         }
1118 #endif // XXX old animation system
1119                         // XXX for now... since speed curve cannot be directly ported yet
1120                         ctime /= 100.0f;
1121                         CLAMP(ctime, 0.0f, 1.0f); // XXX for compat, we use this, but this clamping was confusing
1122                 
1123                         flag= setkeys(ctime, &key->block, k, t, 0);
1124
1125                         if(flag==0)
1126                                 do_key(a, a+step, tot, (char *)out, key, actkb, k, t, 0);
1127                         else
1128                                 cp_key(a, a+step, tot, (char *)out, key, actkb, k[2], NULL, 0);
1129                 }
1130         }
1131         else {
1132                 if(key->type==KEY_RELATIVE) {
1133                         KeyBlock *kb;
1134                         
1135                         for(kb= key->block.first; kb; kb= kb->next)
1136                                 kb->weights= get_weights_array(ob, kb->vgroup);
1137
1138                         do_rel_key(0, tot, tot, (char *)out, key, actkb, 0);
1139                         
1140                         for(kb= key->block.first; kb; kb= kb->next) {
1141                                 if(kb->weights) MEM_freeN(kb->weights);
1142                                 kb->weights= NULL;
1143                         }
1144                 }
1145                 else {
1146                         ctime= bsystem_time(scene, ob, (float)scene->r.cfra, 0.0f); // xxx old cruft
1147                         
1148 #if 0 // XXX old animation system
1149                         if(calc_ipo_spec(key->ipo, KEY_SPEED, &ctime)==0) {
1150                                 ctime /= 100.0;
1151                                 CLAMP(ctime, 0.0, 1.0);
1152                         }
1153 #endif // XXX old animation system
1154                         // XXX for now... since speed curve cannot be directly ported yet
1155                         ctime /= 100.0f;
1156                         CLAMP(ctime, 0.0f, 1.0f); // XXX for compat, we use this, but this clamping was confusing
1157                         
1158                         flag= setkeys(ctime, &key->block, k, t, 0);
1159
1160                         if(flag==0)
1161                                 do_key(0, tot, tot, (char *)out, key, actkb, k, t, 0);
1162                         else
1163                                 cp_key(0, tot, tot, (char *)out, key, actkb, k[2], NULL, 0);
1164                 }
1165         }
1166 }
1167
1168 static void do_cu_key(Curve *cu, Key *key, KeyBlock *actkb, KeyBlock **k, float *t, char *out, int tot)
1169 {
1170         Nurb *nu;
1171         char *poin;
1172         int a, step;
1173         
1174         for(a=0, nu=cu->nurb.first; nu; nu=nu->next, a+=step) {
1175                 if(nu->bp) {
1176                         step= nu->pntsu*nu->pntsv;
1177                         poin= out - a*sizeof(float)*4;
1178                         do_key(a, a+step, tot, poin, key, actkb, k, t, KEY_BPOINT);
1179                 }
1180                 else if(nu->bezt) {
1181                         step= 3*nu->pntsu;
1182                         poin= out - a*sizeof(float)*10;
1183                         do_key(a, a+step, tot, poin, key, actkb, k, t, KEY_BEZTRIPLE);
1184                 }
1185                 else
1186                         step= 0;
1187         }
1188 }
1189
1190 static void do_rel_cu_key(Curve *cu, Key *key, KeyBlock *actkb, float ctime, char *out, int tot)
1191 {
1192         Nurb *nu;
1193         char *poin;
1194         int a, step;
1195         
1196         for(a=0, nu=cu->nurb.first; nu; nu=nu->next, a+=step) {
1197                 if(nu->bp) {
1198                         step= nu->pntsu*nu->pntsv;
1199                         poin= out - a*sizeof(float)*3;
1200                         do_rel_key(a, a+step, tot, out, key, actkb, KEY_BPOINT);
1201                 }
1202                 else if(nu->bezt) {
1203                         step= 3*nu->pntsu;
1204                         poin= out - a*sizeof(float)*10;
1205                         do_rel_key(a, a+step, tot, poin, key, actkb, KEY_BEZTRIPLE);
1206                 }
1207                 else
1208                         step= 0;
1209         }
1210 }
1211
1212 static void do_curve_key(Scene *scene, Object *ob, Key *key, char *out, int tot)
1213 {
1214         Curve *cu= ob->data;
1215         KeyBlock *k[4], *actkb= ob_get_keyblock(ob);
1216         float cfra, ctime, t[4], delta;
1217         int a, flag = 0, step = 0;
1218         
1219         if(key->slurph) {
1220                 delta= key->slurph;
1221                 delta/= tot;
1222                 
1223                 step= 1;
1224                 if(tot>100 && slurph_opt) {
1225                         step= tot/50;
1226                         delta*= step;
1227                         /* in do_key and cp_key the case a>tot has been handled */
1228                 }
1229                 
1230                 cfra= (float)scene->r.cfra;
1231                 
1232                 for(a=0; a<tot; a+=step, cfra+= delta) {
1233                         ctime= bsystem_time(scene, 0, cfra, 0.0f); // XXX old cruft
1234 #if 0 // XXX old animation system
1235                         if(calc_ipo_spec(key->ipo, KEY_SPEED, &ctime)==0) {
1236                                 ctime /= 100.0;
1237                                 CLAMP(ctime, 0.0, 1.0);
1238                         }
1239 #endif // XXX old animation system
1240                 
1241                         flag= setkeys(ctime, &key->block, k, t, 0);
1242
1243                         if(flag==0)
1244                                 ; /* do_key(a, a+step, tot, (char *)out, key, k, t, 0); */
1245                         else
1246                                 ; /* cp_key(a, a+step, tot, (char *)out, key, k[2],0); */
1247                 }
1248         }
1249         else {
1250                 
1251                 ctime= bsystem_time(scene, NULL, (float)scene->r.cfra, 0.0);
1252                 
1253                 if(key->type==KEY_RELATIVE) {
1254                         do_rel_cu_key(cu, cu->key, actkb, ctime, out, tot);
1255                 }
1256                 else {
1257 #if 0 // XXX old animation system
1258                         if(calc_ipo_spec(key->ipo, KEY_SPEED, &ctime)==0) {
1259                                 ctime /= 100.0;
1260                                 CLAMP(ctime, 0.0, 1.0);
1261                         }
1262 #endif // XXX old animation system
1263                         
1264                         flag= setkeys(ctime, &key->block, k, t, 0);
1265                         
1266                         if(flag==0) do_cu_key(cu, key, actkb, k, t, out, tot);
1267                         else cp_cu_key(cu, key, actkb, k[2], 0, tot, out, tot);
1268                 }
1269         }
1270 }
1271
1272 static void do_latt_key(Scene *scene, Object *ob, Key *key, char *out, int tot)
1273 {
1274         Lattice *lt= ob->data;
1275         KeyBlock *k[4], *actkb= ob_get_keyblock(ob);
1276         float delta, cfra, ctime, t[4];
1277         int a, flag;
1278         
1279         if(key->slurph) {
1280                 delta= key->slurph;
1281                 delta/= (float)tot;
1282                 
1283                 cfra= (float)scene->r.cfra;
1284                 
1285                 for(a=0; a<tot; a++, cfra+= delta) {
1286                         
1287                         ctime= bsystem_time(scene, 0, cfra, 0.0); // XXX old cruft
1288 #if 0 // XXX old animation system
1289                         if(calc_ipo_spec(key->ipo, KEY_SPEED, &ctime)==0) {
1290                                 ctime /= 100.0;
1291                                 CLAMP(ctime, 0.0, 1.0);
1292                         }
1293 #endif // XXX old animation system
1294                 
1295                         flag= setkeys(ctime, &key->block, k, t, 0);
1296
1297                         if(flag==0)
1298                                 do_key(a, a+1, tot, (char *)out, key, actkb, k, t, 0);
1299                         else
1300                                 cp_key(a, a+1, tot, (char *)out, key, actkb, k[2], NULL, 0);
1301                 }               
1302         }
1303         else {
1304                 if(key->type==KEY_RELATIVE) {
1305                         KeyBlock *kb;
1306                         
1307                         for(kb= key->block.first; kb; kb= kb->next)
1308                                 kb->weights= get_weights_array(ob, kb->vgroup);
1309                         
1310                         do_rel_key(0, tot, tot, (char *)out, key, actkb, 0);
1311                         
1312                         for(kb= key->block.first; kb; kb= kb->next) {
1313                                 if(kb->weights) MEM_freeN(kb->weights);
1314                                 kb->weights= NULL;
1315                         }
1316                 }
1317                 else {
1318                         ctime= bsystem_time(scene, NULL, (float)scene->r.cfra, 0.0);
1319
1320 #if 0 // XXX old animation system
1321                         if(calc_ipo_spec(key->ipo, KEY_SPEED, &ctime)==0) {
1322                                 ctime /= 100.0;
1323                                 CLAMP(ctime, 0.0, 1.0);
1324                         }
1325 #endif // XXX old animation system
1326                         
1327                         flag= setkeys(ctime, &key->block, k, t, 0);
1328
1329                         if(flag==0)
1330                                 do_key(0, tot, tot, (char *)out, key, actkb, k, t, 0);
1331                         else
1332                                 cp_key(0, tot, tot, (char *)out, key, actkb, k[2], NULL, 0);
1333                 }
1334         }
1335         
1336         if(lt->flag & LT_OUTSIDE) outside_lattice(lt);
1337 }
1338
1339 /* returns key coordinates (+ tilt) when key applied, NULL otherwise */
1340 float *do_ob_key(Scene *scene, Object *ob)
1341 {
1342         Key *key= ob_get_key(ob);
1343         KeyBlock *actkb= ob_get_keyblock(ob);
1344         char *out;
1345         int tot= 0, size= 0;
1346         
1347         if(key==NULL || key->block.first==NULL)
1348                 return NULL;
1349
1350         /* compute size of output array */
1351         if(ob->type == OB_MESH) {
1352                 Mesh *me= ob->data;
1353
1354                 tot= me->totvert;
1355                 size= tot*3*sizeof(float);
1356         }
1357         else if(ob->type == OB_LATTICE) {
1358                 Lattice *lt= ob->data;
1359
1360                 tot= lt->pntsu*lt->pntsv*lt->pntsw;
1361                 size= tot*3*sizeof(float);
1362         }
1363         else if(ELEM(ob->type, OB_CURVE, OB_SURF)) {
1364                 Curve *cu= ob->data;
1365                 Nurb *nu;
1366
1367                 for(nu=cu->nurb.first; nu; nu=nu->next) {
1368                         if(nu->bezt) {
1369                                 tot += 3*nu->pntsu;
1370                                 size += nu->pntsu*10*sizeof(float);
1371                         }
1372                         else if(nu->bp) {
1373                                 tot += nu->pntsu*nu->pntsv;
1374                                 size += nu->pntsu*nu->pntsv*10*sizeof(float);
1375                         }
1376                 }
1377         }
1378
1379         /* if nothing to interpolate, cancel */
1380         if(tot == 0 || size == 0)
1381                 return NULL;
1382         
1383         /* allocate array */
1384         out= MEM_callocN(size, "do_ob_key out");
1385
1386         /* prevent python from screwing this up? anyhoo, the from pointer could be dropped */
1387         key->from= (ID *)ob->data;
1388                 
1389         if(ob->shapeflag & OB_SHAPE_LOCK) {
1390                 /* shape locked, copy the locked shape instead of blending */
1391                 KeyBlock *kb= BLI_findlink(&key->block, ob->shapenr-1);
1392                 
1393                 if(kb && (kb->flag & KEYBLOCK_MUTE))
1394                         kb= key->refkey;
1395
1396                 if(kb==NULL) {
1397                         kb= key->block.first;
1398                         ob->shapenr= 1;
1399                 }
1400                 
1401                 if(ELEM(ob->type, OB_MESH, OB_LATTICE)) {
1402                         float *weights= get_weights_array(ob, kb->vgroup);
1403
1404                         cp_key(0, tot, tot, (char*)out, key, actkb, kb, weights, 0);
1405
1406                         if(weights) MEM_freeN(weights);
1407                 }
1408                 else if(ELEM(ob->type, OB_CURVE, OB_SURF))
1409                         cp_cu_key(ob->data, key, actkb, kb, 0, tot, out, tot);
1410         }
1411         else {
1412                 /* do shapekey local drivers */
1413                 float ctime= (float)scene->r.cfra; // XXX this needs to be checked
1414                 
1415                 BKE_animsys_evaluate_animdata(&key->id, key->adt, ctime, ADT_RECALC_DRIVERS);
1416                 
1417                 if(ob->type==OB_MESH) do_mesh_key(scene, ob, key, out, tot);
1418                 else if(ob->type==OB_LATTICE) do_latt_key(scene, ob, key, out, tot);
1419                 else if(ob->type==OB_CURVE) do_curve_key(scene, ob, key, out, tot);
1420                 else if(ob->type==OB_SURF) do_curve_key(scene, ob, key, out, tot);
1421         }
1422         
1423         return (float*)out;
1424 }
1425
1426 Key *ob_get_key(Object *ob)
1427 {
1428         if(ob==NULL) return NULL;
1429         
1430         if(ob->type==OB_MESH) {
1431                 Mesh *me= ob->data;
1432                 return me->key;
1433         }
1434         else if ELEM(ob->type, OB_CURVE, OB_SURF) {
1435                 Curve *cu= ob->data;
1436                 return cu->key;
1437         }
1438         else if(ob->type==OB_LATTICE) {
1439                 Lattice *lt= ob->data;
1440                 return lt->key;
1441         }
1442         return NULL;
1443 }
1444
1445 /* only the active keyblock */
1446 KeyBlock *ob_get_keyblock(Object *ob) 
1447 {
1448         Key *key= ob_get_key(ob);
1449         
1450         if (key) {
1451                 KeyBlock *kb= BLI_findlink(&key->block, ob->shapenr-1);
1452                 return kb;
1453         }
1454
1455         return NULL;
1456 }
1457
1458 /* get the appropriate KeyBlock given an index */
1459 KeyBlock *key_get_keyblock(Key *key, int index)
1460 {
1461         KeyBlock *kb;
1462         int i;
1463         
1464         if (key) {
1465                 kb= key->block.first;
1466                 
1467                 for (i= 1; i < key->totkey; i++) {
1468                         kb= kb->next;
1469                         
1470                         if (index==i)
1471                                 return kb;
1472                 }
1473         }
1474         
1475         return NULL;
1476 }
1477
1478 /* get the appropriate KeyBlock given a name to search for */
1479 KeyBlock *key_get_named_keyblock(Key *key, const char name[])
1480 {
1481         KeyBlock *kb;
1482         
1483         if (key && name) {
1484                 for (kb= key->block.first; kb; kb= kb->next) {
1485                         if (strcmp(name, kb->name)==0)
1486                                 return kb;
1487                 }
1488         }
1489         
1490         return NULL;
1491 }
1492
1493 /* Get RNA-Path for 'value' setting of the given ShapeKey 
1494  * NOTE: the user needs to free the returned string once they're finishe with it
1495  */
1496 char *key_get_curValue_rnaPath(Key *key, KeyBlock *kb)
1497 {
1498         PointerRNA ptr;
1499         PropertyRNA *prop;
1500         
1501         /* sanity checks */
1502         if ELEM(NULL, key, kb)
1503                 return NULL;
1504         
1505         /* create the RNA pointer */
1506         RNA_pointer_create(&key->id, &RNA_ShapeKey, kb, &ptr);
1507         /* get pointer to the property too */
1508         prop= RNA_struct_find_property(&ptr, "value");
1509         
1510         /* return the path */
1511         return RNA_path_from_ID_to_property(&ptr, prop);
1512 }