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