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