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