style cleanup: follow style guide for formatting of if/for/while loops, and else...
[blender.git] / source / blender / editors / object / object_shapekey.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * Contributor(s): Blender Foundation, shapekey support
22  *
23  * ***** END GPL LICENSE BLOCK *****
24  */
25
26 /** \file blender/editors/object/object_shapekey.c
27  *  \ingroup edobj
28  */
29
30
31 #include <math.h>
32 #include <string.h>
33
34 #ifndef WIN32
35 #include <unistd.h>
36 #else
37 #include <io.h>
38 #endif   
39
40 #include "MEM_guardedalloc.h"
41
42 #include "BLI_blenlib.h"
43 #include "BLI_math.h"
44 #include "BLI_utildefines.h"
45
46 #include "DNA_curve_types.h"
47 #include "DNA_key_types.h"
48 #include "DNA_lattice_types.h"
49 #include "DNA_mesh_types.h"
50 #include "DNA_meshdata_types.h"
51 #include "DNA_scene_types.h"
52 #include "DNA_object_types.h"
53
54 #include "BKE_context.h"
55 #include "BKE_depsgraph.h"
56 #include "BKE_key.h"
57 #include "BKE_library.h"
58 #include "BKE_main.h"
59 #include "BKE_object.h"
60 #include "BKE_curve.h"
61
62 #include "BLO_sys_types.h" // for intptr_t support
63
64 #include "ED_object.h"
65 #include "ED_mesh.h"
66
67 #include "RNA_access.h"
68 #include "RNA_define.h"
69
70 #include "WM_api.h"
71 #include "WM_types.h"
72
73 #include "object_intern.h"
74
75 /*********************** add shape key ***********************/
76
77 static void ED_object_shape_key_add(bContext *C, Scene *scene, Object *ob, int from_mix)
78 {
79         if (object_insert_shape_key(scene, ob, NULL, from_mix)) {
80                 Key *key= ob_get_key(ob);
81                 ob->shapenr= BLI_countlist(&key->block);
82
83                 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
84         }
85 }
86
87 /*********************** remove shape key ***********************/
88
89 static int ED_object_shape_key_remove(bContext *C, Object *ob)
90 {
91         Main *bmain= CTX_data_main(C);
92         KeyBlock *kb, *rkb;
93         Key *key;
94         //IpoCurve *icu;
95
96         key= ob_get_key(ob);
97         if (key==NULL)
98                 return 0;
99         
100         kb= BLI_findlink(&key->block, ob->shapenr-1);
101
102         if (kb) {
103                 for (rkb= key->block.first; rkb; rkb= rkb->next)
104                         if (rkb->relative == ob->shapenr-1)
105                                 rkb->relative= 0;
106
107                 BLI_remlink(&key->block, kb);
108                 key->totkey--;
109                 if (key->refkey== kb) {
110                         key->refkey= key->block.first;
111
112                         if (key->refkey) {
113                                 /* apply new basis key on original data */
114                                 switch(ob->type) {
115                                         case OB_MESH:
116                                                 key_to_mesh(key->refkey, ob->data);
117                                                 break;
118                                         case OB_CURVE:
119                                         case OB_SURF:
120                                                 key_to_curve(key->refkey, ob->data, BKE_curve_nurbs(ob->data));
121                                                 break;
122                                         case OB_LATTICE:
123                                                 key_to_latt(key->refkey, ob->data);
124                                                 break;
125                                 }
126                         }
127                 }
128                         
129                 if (kb->data) MEM_freeN(kb->data);
130                 MEM_freeN(kb);
131                 
132                 for (kb= key->block.first; kb; kb= kb->next)
133                         if (kb->adrcode>=ob->shapenr)
134                                 kb->adrcode--;
135                 
136 #if 0 // XXX old animation system
137                 if (key->ipo) {
138                         
139                         for (icu= key->ipo->curve.first; icu; icu= icu->next) {
140                                 if (icu->adrcode==ob->shapenr-1) {
141                                         BLI_remlink(&key->ipo->curve, icu);
142                                         free_ipo_curve(icu);
143                                         break;
144                                 }
145                         }
146                         for (icu= key->ipo->curve.first; icu; icu= icu->next) 
147                                 if (icu->adrcode>=ob->shapenr)
148                                         icu->adrcode--;
149                 }
150 #endif // XXX old animation system              
151                 
152                 if (ob->shapenr>1) ob->shapenr--;
153         }
154         
155         if (key->totkey==0) {
156                 if (GS(key->from->name)==ID_ME) ((Mesh *)key->from)->key= NULL;
157                 else if (GS(key->from->name)==ID_CU) ((Curve *)key->from)->key= NULL;
158                 else if (GS(key->from->name)==ID_LT) ((Lattice *)key->from)->key= NULL;
159
160                 free_libblock_us(&(bmain->key), key);
161         }
162         
163         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
164         WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
165
166         return 1;
167 }
168
169 static int object_shape_key_mirror(bContext *C, Object *ob)
170 {
171         KeyBlock *kb;
172         Key *key;
173
174         key= ob_get_key(ob);
175         if (key==NULL)
176                 return 0;
177         
178         kb= BLI_findlink(&key->block, ob->shapenr-1);
179
180         if (kb) {
181                 int i1, i2;
182                 float *fp1, *fp2;
183                 float tvec[3];
184                 char *tag_elem= MEM_callocN(sizeof(char) * kb->totelem, "shape_key_mirror");
185
186
187                 if (ob->type==OB_MESH) {
188                         Mesh *me= ob->data;
189                         MVert *mv;
190
191                         mesh_octree_table(ob, NULL, NULL, 's');
192
193                         for (i1=0, mv=me->mvert; i1<me->totvert; i1++, mv++) {
194                                 i2= mesh_get_x_mirror_vert(ob, i1);
195                                 if (i2==i1) {
196                                         fp1= ((float *)kb->data) + i1*3;
197                                         fp1[0] = -fp1[0];
198                                         tag_elem[i1]= 1;
199                                 }
200                                 else if (i2 != -1) {
201                                         if (tag_elem[i1]==0 && tag_elem[i2]==0) {
202                                                 fp1= ((float *)kb->data) + i1*3;
203                                                 fp2= ((float *)kb->data) + i2*3;
204
205                                                 copy_v3_v3(tvec,        fp1);
206                                                 copy_v3_v3(fp1, fp2);
207                                                 copy_v3_v3(fp2, tvec);
208
209                                                 /* flip x axis */
210                                                 fp1[0] = -fp1[0];
211                                                 fp2[0] = -fp2[0];
212                                         }
213                                         tag_elem[i1]= tag_elem[i2]= 1;
214                                 }
215                         }
216
217                         mesh_octree_table(ob, NULL, NULL, 'e');
218                 }
219                 else if (ob->type == OB_LATTICE) {
220                         Lattice *lt= ob->data;
221                         int i1, i2;
222                         float *fp1, *fp2;
223                         int u, v, w;
224                         /* half but found up odd value */
225                         const int pntsu_half = (lt->pntsu / 2) + (lt->pntsu % 2);
226
227                         /* currently editmode isn't supported by mesh so
228                          * ignore here for now too */
229
230                         /* if(lt->editlatt) lt= lt->editlatt->latt; */
231
232                         for (w=0; w<lt->pntsw; w++) {
233                                 for (v=0; v<lt->pntsv; v++) {
234                                         for (u=0; u<pntsu_half; u++) {
235                                                 int u_inv= (lt->pntsu - 1) - u;
236                                                 float tvec[3];
237                                                 if (u == u_inv) {
238                                                         i1= LT_INDEX(lt, u, v, w);
239                                                         fp1= ((float *)kb->data) + i1*3;
240                                                         fp1[0]= -fp1[0];
241                                                 }
242                                                 else {
243                                                         i1= LT_INDEX(lt, u, v, w);
244                                                         i2= LT_INDEX(lt, u_inv, v, w);
245
246                                                         fp1= ((float *)kb->data) + i1*3;
247                                                         fp2= ((float *)kb->data) + i2*3;
248
249                                                         copy_v3_v3(tvec, fp1);
250                                                         copy_v3_v3(fp1, fp2);
251                                                         copy_v3_v3(fp2, tvec);
252                                                         fp1[0]= -fp1[0];
253                                                         fp2[0]= -fp2[0];
254                                                 }
255                                         }
256                                 }
257                         }
258                 }
259
260                 MEM_freeN(tag_elem);
261         }
262         
263         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
264         WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
265
266         return 1;
267 }
268
269 /********************** shape key operators *********************/
270
271 static int shape_key_mode_poll(bContext *C)
272 {
273         Object *ob= ED_object_context(C);
274         ID *data= (ob)? ob->data: NULL;
275         return (ob && !ob->id.lib && data && !data->lib && ob->mode != OB_MODE_EDIT);
276 }
277
278 static int shape_key_poll(bContext *C)
279 {
280         Object *ob= ED_object_context(C);
281         ID *data= (ob)? ob->data: NULL;
282         return (ob && !ob->id.lib && data && !data->lib);
283 }
284
285 static int shape_key_add_exec(bContext *C, wmOperator *op)
286 {
287         Scene *scene= CTX_data_scene(C);
288         Object *ob= ED_object_context(C);
289         int from_mix = RNA_boolean_get(op->ptr, "from_mix");
290
291         ED_object_shape_key_add(C, scene, ob, from_mix);
292
293         return OPERATOR_FINISHED;
294 }
295
296 void OBJECT_OT_shape_key_add(wmOperatorType *ot)
297 {
298         /* identifiers */
299         ot->name = "Add Shape Key";
300         ot->idname = "OBJECT_OT_shape_key_add";
301         ot->description = "Add shape key to the object";
302         
303         /* api callbacks */
304         ot->poll = shape_key_mode_poll;
305         ot->exec = shape_key_add_exec;
306
307         /* flags */
308         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
309
310         /* properties */
311         RNA_def_boolean(ot->srna, "from_mix", 1, "From Mix", "Create the new shape key from the existing mix of keys");
312 }
313
314 static int shape_key_remove_exec(bContext *C, wmOperator *UNUSED(op))
315 {
316         Object *ob= ED_object_context(C);
317
318         if (!ED_object_shape_key_remove(C, ob))
319                 return OPERATOR_CANCELLED;
320         
321         return OPERATOR_FINISHED;
322 }
323
324 void OBJECT_OT_shape_key_remove(wmOperatorType *ot)
325 {
326         /* identifiers */
327         ot->name = "Remove Shape Key";
328         ot->idname = "OBJECT_OT_shape_key_remove";
329         ot->description = "Remove shape key from the object";
330         
331         /* api callbacks */
332         ot->poll = shape_key_mode_poll;
333         ot->exec = shape_key_remove_exec;
334
335         /* flags */
336         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
337 }
338
339 static int shape_key_clear_exec(bContext *C, wmOperator *UNUSED(op))
340 {
341         Object *ob= ED_object_context(C);
342         Key *key= ob_get_key(ob);
343         KeyBlock *kb= ob_get_keyblock(ob);
344
345         if (!key || !kb)
346                 return OPERATOR_CANCELLED;
347         
348         for (kb=key->block.first; kb; kb=kb->next)
349                 kb->curval= 0.0f;
350
351         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
352         WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
353         
354         return OPERATOR_FINISHED;
355 }
356
357 void OBJECT_OT_shape_key_clear(wmOperatorType *ot)
358 {
359         /* identifiers */
360         ot->name = "Clear Shape Keys";
361         ot->description = "Clear weights for all shape keys";
362         ot->idname = "OBJECT_OT_shape_key_clear";
363         
364         /* api callbacks */
365         ot->poll = shape_key_poll;
366         ot->exec = shape_key_clear_exec;
367
368         /* flags */
369         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
370 }
371
372 static int shape_key_mirror_exec(bContext *C, wmOperator *UNUSED(op))
373 {
374         Object *ob= ED_object_context(C);
375
376         if (!object_shape_key_mirror(C, ob))
377                 return OPERATOR_CANCELLED;
378
379         return OPERATOR_FINISHED;
380 }
381
382 void OBJECT_OT_shape_key_mirror(wmOperatorType *ot)
383 {
384         /* identifiers */
385         ot->name = "Mirror Shape Key";
386         ot->idname = "OBJECT_OT_shape_key_mirror";
387
388         /* api callbacks */
389         ot->poll = shape_key_mode_poll;
390         ot->exec = shape_key_mirror_exec;
391
392         /* flags */
393         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
394 }
395
396
397 static int shape_key_move_exec(bContext *C, wmOperator *op)
398 {
399         Object *ob= ED_object_context(C);
400
401         int type= RNA_enum_get(op->ptr, "type");
402         Key *key= ob_get_key(ob);
403
404         if (key) {
405                 KeyBlock *kb, *kb_other;
406                 int shapenr_act= ob->shapenr-1;
407                 int shapenr_swap= shapenr_act + type;
408                 kb= BLI_findlink(&key->block, shapenr_act);
409
410                 if ((type==-1 && kb->prev==NULL) || (type==1 && kb->next==NULL)) {
411                         return OPERATOR_CANCELLED;
412                 }
413
414                 for (kb_other= key->block.first; kb_other; kb_other= kb_other->next) {
415                         if (kb_other->relative == shapenr_act) {
416                                 kb_other->relative += type;
417                         }
418                         else if (kb_other->relative == shapenr_swap) {
419                                 kb_other->relative -= type;
420                         }
421                 }
422
423                 if (type==-1) {
424                         /* move back */
425                         kb_other= kb->prev;
426                         BLI_remlink(&key->block, kb);
427                         BLI_insertlinkbefore(&key->block, kb_other, kb);
428                         ob->shapenr--;
429                 }
430                 else {
431                         /* move next */
432                         kb_other= kb->next;
433                         BLI_remlink(&key->block, kb);
434                         BLI_insertlinkafter(&key->block, kb_other, kb);
435                         ob->shapenr++;
436                 }
437         }
438
439         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
440         WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
441
442         return OPERATOR_FINISHED;
443 }
444
445 void OBJECT_OT_shape_key_move(wmOperatorType *ot)
446 {
447         static EnumPropertyItem slot_move[] = {
448                 {-1, "UP", 0, "Up", ""},
449                 {1, "DOWN", 0, "Down", ""},
450                 {0, NULL, 0, NULL, NULL}
451         };
452
453         /* identifiers */
454         ot->name = "Move Shape Key";
455         ot->idname = "OBJECT_OT_shape_key_move";
456
457         /* api callbacks */
458         ot->poll = shape_key_mode_poll;
459         ot->exec = shape_key_move_exec;
460
461         /* flags */
462         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
463
464         RNA_def_enum(ot->srna, "type", slot_move, 0, "Type", "");
465 }
466