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