Fix some inconsistencies in object visibility/selectability tests.
[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_object_types.h"
52
53 #include "BKE_context.h"
54 #include "BKE_curve.h"
55 #include "BKE_key.h"
56 #include "BKE_lattice.h"
57 #include "BKE_main.h"
58 #include "BKE_object.h"
59
60 #include "DEG_depsgraph.h"
61 #include "DEG_depsgraph_build.h"
62
63 #include "BLI_sys_types.h" // for intptr_t support
64
65 #include "ED_object.h"
66 #include "ED_mesh.h"
67
68 #include "RNA_access.h"
69 #include "RNA_define.h"
70
71 #include "WM_api.h"
72 #include "WM_types.h"
73
74 #include "object_intern.h"
75
76 /*********************** add shape key ***********************/
77
78 static void ED_object_shape_key_add(bContext *C, Object *ob, const bool from_mix)
79 {
80         Main *bmain = CTX_data_main(C);
81         KeyBlock *kb;
82         if ((kb = BKE_object_shapekey_insert(bmain, ob, NULL, from_mix))) {
83                 Key *key = BKE_key_from_object(ob);
84                 /* for absolute shape keys, new keys may not be added last */
85                 ob->shapenr = BLI_findindex(&key->block, kb) + 1;
86
87                 WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
88         }
89 }
90
91 /*********************** remove shape key ***********************/
92
93 static bool object_shapekey_remove(Main *bmain, Object *ob)
94 {
95         KeyBlock *kb;
96         Key *key = BKE_key_from_object(ob);
97
98         if (key == NULL) {
99                 return false;
100         }
101
102         kb = BLI_findlink(&key->block, ob->shapenr - 1);
103         if (kb) {
104                 return BKE_object_shapekey_remove(bmain, ob, kb);
105         }
106
107         return false;
108 }
109
110 static bool object_shape_key_mirror(bContext *C, Object *ob,
111                                     int *r_totmirr, int *r_totfail, bool use_topology)
112 {
113         KeyBlock *kb;
114         Key *key;
115         int totmirr = 0, totfail = 0;
116
117         *r_totmirr = *r_totfail = 0;
118
119         key = BKE_key_from_object(ob);
120         if (key == NULL)
121                 return 0;
122
123         kb = BLI_findlink(&key->block, ob->shapenr - 1);
124
125         if (kb) {
126                 char *tag_elem = MEM_callocN(sizeof(char) * kb->totelem, "shape_key_mirror");
127
128
129                 if (ob->type == OB_MESH) {
130                         Mesh *me = ob->data;
131                         MVert *mv;
132                         int i1, i2;
133                         float *fp1, *fp2;
134                         float tvec[3];
135
136                         ED_mesh_mirror_spatial_table(ob, NULL, NULL, NULL, 's');
137
138                         for (i1 = 0, mv = me->mvert; i1 < me->totvert; i1++, mv++) {
139                                 i2 = mesh_get_x_mirror_vert(ob, NULL, i1, use_topology);
140                                 if (i2 == i1) {
141                                         fp1 = ((float *)kb->data) + i1 * 3;
142                                         fp1[0] = -fp1[0];
143                                         tag_elem[i1] = 1;
144                                         totmirr++;
145                                 }
146                                 else if (i2 != -1) {
147                                         if (tag_elem[i1] == 0 && tag_elem[i2] == 0) {
148                                                 fp1 = ((float *)kb->data) + i1 * 3;
149                                                 fp2 = ((float *)kb->data) + i2 * 3;
150
151                                                 copy_v3_v3(tvec,    fp1);
152                                                 copy_v3_v3(fp1, fp2);
153                                                 copy_v3_v3(fp2, tvec);
154
155                                                 /* flip x axis */
156                                                 fp1[0] = -fp1[0];
157                                                 fp2[0] = -fp2[0];
158                                                 totmirr++;
159                                         }
160                                         tag_elem[i1] = tag_elem[i2] = 1;
161                                 }
162                                 else {
163                                         totfail++;
164                                 }
165                         }
166
167                         ED_mesh_mirror_spatial_table(ob, NULL, NULL, NULL, 'e');
168                 }
169                 else if (ob->type == OB_LATTICE) {
170                         Lattice *lt = ob->data;
171                         int i1, i2;
172                         float *fp1, *fp2;
173                         int u, v, w;
174                         /* half but found up odd value */
175                         const int pntsu_half = (lt->pntsu / 2) + (lt->pntsu % 2);
176
177                         /* currently editmode isn't supported by mesh so
178                          * ignore here for now too */
179
180                         /* if (lt->editlatt) lt = lt->editlatt->latt; */
181
182                         for (w = 0; w < lt->pntsw; w++) {
183                                 for (v = 0; v < lt->pntsv; v++) {
184                                         for (u = 0; u < pntsu_half; u++) {
185                                                 int u_inv = (lt->pntsu - 1) - u;
186                                                 float tvec[3];
187                                                 if (u == u_inv) {
188                                                         i1 = BKE_lattice_index_from_uvw(lt, u, v, w);
189                                                         fp1 = ((float *)kb->data) + i1 * 3;
190                                                         fp1[0] = -fp1[0];
191                                                         totmirr++;
192                                                 }
193                                                 else {
194                                                         i1 = BKE_lattice_index_from_uvw(lt, u, v, w);
195                                                         i2 = BKE_lattice_index_from_uvw(lt, u_inv, v, w);
196
197                                                         fp1 = ((float *)kb->data) + i1 * 3;
198                                                         fp2 = ((float *)kb->data) + i2 * 3;
199
200                                                         copy_v3_v3(tvec, fp1);
201                                                         copy_v3_v3(fp1, fp2);
202                                                         copy_v3_v3(fp2, tvec);
203                                                         fp1[0] = -fp1[0];
204                                                         fp2[0] = -fp2[0];
205                                                         totmirr++;
206                                                 }
207                                         }
208                                 }
209                         }
210                 }
211
212                 MEM_freeN(tag_elem);
213         }
214
215         *r_totmirr = totmirr;
216         *r_totfail = totfail;
217
218         DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
219         WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
220
221         return 1;
222 }
223
224 /********************** shape key operators *********************/
225
226 static bool shape_key_mode_poll(bContext *C)
227 {
228         Object *ob = ED_object_context(C);
229         ID *data = (ob) ? ob->data : NULL;
230         return (ob && !ID_IS_LINKED(ob) && data && !ID_IS_LINKED(data) && ob->mode != OB_MODE_EDIT);
231 }
232
233 static bool shape_key_mode_exists_poll(bContext *C)
234 {
235         Object *ob = ED_object_context(C);
236         ID *data = (ob) ? ob->data : NULL;
237
238         /* same as shape_key_mode_poll */
239         return (ob && !ID_IS_LINKED(ob) && data && !ID_IS_LINKED(data) && ob->mode != OB_MODE_EDIT) &&
240                /* check a keyblock exists */
241                (BKE_keyblock_from_object(ob) != NULL);
242 }
243
244 static bool shape_key_move_poll(bContext *C)
245 {
246         /* Same as shape_key_mode_exists_poll above, but ensure we have at least two shapes! */
247         Object *ob = ED_object_context(C);
248         ID *data = (ob) ? ob->data : NULL;
249         Key *key = BKE_key_from_object(ob);
250
251         return (ob && !ID_IS_LINKED(ob) && data && !ID_IS_LINKED(data) &&
252                 ob->mode != OB_MODE_EDIT && key && key->totkey > 1);
253 }
254
255 static bool shape_key_poll(bContext *C)
256 {
257         Object *ob = ED_object_context(C);
258         ID *data = (ob) ? ob->data : NULL;
259         return (ob && !ID_IS_LINKED(ob) && data && !ID_IS_LINKED(data));
260 }
261
262 static int shape_key_add_exec(bContext *C, wmOperator *op)
263 {
264         Object *ob = ED_object_context(C);
265         const bool from_mix = RNA_boolean_get(op->ptr, "from_mix");
266
267         ED_object_shape_key_add(C, ob, from_mix);
268
269         DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
270         DEG_relations_tag_update(CTX_data_main(C));
271
272         return OPERATOR_FINISHED;
273 }
274
275 void OBJECT_OT_shape_key_add(wmOperatorType *ot)
276 {
277         /* identifiers */
278         ot->name = "Add Shape Key";
279         ot->idname = "OBJECT_OT_shape_key_add";
280         ot->description = "Add shape key to the object";
281
282         /* api callbacks */
283         ot->poll = shape_key_mode_poll;
284         ot->exec = shape_key_add_exec;
285
286         /* flags */
287         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
288
289         /* properties */
290         RNA_def_boolean(ot->srna, "from_mix", true, "From Mix", "Create the new shape key from the existing mix of keys");
291 }
292
293 static int shape_key_remove_exec(bContext *C, wmOperator *op)
294 {
295         Main *bmain = CTX_data_main(C);
296         Object *ob = ED_object_context(C);
297         bool changed = false;
298
299         if (RNA_boolean_get(op->ptr, "all")) {
300                 changed = BKE_object_shapekey_free(bmain, ob);
301         }
302         else {
303                 changed = object_shapekey_remove(bmain, ob);
304         }
305
306         if (changed) {
307                 DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
308                 DEG_relations_tag_update(CTX_data_main(C));
309                 WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
310
311                 return OPERATOR_FINISHED;
312         }
313         else {
314                 return OPERATOR_CANCELLED;
315         }
316 }
317
318 void OBJECT_OT_shape_key_remove(wmOperatorType *ot)
319 {
320         /* identifiers */
321         ot->name = "Remove Shape Key";
322         ot->idname = "OBJECT_OT_shape_key_remove";
323         ot->description = "Remove shape key from the object";
324
325         /* api callbacks */
326         ot->poll = shape_key_mode_exists_poll;
327         ot->exec = shape_key_remove_exec;
328
329         /* flags */
330         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
331
332         /* properties */
333         RNA_def_boolean(ot->srna, "all", 0, "All", "Remove all shape keys");
334 }
335
336 static int shape_key_clear_exec(bContext *C, wmOperator *UNUSED(op))
337 {
338         Object *ob = ED_object_context(C);
339         Key *key = BKE_key_from_object(ob);
340         KeyBlock *kb = BKE_keyblock_from_object(ob);
341
342         if (!key || !kb)
343                 return OPERATOR_CANCELLED;
344
345         for (kb = key->block.first; kb; kb = kb->next)
346                 kb->curval = 0.0f;
347
348         DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
349         WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
350
351         return OPERATOR_FINISHED;
352 }
353
354 void OBJECT_OT_shape_key_clear(wmOperatorType *ot)
355 {
356         /* identifiers */
357         ot->name = "Clear Shape Keys";
358         ot->description = "Clear weights for all shape keys";
359         ot->idname = "OBJECT_OT_shape_key_clear";
360
361         /* api callbacks */
362         ot->poll = shape_key_poll;
363         ot->exec = shape_key_clear_exec;
364
365         /* flags */
366         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
367 }
368
369 /* starting point and step size could be optional */
370 static int shape_key_retime_exec(bContext *C, wmOperator *UNUSED(op))
371 {
372         Object *ob = ED_object_context(C);
373         Key *key = BKE_key_from_object(ob);
374         KeyBlock *kb = BKE_keyblock_from_object(ob);
375         float cfra = 0.0f;
376
377         if (!key || !kb)
378                 return OPERATOR_CANCELLED;
379
380         for (kb = key->block.first; kb; kb = kb->next) {
381                 kb->pos = cfra;
382                 cfra += 0.1f;
383         }
384
385         DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
386         WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
387
388         return OPERATOR_FINISHED;
389 }
390
391 void OBJECT_OT_shape_key_retime(wmOperatorType *ot)
392 {
393         /* identifiers */
394         ot->name = "Re-Time Shape Keys";
395         ot->description = "Resets the timing for absolute shape keys";
396         ot->idname = "OBJECT_OT_shape_key_retime";
397
398         /* api callbacks */
399         ot->poll = shape_key_poll;
400         ot->exec = shape_key_retime_exec;
401
402         /* flags */
403         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
404 }
405
406 static int shape_key_mirror_exec(bContext *C, wmOperator *op)
407 {
408         Object *ob = ED_object_context(C);
409         int totmirr = 0, totfail = 0;
410         bool use_topology = RNA_boolean_get(op->ptr, "use_topology");
411
412         if (!object_shape_key_mirror(C, ob, &totmirr, &totfail, use_topology))
413                 return OPERATOR_CANCELLED;
414
415         ED_mesh_report_mirror(op, totmirr, totfail);
416
417         return OPERATOR_FINISHED;
418 }
419
420 void OBJECT_OT_shape_key_mirror(wmOperatorType *ot)
421 {
422         /* identifiers */
423         ot->name = "Mirror Shape Key";
424         ot->idname = "OBJECT_OT_shape_key_mirror";
425         ot->description = "Mirror the current shape key along the local X axis";
426
427         /* api callbacks */
428         ot->poll = shape_key_mode_poll;
429         ot->exec = shape_key_mirror_exec;
430
431         /* flags */
432         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
433
434         /* properties */
435         RNA_def_boolean(ot->srna, "use_topology", 0, "Topology Mirror",
436                         "Use topology based mirroring (for when both sides of mesh have matching, unique topology)");
437 }
438
439
440 enum {
441         KB_MOVE_TOP = -2,
442         KB_MOVE_UP = -1,
443         KB_MOVE_DOWN = 1,
444         KB_MOVE_BOTTOM = 2,
445 };
446
447 static int shape_key_move_exec(bContext *C, wmOperator *op)
448 {
449         Object *ob = ED_object_context(C);
450
451         Key *key = BKE_key_from_object(ob);
452         const int type = RNA_enum_get(op->ptr, "type");
453         const int totkey = key->totkey;
454         const int act_index = ob->shapenr - 1;
455         int new_index;
456
457         switch (type) {
458                 case KB_MOVE_TOP:
459                         /* Replace the ref key only if we're at the top already (only for relative keys) */
460                         new_index = (ELEM(act_index, 0, 1) || key->type == KEY_NORMAL) ? 0 : 1;
461                         break;
462                 case KB_MOVE_BOTTOM:
463                         new_index = totkey - 1;
464                         break;
465                 case KB_MOVE_UP:
466                 case KB_MOVE_DOWN:
467                 default:
468                         new_index = (totkey + act_index + type) % totkey;
469                         break;
470         }
471
472         if (!BKE_keyblock_move(ob, act_index, new_index)) {
473                 return OPERATOR_CANCELLED;
474         }
475
476         DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
477         WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
478
479         return OPERATOR_FINISHED;
480 }
481
482 void OBJECT_OT_shape_key_move(wmOperatorType *ot)
483 {
484         static const EnumPropertyItem slot_move[] = {
485                 {KB_MOVE_TOP, "TOP", 0, "Top", "Top of the list"},
486                 {KB_MOVE_UP, "UP", 0, "Up", ""},
487                 {KB_MOVE_DOWN, "DOWN", 0, "Down", ""},
488                 {KB_MOVE_BOTTOM, "BOTTOM", 0, "Bottom", "Bottom of the list"},
489                 { 0, NULL, 0, NULL, NULL }
490         };
491
492         /* identifiers */
493         ot->name = "Move Shape Key";
494         ot->idname = "OBJECT_OT_shape_key_move";
495         ot->description = "Move the active shape key up/down in the list";
496
497         /* api callbacks */
498         ot->poll = shape_key_move_poll;
499         ot->exec = shape_key_move_exec;
500
501         /* flags */
502         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
503
504         RNA_def_enum(ot->srna, "type", slot_move, 0, "Type", "");
505 }