merge with/from trunk at r35190
[blender.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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_math.h"
41 #include "BLI_utildefines.h"
42
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_scene_types.h"
49 #include "DNA_object_types.h"
50
51 #include "BKE_context.h"
52 #include "BKE_depsgraph.h"
53 #include "BKE_key.h"
54 #include "BKE_library.h"
55 #include "BKE_main.h"
56 #include "BKE_object.h"
57 #include "BKE_curve.h"
58
59 #include "BLO_sys_types.h" // for intptr_t support
60
61 #include "ED_mesh.h"
62
63 #include "RNA_access.h"
64 #include "RNA_define.h"
65
66 #include "WM_api.h"
67 #include "WM_types.h"
68
69 #include "object_intern.h"
70
71 /*********************** add shape key ***********************/
72
73 static void ED_object_shape_key_add(bContext *C, Scene *scene, Object *ob, int from_mix)
74 {
75         if(object_insert_shape_key(scene, ob, NULL, from_mix)) {
76                 Key *key= ob_get_key(ob);
77                 ob->shapenr= BLI_countlist(&key->block);
78
79                 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
80         }
81 }
82
83 /*********************** remove shape key ***********************/
84
85 static int ED_object_shape_key_remove(bContext *C, Object *ob)
86 {
87         Main *bmain= CTX_data_main(C);
88         KeyBlock *kb, *rkb;
89         Key *key;
90         //IpoCurve *icu;
91
92         key= ob_get_key(ob);
93         if(key==NULL)
94                 return 0;
95         
96         kb= BLI_findlink(&key->block, ob->shapenr-1);
97
98         if(kb) {
99                 for(rkb= key->block.first; rkb; rkb= rkb->next)
100                         if(rkb->relative == ob->shapenr-1)
101                                 rkb->relative= 0;
102
103                 BLI_remlink(&key->block, kb);
104                 key->totkey--;
105                 if(key->refkey== kb) {
106                         key->refkey= key->block.first;
107
108                         if(key->refkey) {
109                                 /* apply new basis key on original data */
110                                 switch(ob->type) {
111                                         case OB_MESH:
112                                                 key_to_mesh(key->refkey, ob->data);
113                                                 break;
114                                         case OB_CURVE:
115                                         case OB_SURF:
116                                                 key_to_curve(key->refkey, ob->data, BKE_curve_nurbs(ob->data));
117                                                 break;
118                                         case OB_LATTICE:
119                                                 key_to_latt(key->refkey, ob->data);
120                                                 break;
121                                 }
122                         }
123                 }
124                         
125                 if(kb->data) MEM_freeN(kb->data);
126                 MEM_freeN(kb);
127                 
128                 for(kb= key->block.first; kb; kb= kb->next)
129                         if(kb->adrcode>=ob->shapenr)
130                                 kb->adrcode--;
131                 
132 #if 0 // XXX old animation system
133                 if(key->ipo) {
134                         
135                         for(icu= key->ipo->curve.first; icu; icu= icu->next) {
136                                 if(icu->adrcode==ob->shapenr-1) {
137                                         BLI_remlink(&key->ipo->curve, icu);
138                                         free_ipo_curve(icu);
139                                         break;
140                                 }
141                         }
142                         for(icu= key->ipo->curve.first; icu; icu= icu->next) 
143                                 if(icu->adrcode>=ob->shapenr)
144                                         icu->adrcode--;
145                 }
146 #endif // XXX old animation system              
147                 
148                 if(ob->shapenr>1) ob->shapenr--;
149         }
150         
151         if(key->totkey==0) {
152                 if(GS(key->from->name)==ID_ME) ((Mesh *)key->from)->key= NULL;
153                 else if(GS(key->from->name)==ID_CU) ((Curve *)key->from)->key= NULL;
154                 else if(GS(key->from->name)==ID_LT) ((Lattice *)key->from)->key= NULL;
155
156                 free_libblock_us(&(bmain->key), key);
157         }
158         
159         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
160         WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
161
162         return 1;
163 }
164
165 static int object_shape_key_mirror(bContext *C, Object *ob)
166 {
167         KeyBlock *kb;
168         Key *key;
169
170         key= ob_get_key(ob);
171         if(key==NULL)
172                 return 0;
173         
174         kb= BLI_findlink(&key->block, ob->shapenr-1);
175
176         if(kb) {
177                 int i1, i2;
178                 float *fp1, *fp2;
179                 float tvec[3];
180                 char *tag_elem= MEM_callocN(sizeof(char) * kb->totelem, "shape_key_mirror");
181
182
183                 if(ob->type==OB_MESH) {
184                         Mesh *me= ob->data;
185                         MVert *mv;
186
187                         //BMESH_TODO mesh_octree_table(ob, NULL, NULL, 's');
188
189                         for(i1=0, mv=me->mvert; i1<me->totvert; i1++, mv++) {
190                                 i2= -1; //BMESH_TODO mesh_get_x_mirror_vert(ob, i1);
191                                 if(i2==i1) {
192                                         fp1= ((float *)kb->data) + i1*3;
193                                         fp1[0] = -fp1[0];
194                                         tag_elem[i1]= 1;
195                                 }
196                                 else if(i2 != -1) {
197                                         if(tag_elem[i1]==0 && tag_elem[i2]==0) {
198                                                 fp1= ((float *)kb->data) + i1*3;
199                                                 fp2= ((float *)kb->data) + i2*3;
200
201                                                 VECCOPY(tvec,   fp1);
202                                                 VECCOPY(fp1,    fp2);
203                                                 VECCOPY(fp2,    tvec);
204
205                                                 /* flip x axis */
206                                                 fp1[0] = -fp1[0];
207                                                 fp2[0] = -fp2[0];
208                                         }
209                                         tag_elem[i1]= tag_elem[i2]= 1;
210                                 }
211                         }
212
213                         //BMESH_TODO mesh_octree_table(ob, NULL, NULL, 'e');
214                 }
215                 /* todo, other types? */
216
217                 MEM_freeN(tag_elem);
218         }
219         
220         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
221         WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
222
223         return 1;
224 }
225
226 /********************** shape key operators *********************/
227
228 static int shape_key_mode_poll(bContext *C)
229 {
230         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
231         ID *data= (ob)? ob->data: NULL;
232         return (ob && !ob->id.lib && data && !data->lib && ob->mode != OB_MODE_EDIT);
233 }
234
235 static int shape_key_poll(bContext *C)
236 {
237         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
238         ID *data= (ob)? ob->data: NULL;
239         return (ob && !ob->id.lib && data && !data->lib);
240 }
241
242 static int shape_key_add_exec(bContext *C, wmOperator *op)
243 {
244         Scene *scene= CTX_data_scene(C);
245         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
246         int from_mix = RNA_boolean_get(op->ptr, "from_mix");
247
248         ED_object_shape_key_add(C, scene, ob, from_mix);
249
250         return OPERATOR_FINISHED;
251 }
252
253 void OBJECT_OT_shape_key_add(wmOperatorType *ot)
254 {
255         /* identifiers */
256         ot->name= "Add Shape Key";
257         ot->idname= "OBJECT_OT_shape_key_add";
258         ot->description= "Add shape key to the object";
259         
260         /* api callbacks */
261         ot->poll= shape_key_mode_poll;
262         ot->exec= shape_key_add_exec;
263
264         /* flags */
265         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
266
267         /* properties */
268         RNA_def_boolean(ot->srna, "from_mix", 1, "From Mix", "Create the new shape key from the existing mix of keys.");
269 }
270
271 static int shape_key_remove_exec(bContext *C, wmOperator *UNUSED(op))
272 {
273         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
274
275         if(!ED_object_shape_key_remove(C, ob))
276                 return OPERATOR_CANCELLED;
277         
278         return OPERATOR_FINISHED;
279 }
280
281 void OBJECT_OT_shape_key_remove(wmOperatorType *ot)
282 {
283         /* identifiers */
284         ot->name= "Remove Shape Key";
285         ot->idname= "OBJECT_OT_shape_key_remove";
286         ot->description= "Remove shape key from the object";
287         
288         /* api callbacks */
289         ot->poll= shape_key_mode_poll;
290         ot->exec= shape_key_remove_exec;
291
292         /* flags */
293         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
294 }
295
296 static int shape_key_clear_exec(bContext *C, wmOperator *UNUSED(op))
297 {
298         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
299         Key *key= ob_get_key(ob);
300         KeyBlock *kb= ob_get_keyblock(ob);
301
302         if(!key || !kb)
303                 return OPERATOR_CANCELLED;
304         
305         for(kb=key->block.first; kb; kb=kb->next)
306                 kb->curval= 0.0f;
307
308         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
309         WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
310         
311         return OPERATOR_FINISHED;
312 }
313
314 void OBJECT_OT_shape_key_clear(wmOperatorType *ot)
315 {
316         /* identifiers */
317         ot->name= "Clear Shape Keys";
318         ot->description= "Clear weights for all shape keys";
319         ot->idname= "OBJECT_OT_shape_key_clear";
320         
321         /* api callbacks */
322         ot->poll= shape_key_poll;
323         ot->exec= shape_key_clear_exec;
324
325         /* flags */
326         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
327 }
328
329 static int shape_key_mirror_exec(bContext *C, wmOperator *UNUSED(op))
330 {
331         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
332
333         if(!object_shape_key_mirror(C, ob))
334                 return OPERATOR_CANCELLED;
335
336         return OPERATOR_FINISHED;
337 }
338
339 void OBJECT_OT_shape_key_mirror(wmOperatorType *ot)
340 {
341         /* identifiers */
342         ot->name= "Mirror Shape Key";
343         ot->idname= "OBJECT_OT_shape_key_mirror";
344
345         /* api callbacks */
346         ot->poll= shape_key_mode_poll;
347         ot->exec= shape_key_mirror_exec;
348
349         /* flags */
350         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
351 }
352
353
354 static int shape_key_move_exec(bContext *C, wmOperator *op)
355 {
356         Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
357
358         int type= RNA_enum_get(op->ptr, "type");
359         Key *key= ob_get_key(ob);
360
361         if(key) {
362                 KeyBlock *kb, *kb_other;
363                 int shapenr_act= ob->shapenr-1;
364                 int shapenr_swap= shapenr_act + type;
365                 kb= BLI_findlink(&key->block, shapenr_act);
366
367                 if((type==-1 && kb->prev==NULL) || (type==1 && kb->next==NULL)) {
368                         return OPERATOR_CANCELLED;
369                 }
370
371                 for(kb_other= key->block.first; kb_other; kb_other= kb_other->next) {
372                         if(kb_other->relative == shapenr_act) {
373                                 kb_other->relative += type;
374                         }
375                         else if(kb_other->relative == shapenr_swap) {
376                                 kb_other->relative -= type;
377                         }
378                 }
379
380                 if(type==-1) {
381                         /* move back */
382                         kb_other= kb->prev;
383                         BLI_remlink(&key->block, kb);
384                         BLI_insertlinkbefore(&key->block, kb_other, kb);
385                         ob->shapenr--;
386                 }
387                 else {
388                         /* move next */
389                         kb_other= kb->next;
390                         BLI_remlink(&key->block, kb);
391                         BLI_insertlinkafter(&key->block, kb_other, kb);
392                         ob->shapenr++;
393                 }
394         }
395
396         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
397         WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
398
399         return OPERATOR_FINISHED;
400 }
401
402 void OBJECT_OT_shape_key_move(wmOperatorType *ot)
403 {
404         static EnumPropertyItem slot_move[] = {
405                 {-1, "UP", 0, "Up", ""},
406                 {1, "DOWN", 0, "Down", ""},
407                 {0, NULL, 0, NULL, NULL}
408         };
409
410         /* identifiers */
411         ot->name= "Move Shape Key";
412         ot->idname= "OBJECT_OT_shape_key_move";
413
414         /* api callbacks */
415         ot->poll= shape_key_mode_poll;
416         ot->exec= shape_key_move_exec;
417
418         /* flags */
419         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
420
421         RNA_def_enum(ot->srna, "type", slot_move, 0, "Type", "");
422 }
423