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