0d8b04339c1fa578bf20d9ca176829d1bc172531
[blender.git] / source / blender / src / editkey.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
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/BL DUAL LICENSE BLOCK *****
31  */
32
33 #include <math.h>
34
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
38
39 #ifndef WIN32
40 #include <unistd.h>
41 #else
42 #include <io.h>
43 #include "BLI_winstuff.h"
44 #endif   
45 #include "MEM_guardedalloc.h"
46
47 #include "BLI_blenlib.h"
48 #include "BLI_arithb.h"
49 #include "BLI_editVert.h"
50
51 #include "DNA_curve_types.h"
52 #include "DNA_ipo_types.h"
53 #include "DNA_key_types.h"
54 #include "DNA_mesh_types.h"
55 #include "DNA_object_types.h"
56 #include "DNA_screen_types.h"
57 #include "DNA_space_types.h"
58 #include "DNA_userdef_types.h"
59 #include "DNA_view2d_types.h"
60 #include "DNA_lattice_types.h"
61 #include "DNA_scene_types.h"
62
63 #include "BKE_utildefines.h"
64 #include "BKE_anim.h"
65 #include "BKE_curve.h"
66 #include "BKE_global.h"
67 #include "BKE_ipo.h"
68 #include "BKE_key.h"
69 #include "BKE_library.h"
70 #include "BKE_main.h"
71 #include "BKE_object.h"
72
73 #include "BIF_editkey.h"
74 #include "BIF_editview.h"
75 #include "BIF_mywindow.h"
76 #include "BIF_screen.h"
77 #include "BIF_space.h"
78 #include "BIF_toolbox.h"
79
80 #include "BSE_editipo.h"
81 #include "BSE_trans_types.h"
82
83 #include "BDR_editobject.h"
84
85 #include "blendef.h"
86 #include "mydevice.h"
87 #include "ipo.h"
88
89 extern ListBase editNurb; /* in editcurve.c */
90
91 static void default_key_ipo(Key *key)
92 {
93         IpoCurve *icu;
94         BezTriple *bezt;
95         
96         key->ipo= add_ipo("KeyIpo", ID_KE);
97         
98         icu= MEM_callocN(sizeof(IpoCurve), "ipocurve");
99                         
100         icu->blocktype= ID_KE;
101         icu->adrcode= KEY_SPEED;
102         icu->flag= IPO_VISIBLE+IPO_SELECT;
103         set_icu_vars(icu);
104         
105         BLI_addtail( &(key->ipo->curve), icu);
106         
107         icu->bezt= bezt= MEM_callocN(2*sizeof(BezTriple), "defaultipo");
108         icu->totvert= 2;
109         
110         bezt->hide= IPO_BEZ;
111         bezt->f1=bezt->f2= bezt->f3= SELECT;
112         bezt->h1= bezt->h2= HD_AUTO;
113         bezt++;
114         bezt->vec[1][0]= 100.0;
115         bezt->vec[1][1]= 1.0;
116         bezt->hide= IPO_BEZ;
117         bezt->f1=bezt->f2= bezt->f3= SELECT;
118         bezt->h1= bezt->h2= HD_AUTO;
119         
120         calchandles_ipocurve(icu);
121 }
122
123         
124
125 /* **************************************** */
126
127 void mesh_to_key(Mesh *me, KeyBlock *kb)
128 {
129         MVert *mvert;
130         float *fp;
131         int a;
132         
133         if(me->totvert==0) return;
134         
135         if(kb->data) MEM_freeN(kb->data);
136         
137         kb->data= MEM_callocN(me->key->elemsize*me->totvert, "kb->data");
138         kb->totelem= me->totvert;
139         
140         mvert= me->mvert;
141         fp= kb->data;
142         for(a=0; a<kb->totelem; a++, fp+=3, mvert++) {
143                 VECCOPY(fp, mvert->co);
144                 
145         }
146 }
147
148 void key_to_mesh(KeyBlock *kb, Mesh *me)
149 {
150         MVert *mvert;
151         float *fp;
152         int a, tot;
153         
154         mvert= me->mvert;
155         fp= kb->data;
156         
157         tot= MIN2(kb->totelem, me->totvert);
158         
159         for(a=0; a<tot; a++, fp+=3, mvert++) {
160                 VECCOPY(mvert->co, fp);
161         }
162 }
163
164
165
166 void insert_meshkey(Mesh *me)
167 {
168         Key *key;
169         KeyBlock *kb, *kkb;
170         float curpos;
171         
172         if(me->key==0) {
173                 me->key= add_key( (ID *)me);
174                 default_key_ipo(me->key);
175         }
176         key= me->key;
177         
178         kb= MEM_callocN(sizeof(KeyBlock), "Keyblock");
179         BLI_addtail(&key->block, kb);
180         kb->type= KEY_CARDINAL;
181         
182         curpos= bsystem_time(0, 0, (float)CFRA, 0.0);
183         if(calc_ipo_spec(me->key->ipo, KEY_SPEED, &curpos)==0) {
184                 curpos /= 100.0;
185         }
186         kb->pos= curpos;
187         
188         key->totkey++;
189         if(key->totkey==1) key->refkey= kb;
190         
191         mesh_to_key(me, kb);
192         
193         sort_keys(me->key);
194
195         /* curent active: */
196         kkb= key->block.first;
197         while(kkb) {
198                 kkb->flag &= ~SELECT;
199                 if(kkb==kb) kkb->flag |= SELECT;
200                 
201                 kkb= kkb->next;
202         }
203 }
204
205 /* ******************** */
206
207 void latt_to_key(Lattice *lt, KeyBlock *kb)
208 {
209         BPoint *bp;
210         float *fp;
211         int a, tot;
212         
213         tot= lt->pntsu*lt->pntsv*lt->pntsw;
214         if(tot==0) return;
215         
216         if(kb->data) MEM_freeN(kb->data);
217         
218         kb->data= MEM_callocN(lt->key->elemsize*tot, "kb->data");
219         kb->totelem= tot;
220         
221         bp= lt->def;
222         fp= kb->data;
223         for(a=0; a<kb->totelem; a++, fp+=3, bp++) {
224                 VECCOPY(fp, bp->vec);
225         }
226 }
227
228 void key_to_latt(KeyBlock *kb, Lattice *lt)
229 {
230         BPoint *bp;
231         float *fp;
232         int a, tot;
233         
234         bp= lt->def;
235         fp= kb->data;
236         
237         tot= lt->pntsu*lt->pntsv*lt->pntsw;
238         tot= MIN2(kb->totelem, tot);
239         
240         for(a=0; a<tot; a++, fp+=3, bp++) {
241                 VECCOPY(bp->vec, fp);
242         }
243         
244 }
245
246 void insert_lattkey(Lattice *lt)
247 {
248         Key *key;
249         KeyBlock *kb, *kkb;
250         float curpos;
251         
252         if(lt->key==0) {
253                 lt->key= add_key( (ID *)lt);
254                 default_key_ipo(lt->key);
255         }
256         key= lt->key;
257         
258         kb= MEM_callocN(sizeof(KeyBlock), "Keyblock");
259         BLI_addtail(&key->block, kb);
260         kb->type= KEY_CARDINAL;
261         
262         curpos= bsystem_time(0, 0, (float)CFRA, 0.0);
263         if(calc_ipo_spec(lt->key->ipo, KEY_SPEED, &curpos)==0) {
264                 curpos /= 100.0;
265         }
266         kb->pos= curpos;
267         
268         key->totkey++;
269         if(key->totkey==1) key->refkey= kb;
270         
271         latt_to_key(lt, kb);
272         
273         sort_keys(lt->key);
274
275         /* curent active: */
276         kkb= key->block.first;
277         while(kkb) {
278                 kkb->flag &= ~SELECT;
279                 if(kkb==kb) kkb->flag |= SELECT;
280                 
281                 kkb= kkb->next;
282         }
283 }
284
285 /* ******************************** */
286
287 void curve_to_key(Curve *cu, KeyBlock *kb, ListBase *nurb)
288 {
289         Nurb *nu;
290         BezTriple *bezt;
291         BPoint *bp;
292         float *fp;
293         int a, tot;
294         
295         /* count */
296         tot= count_curveverts(nurb);
297         if(tot==0) return;
298         
299         if(kb->data) MEM_freeN(kb->data);
300         
301         kb->data= MEM_callocN(cu->key->elemsize*tot, "kb->data");
302         kb->totelem= tot;
303         
304         nu= nurb->first;
305         fp= kb->data;
306         while(nu) {
307                 
308                 if(nu->bezt) {
309                         bezt= nu->bezt;
310                         a= nu->pntsu;
311                         while(a--) {
312                                 VECCOPY(fp, bezt->vec[0]);
313                                 fp+= 3;
314                                 VECCOPY(fp, bezt->vec[1]);
315                                 fp+= 3;
316                                 VECCOPY(fp, bezt->vec[2]);
317                                 fp+= 3;
318                                 fp+= 3; /* alphas */
319                                 bezt++;
320                         }
321                 }
322                 else {
323                         bp= nu->bp;
324                         a= nu->pntsu*nu->pntsv;
325                         while(a--) {
326                                 VECCOPY(fp, bp->vec);
327                                 fp[3]= bp->alfa;
328                                 
329                                 fp+= 4;
330                                 bp++;
331                         }
332                 }
333                 nu= nu->next;
334         }
335 }
336
337 void key_to_curve(KeyBlock *kb, Curve  *cu, ListBase *nurb)
338 {
339         Nurb *nu;
340         BezTriple *bezt;
341         BPoint *bp;
342         float *fp;
343         int a, tot;
344         
345         nu= nurb->first;
346         fp= kb->data;
347         
348         tot= count_curveverts(nurb);
349
350         tot= MIN2(kb->totelem, tot);
351         
352         while(nu && tot>0) {
353                 
354                 if(nu->bezt) {
355                         bezt= nu->bezt;
356                         a= nu->pntsu;
357                         while(a-- && tot>0) {
358                                 VECCOPY(bezt->vec[0], fp);
359                                 fp+= 3;
360                                 VECCOPY(bezt->vec[1], fp);
361                                 fp+= 3;
362                                 VECCOPY(bezt->vec[2], fp);
363                                 fp+= 3;
364                                 fp+= 3; /* alphas */
365                                 
366                                 tot-= 3;
367                                 bezt++;
368                         }
369                 }
370                 else {
371                         bp= nu->bp;
372                         a= nu->pntsu*nu->pntsv;
373                         while(a-- && tot>0) {
374                                 VECCOPY(bp->vec, fp);
375                                 bp->alfa= fp[3];
376                                 
377                                 fp+= 4;
378                                 tot--;
379                                 bp++;
380                         }
381                 }
382                 nu= nu->next;
383         }
384 }
385
386
387
388 void insert_curvekey(Curve *cu)
389 {
390         Key *key;
391         KeyBlock *kb, *kkb;
392         float curpos;
393         
394         if(cu->key==0) {
395                 cu->key= add_key( (ID *)cu);
396                 default_key_ipo(cu->key);
397         }
398         key= cu->key;
399         
400         kb= MEM_callocN(sizeof(KeyBlock), "Keyblock");
401         BLI_addtail(&key->block, kb);
402         kb->type= KEY_CARDINAL;
403         
404         curpos= bsystem_time(0, 0, (float)CFRA, 0.0);
405         if(calc_ipo_spec(cu->key->ipo, KEY_SPEED, &curpos)==0) {
406                 curpos /= 100.0;
407         }
408         kb->pos= curpos;
409         
410         key->totkey++;
411         if(key->totkey==1) key->refkey= kb;
412         
413         if(editNurb.first) curve_to_key(cu, kb, &editNurb);
414         else curve_to_key(cu, kb, &cu->nurb);
415         
416         sort_keys(cu->key);
417
418         /* curent active: */
419         kkb= key->block.first;
420         while(kkb) {
421                 kkb->flag &= ~SELECT;
422                 if(kkb==kb) kkb->flag |= SELECT;
423                 
424                 kkb= kkb->next;
425         }
426 }
427
428
429 /* ******************** */
430
431 Key *give_current_key(Object *ob)
432 {
433         Mesh *me;
434         Curve *cu;
435         Lattice *lt;
436         
437         if(ob->type==OB_MESH) {
438                 me= ob->data;
439                 return me->key;
440         }
441         else if ELEM(ob->type, OB_CURVE, OB_SURF) {
442                 cu= ob->data;
443                 return cu->key;
444         }
445         else if(ob->type==OB_LATTICE) {
446                 lt= ob->data;
447                 return lt->key;
448         }
449         return 0;
450 }
451
452 void showkeypos(Key *key, KeyBlock *kb)
453 {
454         Object *ob;
455         Mesh *me;
456         Lattice *lt;
457         Curve *cu;
458         int tot;
459         
460         /* from ipo */
461         ob= OBACT;
462         if(ob==0) return;
463         
464         if(key == give_current_key(ob)) {
465                 
466                 if(ob->type==OB_MESH) {
467                         me= ob->data;
468
469                         cp_key(0, me->totvert, me->totvert, (char *)me->mvert->co, me->key, kb, 0);
470
471                         make_displists_by_obdata(me);
472                 }
473                 else if(ob->type==OB_LATTICE) {
474                         lt= ob->data;
475                         tot= lt->pntsu*lt->pntsv*lt->pntsw;
476                         
477                         cp_key(0, tot, tot, (char *)lt->def->vec, lt->key, kb, 0);
478
479                         make_displists_by_parent(ob);
480                 }
481                 else if ELEM(ob->type, OB_CURVE, OB_SURF) {
482                         cu= ob->data;
483                         tot= count_curveverts(&cu->nurb);
484                         cp_cu_key(cu, kb, 0, tot);
485
486                         make_displists_by_obdata(cu);
487                 }
488                 
489                 allqueue(REDRAWVIEW3D, 0);
490         }
491 }
492
493 void deselectall_key(void)
494 {
495         KeyBlock *kb;
496         Key *key;
497         
498         if(G.sipo->blocktype!=ID_KE) return;
499         key= (Key *)G.sipo->from;
500         if(key==0) return;
501         
502         kb= key->block.first;
503         while(kb) {
504                 kb->flag &= ~SELECT;
505                 kb= kb->next;
506         }
507 }
508
509
510 void delete_key(void)
511 {
512         KeyBlock *kb, *kbn;
513         Key *key;
514         
515         if(G.sipo->blocktype!=ID_KE) return;
516
517         if(okee("Erase selected keys")==0) return;
518         
519         key= (Key *)G.sipo->from;
520         if(key==0) return;
521         
522         kb= key->block.first;
523         while(kb) {
524                 kbn= kb->next;
525                 if(kb->flag & SELECT) {
526                         BLI_remlink(&key->block, kb);
527                         key->totkey--;
528                         if(key->refkey== kb) key->refkey= key->block.first;
529                         
530                         if(kb->data) MEM_freeN(kb->data);
531                         MEM_freeN(kb);
532                         
533                 }
534                 kb= kbn;
535         }
536         
537         if(key->totkey==0) {
538                 if(GS(key->from->name)==ID_ME) ((Mesh *)key->from)->key= 0;
539                 else if(GS(key->from->name)==ID_CU) ((Curve *)key->from)->key= 0;
540                 else if(GS(key->from->name)==ID_LT) ((Lattice *)key->from)->key= 0;
541
542                 free_libblock_us(&(G.main->key), key);
543                 scrarea_queue_headredraw(curarea);      /* ipo remove too */
544         }
545         else do_spec_key(key);
546         
547         allqueue(REDRAWVIEW3D, 0);
548         scrarea_queue_winredraw(curarea);
549 }
550
551 void move_keys(void)
552 {
553         Key *key;
554         KeyBlock *kb;
555         TransVert *transmain, *tv;
556         float div, dy, vec[3], dvec[3];
557         int a, tot=0, afbreek=0, firsttime= 1;
558         unsigned short event = 0;
559         short mval[2], val, xo, yo;
560         char str[32];
561         
562         if(G.sipo->blocktype!=ID_KE) return;
563         
564         if(G.sipo->ipo && G.sipo->ipo->id.lib) return;
565         if(G.sipo->editipo==0) return;
566
567         key= (Key *)G.sipo->from;
568         if(key==0) return;
569         
570         /* which keys are involved */
571         kb= key->block.first;
572         while(kb) {
573                 if(kb->flag & SELECT) tot++;
574                 kb= kb->next;
575         }
576         
577         if(tot==0) return;      
578         
579         tv=transmain= MEM_callocN(tot*sizeof(TransVert), "transmain");
580         kb= key->block.first;
581         while(kb) {
582                 if(kb->flag & SELECT) {
583                         tv->loc= &kb->pos;
584                         tv->oldloc[0]= kb->pos;
585                         tv++;
586                 }
587                 kb= kb->next;
588         }
589         
590         getmouseco_areawin(mval);
591         xo= mval[0];
592         yo= mval[1];
593         dvec[0]=dvec[1]=dvec[2]= 0.0; 
594         
595
596         while(afbreek==0) {
597                 getmouseco_areawin(mval);
598                 if(mval[0]!=xo || mval[1]!=yo || firsttime) {
599                         firsttime= 0;
600                         
601                         dy= (float)(mval[1]- yo);
602
603                         div= (float)(G.v2d->mask.ymax-G.v2d->mask.ymin);
604                         dvec[1]+= (G.v2d->cur.ymax-G.v2d->cur.ymin)*(dy)/div;
605                         
606                         VECCOPY(vec, dvec);
607
608                         apply_keyb_grid(vec, 0.0, 1.0, 0.1, U.flag & AUTOGRABGRID);
609                         apply_keyb_grid(vec+1, 0.0, 1.0, 0.1, U.flag & AUTOGRABGRID);
610
611                         tv= transmain;
612                         for(a=0; a<tot; a++, tv++) {
613                                 tv->loc[0]= tv->oldloc[0]+vec[1];
614                         }
615                         
616                         sprintf(str, "Y: %.3f  ", vec[1]);
617                         headerprint(str);
618                         
619                         xo= mval[0];
620                         yo= mval[1];
621                                 
622                         force_draw();
623                 }
624                 else BIF_wait_for_statechange();
625                 
626                 while(qtest()) {
627                         event= extern_qread(&val);
628                         if(val) {
629                                 switch(event) {
630                                 case ESCKEY:
631                                 case LEFTMOUSE:
632                                 case SPACEKEY:
633                                         afbreek= 1;
634                                         break;
635                                 default:
636                                         arrows_move_cursor(event);
637                                 }
638                         }
639                 }
640         }
641         
642         if(event==ESCKEY) {
643                 tv= transmain;
644                 for(a=0; a<tot; a++, tv++) {
645                         tv->loc[0]= tv->oldloc[0];
646                 }
647         }
648         
649         sort_keys(key);
650         do_spec_key(key);
651         
652         /* for boundbox */
653         editipo_changed(G.sipo, 0);
654
655         MEM_freeN(transmain);   
656         allqueue(REDRAWVIEW3D, 0);
657         scrarea_queue_redraw(curarea);
658 }