5f3d73ec34880a25df48f9d445cc1f6b33f600f7
[blender-staging.git] / source / blender / editors / object / object_shapekey.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL 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.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * Contributor(s): Blender Foundation, shapekey support
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 #include <math.h>
29 #include <string.h>
30
31 #ifndef WIN32
32 #include <unistd.h>
33 #else
34 #include <io.h>
35 #endif   
36
37 #include "MEM_guardedalloc.h"
38
39 #include "BLI_blenlib.h"
40 #include "BLI_arithb.h"
41
42 #include "DNA_action_types.h"
43 #include "DNA_curve_types.h"
44 #include "DNA_ipo_types.h"
45 #include "DNA_key_types.h"
46 #include "DNA_lattice_types.h"
47 #include "DNA_mesh_types.h"
48 #include "DNA_meshdata_types.h"
49 #include "DNA_object_types.h"
50 #include "DNA_scene_types.h"
51 #include "DNA_screen_types.h"
52 #include "DNA_space_types.h"
53 #include "DNA_userdef_types.h"
54 #include "DNA_view2d_types.h"
55
56 #include "BKE_action.h"
57 #include "BKE_anim.h"
58 #include "BKE_context.h"
59 #include "BKE_curve.h"
60 #include "BKE_depsgraph.h"
61 #include "BKE_global.h"
62 #include "BKE_ipo.h"
63 #include "BKE_key.h"
64 #include "BKE_library.h"
65 #include "BKE_main.h"
66 #include "BKE_mesh.h"
67 #include "BKE_object.h"
68 #include "BKE_utildefines.h"
69
70 #include "BLO_sys_types.h" // for intptr_t support
71
72 #include "ED_object.h"
73 #include "ED_mesh.h"
74
75 #include "RNA_access.h"
76 #include "RNA_define.h"
77
78 #include "WM_api.h"
79 #include "WM_types.h"
80
81 #include "object_intern.h"
82
83 #if 0 // XXX old animation system
84 static void default_key_ipo(Scene *scene, Key *key)
85 {
86         IpoCurve *icu;
87         BezTriple *bezt;
88         
89         key->ipo= add_ipo(scene, "KeyIpo", ID_KE);
90         
91         icu= MEM_callocN(sizeof(IpoCurve), "ipocurve");
92                         
93         icu->blocktype= ID_KE;
94         icu->adrcode= KEY_SPEED;
95         icu->flag= IPO_VISIBLE|IPO_SELECT|IPO_AUTO_HORIZ;
96         set_icu_vars(icu);
97         
98         BLI_addtail( &(key->ipo->curve), icu);
99         
100         icu->bezt= bezt= MEM_callocN(2*sizeof(BezTriple), "defaultipo");
101         icu->totvert= 2;
102         
103         bezt->hide= IPO_BEZ;
104         bezt->f1=bezt->f2= bezt->f3= SELECT;
105         bezt->h1= bezt->h2= HD_AUTO;
106         bezt++;
107         bezt->vec[1][0]= 100.0;
108         bezt->vec[1][1]= 1.0;
109         bezt->hide= IPO_BEZ;
110         bezt->f1=bezt->f2= bezt->f3= SELECT;
111         bezt->h1= bezt->h2= HD_AUTO;
112         
113         calchandles_ipocurve(icu);
114 }
115 #endif // XXX old animation system
116         
117
118 /************************* Mesh ************************/
119
120 void mesh_to_key(Mesh *me, KeyBlock *kb)
121 {
122         MVert *mvert;
123         float *fp;
124         int a;
125         
126         if(me->totvert==0) return;
127         
128         if(kb->data) MEM_freeN(kb->data);
129         
130         kb->data= MEM_callocN(me->key->elemsize*me->totvert, "kb->data");
131         kb->totelem= me->totvert;
132         
133         mvert= me->mvert;
134         fp= kb->data;
135         for(a=0; a<kb->totelem; a++, fp+=3, mvert++) {
136                 VECCOPY(fp, mvert->co);
137                 
138         }
139 }
140
141 void key_to_mesh(KeyBlock *kb, Mesh *me)
142 {
143         MVert *mvert;
144         float *fp;
145         int a, tot;
146         
147         mvert= me->mvert;
148         fp= kb->data;
149         
150         tot= MIN2(kb->totelem, me->totvert);
151         
152         for(a=0; a<tot; a++, fp+=3, mvert++) {
153                 VECCOPY(mvert->co, fp);
154         }
155 }
156
157 static KeyBlock *add_keyblock(Scene *scene, Key *key)
158 {
159         KeyBlock *kb;
160         float curpos= -0.1;
161         int tot;
162         
163         kb= key->block.last;
164         if(kb) curpos= kb->pos;
165         
166         kb= MEM_callocN(sizeof(KeyBlock), "Keyblock");
167         BLI_addtail(&key->block, kb);
168         kb->type= KEY_CARDINAL;
169         
170         tot= BLI_countlist(&key->block);
171         if(tot==1) strcpy(kb->name, "Basis");
172         else sprintf(kb->name, "Key %d", tot-1);
173         
174                 // XXX this is old anim system stuff? (i.e. the 'index' of the shapekey)
175         kb->adrcode= tot-1;
176         
177         key->totkey++;
178         if(key->totkey==1) key->refkey= kb;
179         
180         kb->slidermin= 0.0f;
181         kb->slidermax= 1.0f;
182         
183         // XXX kb->pos is the confusing old horizontal-line RVK crap in old IPO Editor...
184         if(key->type == KEY_RELATIVE) 
185                 kb->pos= curpos+0.1;
186         else {
187 #if 0 // XXX old animation system
188                 curpos= bsystem_time(scene, 0, (float)CFRA, 0.0);
189                 if(calc_ipo_spec(key->ipo, KEY_SPEED, &curpos)==0) {
190                         curpos /= 100.0;
191                 }
192                 kb->pos= curpos;
193                 
194                 sort_keys(key);
195 #endif // XXX old animation system
196         }
197         return kb;
198 }
199
200 void insert_meshkey(Scene *scene, Mesh *me, short rel)
201 {
202         Key *key;
203         KeyBlock *kb;
204
205         if(me->key==NULL) {
206                 me->key= add_key( (ID *)me);
207
208                 if(rel)
209                         me->key->type = KEY_RELATIVE;
210 //              else
211 //                      default_key_ipo(scene, me->key); // XXX old animation system
212         }
213         key= me->key;
214         
215         kb= add_keyblock(scene, key);
216         
217         mesh_to_key(me, kb);
218 }
219
220 /************************* Lattice ************************/
221
222 void latt_to_key(Lattice *lt, KeyBlock *kb)
223 {
224         BPoint *bp;
225         float *fp;
226         int a, tot;
227         
228         tot= lt->pntsu*lt->pntsv*lt->pntsw;
229         if(tot==0) return;
230         
231         if(kb->data) MEM_freeN(kb->data);
232         
233         kb->data= MEM_callocN(lt->key->elemsize*tot, "kb->data");
234         kb->totelem= tot;
235         
236         bp= lt->def;
237         fp= kb->data;
238         for(a=0; a<kb->totelem; a++, fp+=3, bp++) {
239                 VECCOPY(fp, bp->vec);
240         }
241 }
242
243 void key_to_latt(KeyBlock *kb, Lattice *lt)
244 {
245         BPoint *bp;
246         float *fp;
247         int a, tot;
248         
249         bp= lt->def;
250         fp= kb->data;
251         
252         tot= lt->pntsu*lt->pntsv*lt->pntsw;
253         tot= MIN2(kb->totelem, tot);
254         
255         for(a=0; a<tot; a++, fp+=3, bp++) {
256                 VECCOPY(bp->vec, fp);
257         }
258         
259 }
260
261 /* exported to python... hrms, should not, use object levels! (ton) */
262 void insert_lattkey(Scene *scene, Lattice *lt, short rel)
263 {
264         Key *key;
265         KeyBlock *kb;
266         
267         if(lt->key==NULL) {
268                 lt->key= add_key( (ID *)lt);
269 //              default_key_ipo(scene, lt->key); // XXX old animation system
270         }
271         key= lt->key;
272         
273         kb= add_keyblock(scene, key);
274         
275         latt_to_key(lt, kb);
276 }
277
278 /************************* Curve ************************/
279
280 void curve_to_key(Curve *cu, KeyBlock *kb, ListBase *nurb)
281 {
282         Nurb *nu;
283         BezTriple *bezt;
284         BPoint *bp;
285         float *fp;
286         int a, tot;
287         
288         /* count */
289         tot= count_curveverts(nurb);
290         if(tot==0) return;
291         
292         if(kb->data) MEM_freeN(kb->data);
293         
294         kb->data= MEM_callocN(cu->key->elemsize*tot, "kb->data");
295         kb->totelem= tot;
296         
297         nu= nurb->first;
298         fp= kb->data;
299         while(nu) {
300                 
301                 if(nu->bezt) {
302                         bezt= nu->bezt;
303                         a= nu->pntsu;
304                         while(a--) {
305                                 VECCOPY(fp, bezt->vec[0]);
306                                 fp+= 3;
307                                 VECCOPY(fp, bezt->vec[1]);
308                                 fp+= 3;
309                                 VECCOPY(fp, bezt->vec[2]);
310                                 fp+= 3;
311                                 fp[0]= bezt->alfa;
312                                 fp+= 3; /* alphas */
313                                 bezt++;
314                         }
315                 }
316                 else {
317                         bp= nu->bp;
318                         a= nu->pntsu*nu->pntsv;
319                         while(a--) {
320                                 VECCOPY(fp, bp->vec);
321                                 fp[3]= bp->alfa;
322                                 
323                                 fp+= 4;
324                                 bp++;
325                         }
326                 }
327                 nu= nu->next;
328         }
329 }
330
331 void key_to_curve(KeyBlock *kb, Curve  *cu, ListBase *nurb)
332 {
333         Nurb *nu;
334         BezTriple *bezt;
335         BPoint *bp;
336         float *fp;
337         int a, tot;
338         
339         nu= nurb->first;
340         fp= kb->data;
341         
342         tot= count_curveverts(nurb);
343
344         tot= MIN2(kb->totelem, tot);
345         
346         while(nu && tot>0) {
347                 
348                 if(nu->bezt) {
349                         bezt= nu->bezt;
350                         a= nu->pntsu;
351                         while(a-- && tot>0) {
352                                 VECCOPY(bezt->vec[0], fp);
353                                 fp+= 3;
354                                 VECCOPY(bezt->vec[1], fp);
355                                 fp+= 3;
356                                 VECCOPY(bezt->vec[2], fp);
357                                 fp+= 3;
358                                 bezt->alfa= fp[0];
359                                 fp+= 3; /* alphas */
360                         
361                                 tot-= 3;
362                                 bezt++;
363                         }
364                 }
365                 else {
366                         bp= nu->bp;
367                         a= nu->pntsu*nu->pntsv;
368                         while(a-- && tot>0) {
369                                 VECCOPY(bp->vec, fp);
370                                 bp->alfa= fp[3];
371                                 
372                                 fp+= 4;
373                                 tot--;
374                                 bp++;
375                         }
376                 }
377                 nu= nu->next;
378         }
379 }
380
381
382 void insert_curvekey(Scene *scene, Curve *cu, short rel) 
383 {
384         Key *key;
385         KeyBlock *kb;
386         ListBase *lb= (cu->editnurb)? cu->editnurb: &cu->nurb;
387         
388         if(cu->key==NULL) {
389                 cu->key= add_key( (ID *)cu);
390
391                 if(rel)
392                         cu->key->type = KEY_RELATIVE;
393 //              else
394 //                      default_key_ipo(scene, cu->key);        // XXX old animation system
395         }
396         key= cu->key;
397         
398         kb= add_keyblock(scene, key);
399         
400         curve_to_key(cu, kb, lb);
401 }
402
403 /*********************** add shape key ***********************/
404
405 static void ED_object_shape_key_add(bContext *C, Scene *scene, Object *ob)
406 {
407         Key *key;
408
409         if(ob->type==OB_MESH) insert_meshkey(scene, ob->data, 1);
410         else if ELEM(ob->type, OB_CURVE, OB_SURF) insert_curvekey(scene, ob->data, 1);
411         else if(ob->type==OB_LATTICE) insert_lattkey(scene, ob->data, 1);
412
413         key= ob_get_key(ob);
414         ob->shapenr= BLI_countlist(&key->block);
415
416         WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
417 }
418
419 /*********************** remove shape key ***********************/
420
421 static int ED_object_shape_key_remove(bContext *C, Object *ob)
422 {
423         Main *bmain= CTX_data_main(C);
424         KeyBlock *kb, *rkb;
425         Key *key;
426         //IpoCurve *icu;
427
428         key= ob_get_key(ob);
429         if(key==NULL)
430                 return 0;
431         
432         kb= BLI_findlink(&key->block, ob->shapenr-1);
433
434         if(kb) {
435                 for(rkb= key->block.first; rkb; rkb= rkb->next)
436                         if(rkb->relative == ob->shapenr-1)
437                                 rkb->relative= 0;
438
439                 BLI_remlink(&key->block, kb);
440                 key->totkey--;
441                 if(key->refkey== kb)
442                         key->refkey= key->block.first;
443                         
444                 if(kb->data) MEM_freeN(kb->data);
445                 MEM_freeN(kb);
446                 
447                 for(kb= key->block.first; kb; kb= kb->next)
448                         if(kb->adrcode>=ob->shapenr)
449                                 kb->adrcode--;
450                 
451 #if 0 // XXX old animation system
452                 if(key->ipo) {
453                         
454                         for(icu= key->ipo->curve.first; icu; icu= icu->next) {
455                                 if(icu->adrcode==ob->shapenr-1) {
456                                         BLI_remlink(&key->ipo->curve, icu);
457                                         free_ipo_curve(icu);
458                                         break;
459                                 }
460                         }
461                         for(icu= key->ipo->curve.first; icu; icu= icu->next) 
462                                 if(icu->adrcode>=ob->shapenr)
463                                         icu->adrcode--;
464                 }
465 #endif // XXX old animation system              
466                 
467                 if(ob->shapenr>1) ob->shapenr--;
468         }
469         
470         if(key->totkey==0) {
471                 if(GS(key->from->name)==ID_ME) ((Mesh *)key->from)->key= NULL;
472                 else if(GS(key->from->name)==ID_CU) ((Curve *)key->from)->key= NULL;
473                 else if(GS(key->from->name)==ID_LT) ((Lattice *)key->from)->key= NULL;
474
475                 free_libblock_us(&(bmain->key), key);
476         }
477         
478         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
479         WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
480
481         return 1;
482 }
483
484 static int ED_object_shape_key_mirror(bContext *C, Scene *scene, Object *ob)
485 {
486         KeyBlock *kb;
487         Key *key;
488
489         key= ob_get_key(ob);
490         if(key==NULL)
491                 return 0;
492         
493         kb= BLI_findlink(&key->block, ob->shapenr-1);
494
495         if(kb) {
496                 int i1, i2;
497                 float *fp1, *fp2;
498                 float tvec[3];
499                 char *tag_elem= MEM_callocN(sizeof(char) * kb->totelem, "shape_key_mirror");
500
501
502                 if(ob->type==OB_MESH) {
503                         Mesh *me= ob->data;
504                         MVert *mv;
505
506                         mesh_octree_table(ob, NULL, NULL, 's');
507
508                         for(i1=0, mv=me->mvert; i1<me->totvert; i1++, mv++) {
509                                 i2= mesh_get_x_mirror_vert(ob, i1);
510                                 if(i2==i1) {
511                                         fp1= ((float *)kb->data) + i1*3;
512                                         fp1[0] = -fp1[0];
513                                         tag_elem[i1]= 1;
514                                 }
515                                 else if(i2 != -1) {
516                                         if(tag_elem[i1]==0 && tag_elem[i2]==0) {
517                                                 fp1= ((float *)kb->data) + i1*3;
518                                                 fp2= ((float *)kb->data) + i2*3;
519
520                                                 VECCOPY(tvec,   fp1);
521                                                 VECCOPY(fp1,    fp2);
522                                                 VECCOPY(fp2,    tvec);
523
524                                                 /* flip x axis */
525                                                 fp1[0] = -fp1[0];
526                                                 fp2[0] = -fp2[0];
527                                         }
528                                         tag_elem[i1]= tag_elem[i2]= 1;
529                                 }
530                         }
531
532                         mesh_octree_table(ob, NULL, NULL, 'e');
533                 }
534                 /* todo, other types? */
535
536                 MEM_freeN(tag_elem);
537         }
538         
539         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
540         WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
541
542         return 1;
543 }
544
545 /********************** shape key operators *********************/
546
547 static int shape_key_poll(bContext *C)
548 {
549         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
550         ID *data= (ob)? ob->data: NULL;
551         return (ob && !ob->id.lib && data && !data->lib);
552 }
553
554 static int shape_key_add_exec(bContext *C, wmOperator *op)
555 {
556         Scene *scene= CTX_data_scene(C);
557         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
558
559         ED_object_shape_key_add(C, scene, ob);
560         
561         return OPERATOR_FINISHED;
562 }
563
564 void OBJECT_OT_shape_key_add(wmOperatorType *ot)
565 {
566         /* identifiers */
567         ot->name= "Add Shape Key";
568         ot->name= "Add shape key to the object.";
569         ot->idname= "OBJECT_OT_shape_key_add";
570         
571         /* api callbacks */
572         ot->poll= shape_key_poll;
573         ot->exec= shape_key_add_exec;
574
575         /* flags */
576         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
577 }
578
579 static int shape_key_remove_exec(bContext *C, wmOperator *op)
580 {
581         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
582
583         if(!ED_object_shape_key_remove(C, ob))
584                 return OPERATOR_CANCELLED;
585         
586         return OPERATOR_FINISHED;
587 }
588
589 void OBJECT_OT_shape_key_remove(wmOperatorType *ot)
590 {
591         /* identifiers */
592         ot->name= "Remove Shape Key";
593         ot->name= "Remove shape key from the object.";
594         ot->idname= "OBJECT_OT_shape_key_remove";
595         
596         /* api callbacks */
597         ot->poll= shape_key_poll;
598         ot->exec= shape_key_remove_exec;
599
600         /* flags */
601         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
602 }
603
604 static int shape_key_clear_exec(bContext *C, wmOperator *op)
605 {
606         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
607         Key *key= ob_get_key(ob);
608         KeyBlock *kb= ob_get_keyblock(ob);
609
610         if(!key || !kb)
611                 return OPERATOR_CANCELLED;
612         
613         for(kb=key->block.first; kb; kb=kb->next)
614                 kb->curval= 0.0f;
615
616         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
617         WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
618         
619         return OPERATOR_FINISHED;
620 }
621
622 void OBJECT_OT_shape_key_clear(wmOperatorType *ot)
623 {
624         /* identifiers */
625         ot->name= "Clear Shape Keys";
626         ot->description= "Clear weights for all shape keys.";
627         ot->idname= "OBJECT_OT_shape_key_clear";
628         
629         /* api callbacks */
630         ot->poll= shape_key_poll;
631         ot->exec= shape_key_clear_exec;
632
633         /* flags */
634         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
635 }
636
637 static int shape_key_mirror_exec(bContext *C, wmOperator *op)
638 {
639         Scene *scene= CTX_data_scene(C);
640         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
641
642         if(!ED_object_shape_key_mirror(C, scene, ob))
643                 return OPERATOR_CANCELLED;
644
645         return OPERATOR_FINISHED;
646 }
647
648 void OBJECT_OT_shape_key_mirror(wmOperatorType *ot)
649 {
650         /* identifiers */
651         ot->name= "Mirror Shape Key";
652         ot->idname= "OBJECT_OT_shape_key_mirror";
653
654         /* api callbacks */
655         ot->poll= shape_key_poll;
656         ot->exec= shape_key_mirror_exec;
657
658         /* flags */
659         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
660 }
661
662
663 static int shape_key_move_exec(bContext *C, wmOperator *op)
664 {
665         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
666
667         int type= RNA_enum_get(op->ptr, "type");
668         Key *key= ob_get_key(ob);
669
670         if(key) {
671                 KeyBlock *kb, *kb_other;
672                 kb= BLI_findlink(&key->block, ob->shapenr-1);
673
674                 if(type==-1) {
675                         /* move back */
676                         if(kb->prev) {
677                                 kb_other= kb->prev;
678                                 BLI_remlink(&key->block, kb);
679                                 BLI_insertlinkbefore(&key->block, kb_other, kb);
680                                 ob->shapenr--;
681                         }
682                 }
683                 else {
684                         /* move next */
685                         if(kb->next) {
686                                 kb_other= kb->next;
687                                 BLI_remlink(&key->block, kb);
688                                 BLI_insertlinkafter(&key->block, kb_other, kb);
689                                 ob->shapenr++;
690                         }
691                 }
692         }
693
694         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
695         WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
696
697         return OPERATOR_FINISHED;
698 }
699
700 void OBJECT_OT_shape_key_move(wmOperatorType *ot)
701 {
702         static EnumPropertyItem slot_move[] = {
703                 {-1, "UP", 0, "Up", ""},
704                 {1, "DOWN", 0, "Down", ""},
705                 {0, NULL, 0, NULL, NULL}
706         };
707
708         /* identifiers */
709         ot->name= "Move Shape Key";
710         ot->idname= "OBJECT_OT_shape_key_move";
711
712         /* api callbacks */
713         ot->poll= shape_key_poll;
714         ot->exec= shape_key_move_exec;
715
716         /* flags */
717         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
718
719         RNA_def_enum(ot->srna, "type", slot_move, 0, "Type", "");
720 }
721