Blender V4.5
object_shapekey.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <cstring>
10
11#ifndef WIN32
12# include <unistd.h>
13#else
14# include <io.h>
15#endif
16
17#include "MEM_guardedalloc.h"
18
19#include "BLI_listbase.h"
20#include "BLI_math_vector.h"
21#include "BLI_utildefines.h"
22
23#include "BLT_translation.hh"
24
25#include "DNA_key_types.h"
26#include "DNA_lattice_types.h"
27#include "DNA_mesh_types.h"
28#include "DNA_object_types.h"
29
30#include "BKE_context.hh"
31#include "BKE_key.hh"
32#include "BKE_lattice.hh"
33#include "BKE_library.hh"
34#include "BKE_object.hh"
35#include "BKE_report.hh"
36
37#include "DEG_depsgraph.hh"
39
40#include "ED_curve.hh"
41#include "ED_lattice.hh"
42#include "ED_mesh.hh"
43#include "ED_object.hh"
44
45#include "RNA_access.hh"
46#include "RNA_define.hh"
47
48#include "WM_api.hh"
49#include "WM_types.hh"
50
51#include "object_intern.hh"
52
53namespace blender::ed::object {
54
55/* -------------------------------------------------------------------- */
58
60{
61 KeyBlock *key_block;
62
63 switch (obedit->type) {
64 case OB_MESH:
65 key_block = ED_mesh_get_edit_shape_key(static_cast<Mesh *>(obedit->data));
66 break;
67 case OB_SURF:
69 key_block = ED_curve_get_edit_shape_key(static_cast<Curve *>(obedit->data));
70 break;
71 case OB_LATTICE:
72 key_block = ED_lattice_get_edit_shape_key(static_cast<Lattice *>(obedit->data));
73 break;
74 default:
75 return false;
76 }
77
78 if (key_block && (key_block->flag & KEYBLOCK_LOCKED_SHAPE) != 0) {
79 if (reports) {
80 BKE_reportf(reports, RPT_ERROR, "The active shape key of %s is locked", obedit->id.name + 2);
81 }
82 return true;
83 }
84
85 return false;
86}
87
89{
90 const KeyBlock *kb = BKE_keyblock_from_object(ob);
91
92 if (kb && (kb->flag & KEYBLOCK_LOCKED_SHAPE) != 0) {
93 if (reports) {
94 BKE_reportf(reports, RPT_ERROR, "The active shape key of %s is locked", ob->id.name + 2);
95 }
96 return true;
97 }
98
99 return false;
100}
101
103{
104 const Key *key = BKE_key_from_object(ob);
105
106 if (key) {
107 LISTBASE_FOREACH (const KeyBlock *, kb, &key->block) {
108 if (kb->flag & KEYBLOCK_LOCKED_SHAPE) {
109 return true;
110 }
111 }
112 }
113
114 return false;
115}
116
118{
120 if (reports) {
121 BKE_reportf(reports, RPT_ERROR, "The object %s has locked shape keys", ob->id.name + 2);
122 }
123 return true;
124 }
125
126 return false;
127}
128
130
131/* -------------------------------------------------------------------- */
134
135static void object_shape_key_add(bContext *C, Object *ob, const bool from_mix)
136{
137 Main *bmain = CTX_data_main(C);
138 KeyBlock *kb = BKE_object_shapekey_insert(bmain, ob, nullptr, from_mix);
139 if (kb) {
140 Key *key = BKE_key_from_object(ob);
141 /* for absolute shape keys, new keys may not be added last */
142 ob->shapenr = BLI_findindex(&key->block, kb) + 1;
143
145 }
146}
147
149
150/* -------------------------------------------------------------------- */
153
154static bool object_shapekey_remove(Main *bmain, Object *ob)
155{
156 KeyBlock *kb;
157 Key *key = BKE_key_from_object(ob);
158
159 if (key == nullptr) {
160 return false;
161 }
162
163 kb = static_cast<KeyBlock *>(BLI_findlink(&key->block, ob->shapenr - 1));
164 if (kb) {
165 return BKE_object_shapekey_remove(bmain, ob, kb);
166 }
167
168 return false;
169}
170
172 bContext *C, Object *ob, int *r_totmirr, int *r_totfail, bool use_topology)
173{
174 KeyBlock *kb;
175 Key *key;
176 int totmirr = 0, totfail = 0;
177
178 *r_totmirr = *r_totfail = 0;
179
180 key = BKE_key_from_object(ob);
181 if (key == nullptr) {
182 return false;
183 }
184
185 kb = static_cast<KeyBlock *>(BLI_findlink(&key->block, ob->shapenr - 1));
186
187 if (kb) {
188 char *tag_elem = MEM_calloc_arrayN<char>(kb->totelem, "shape_key_mirror");
189
190 if (ob->type == OB_MESH) {
191 Mesh *mesh = static_cast<Mesh *>(ob->data);
192 int i1, i2;
193 float *fp1, *fp2;
194 float tvec[3];
195
196 ED_mesh_mirror_spatial_table_begin(ob, nullptr, nullptr);
197
198 for (i1 = 0; i1 < mesh->verts_num; i1++) {
199 i2 = mesh_get_x_mirror_vert(ob, nullptr, i1, use_topology);
200 if (i2 == i1) {
201 fp1 = ((float *)kb->data) + i1 * 3;
202 fp1[0] = -fp1[0];
203 tag_elem[i1] = 1;
204 totmirr++;
205 }
206 else if (i2 != -1) {
207 if (tag_elem[i1] == 0 && tag_elem[i2] == 0) {
208 fp1 = ((float *)kb->data) + i1 * 3;
209 fp2 = ((float *)kb->data) + i2 * 3;
210
211 copy_v3_v3(tvec, fp1);
212 copy_v3_v3(fp1, fp2);
213 copy_v3_v3(fp2, tvec);
214
215 /* flip x axis */
216 fp1[0] = -fp1[0];
217 fp2[0] = -fp2[0];
218 totmirr++;
219 }
220 tag_elem[i1] = tag_elem[i2] = 1;
221 }
222 else {
223 totfail++;
224 }
225 }
226
228 }
229 else if (ob->type == OB_LATTICE) {
230 const Lattice *lt = static_cast<const Lattice *>(ob->data);
231 int i1, i2;
232 float *fp1, *fp2;
233 int u, v, w;
234 /* half but found up odd value */
235 const int pntsu_half = (lt->pntsu / 2) + (lt->pntsu % 2);
236
237 /* Currently edit-mode isn't supported by mesh so ignore here for now too. */
238#if 0
239 if (lt->editlatt) {
240 lt = lt->editlatt->latt;
241 }
242#endif
243
244 for (w = 0; w < lt->pntsw; w++) {
245 for (v = 0; v < lt->pntsv; v++) {
246 for (u = 0; u < pntsu_half; u++) {
247 int u_inv = (lt->pntsu - 1) - u;
248 float tvec[3];
249 if (u == u_inv) {
250 i1 = BKE_lattice_index_from_uvw(lt, u, v, w);
251 fp1 = ((float *)kb->data) + i1 * 3;
252 fp1[0] = -fp1[0];
253 totmirr++;
254 }
255 else {
256 i1 = BKE_lattice_index_from_uvw(lt, u, v, w);
257 i2 = BKE_lattice_index_from_uvw(lt, u_inv, v, w);
258
259 fp1 = ((float *)kb->data) + i1 * 3;
260 fp2 = ((float *)kb->data) + i2 * 3;
261
262 copy_v3_v3(tvec, fp1);
263 copy_v3_v3(fp1, fp2);
264 copy_v3_v3(fp2, tvec);
265 fp1[0] = -fp1[0];
266 fp2[0] = -fp2[0];
267 totmirr++;
268 }
269 }
270 }
271 }
272 }
273
274 MEM_freeN(tag_elem);
275 }
276
277 *r_totmirr = totmirr;
278 *r_totfail = totfail;
279
282
283 return true;
284}
285
287
288/* -------------------------------------------------------------------- */
291
293{
294 Object *ob = context_object(C);
295 ID *data = static_cast<ID *>((ob) ? ob->data : nullptr);
296
297 return (ob != nullptr && ID_IS_EDITABLE(ob) && !ID_IS_OVERRIDE_LIBRARY(ob) && data != nullptr &&
299}
300
302{
303 Object *ob = context_object(C);
304
305 return (shape_key_poll(C) &&
306 /* check a keyblock exists */
307 (BKE_keyblock_from_object(ob) != nullptr));
308}
309
311{
312 Object *ob = context_object(C);
313
314 return (shape_key_poll(C) && ob->mode != OB_MODE_EDIT);
315}
316
318{
319 Object *ob = context_object(C);
320
321 return (shape_key_mode_poll(C) &&
322 /* check a keyblock exists */
323 (BKE_keyblock_from_object(ob) != nullptr));
324}
325
327{
328 /* Same as shape_key_mode_exists_poll above, but ensure we have at least two shapes! */
329 Object *ob = context_object(C);
330 Key *key = BKE_key_from_object(ob);
331
332 return (shape_key_mode_poll(C) && key != nullptr && key->totkey > 1);
333}
334
336
337/* -------------------------------------------------------------------- */
340
342{
343 Object *ob = context_object(C);
344 const bool from_mix = RNA_boolean_get(op->ptr, "from_mix");
345
346 object_shape_key_add(C, ob, from_mix);
347
350
351 return OPERATOR_FINISHED;
352}
353
355{
356 /* identifiers */
357 ot->name = "Add Shape Key";
358 ot->idname = "OBJECT_OT_shape_key_add";
359 ot->description = "Add shape key to the object";
360
361 /* API callbacks. */
362 ot->poll = shape_key_mode_poll;
363 ot->exec = shape_key_add_exec;
364
365 /* flags */
367
368 /* properties */
369 RNA_def_boolean(ot->srna,
370 "from_mix",
371 true,
372 "From Mix",
373 "Create the new shape key from the existing mix of keys");
374}
375
377
378/* -------------------------------------------------------------------- */
381
394
396{
397 ot->name = "Duplicate Shape Key";
398 ot->idname = "OBJECT_OT_shape_key_copy";
399 ot->description = "Duplicate the active shape key";
400
402 ot->exec = shape_key_copy_exec;
403
405}
406
408
409/* -------------------------------------------------------------------- */
412
414{
415 Main *bmain = CTX_data_main(C);
416 Object *ob = context_object(C);
417 bool changed = false;
418
419 if (RNA_boolean_get(op->ptr, "all")) {
421 return OPERATOR_CANCELLED;
422 }
423
424 if (RNA_boolean_get(op->ptr, "apply_mix")) {
425 float *arr = BKE_key_evaluate_object_ex(
426 ob, nullptr, nullptr, 0, static_cast<ID *>(ob->data));
427 MEM_freeN(arr);
428 }
429 changed = BKE_object_shapekey_free(bmain, ob);
430 }
431 else {
433 return OPERATOR_CANCELLED;
434 }
435
436 changed = object_shapekey_remove(bmain, ob);
437 }
438
439 if (changed) {
443
444 return OPERATOR_FINISHED;
445 }
446 return OPERATOR_CANCELLED;
447}
448
449static bool shape_key_remove_poll_property(const bContext * /*C*/,
450 wmOperator *op,
451 const PropertyRNA *prop)
452{
453 const char *prop_id = RNA_property_identifier(prop);
454 const bool do_all = RNA_enum_get(op->ptr, "all");
455
456 /* Only show seed for randomize action! */
457 if (STREQ(prop_id, "apply_mix") && !do_all) {
458 return false;
459 }
460 return true;
461}
462
464 wmOperatorType * /*ot*/,
466{
467 const bool do_apply_mix = RNA_boolean_get(ptr, "apply_mix");
468 if (do_apply_mix) {
469 return TIP_("Apply current visible shape to the object data, and delete all shape keys");
470 }
471
472 return "";
473}
474
476{
477 /* identifiers */
478 ot->name = "Remove Shape Key";
479 ot->idname = "OBJECT_OT_shape_key_remove";
480 ot->description = "Remove shape key from the object";
481
482 /* API callbacks. */
485 ot->poll_property = shape_key_remove_poll_property;
486 ot->get_description = shape_key_remove_get_description;
487
488 /* flags */
490
491 /* properties */
492 RNA_def_boolean(ot->srna, "all", false, "All", "Remove all shape keys");
493 RNA_def_boolean(ot->srna,
494 "apply_mix",
495 false,
496 "Apply Mix",
497 "Apply current mix of shape keys to the geometry before removing them");
498}
499
501
502/* -------------------------------------------------------------------- */
505
507{
508 Object *ob = context_object(C);
509 Key *key = BKE_key_from_object(ob);
510
511 if (!key || BLI_listbase_is_empty(&key->block)) {
512 return OPERATOR_CANCELLED;
513 }
514
515 LISTBASE_FOREACH (KeyBlock *, kb, &key->block) {
516 kb->curval = clamp_f(0.0f, kb->slidermin, kb->slidermax);
517 }
518
521
522 return OPERATOR_FINISHED;
523}
524
526{
527 /* identifiers */
528 ot->name = "Clear Shape Keys";
529 ot->description =
530 "Reset the weights of all shape keys to 0 or to the closest value respecting the limits";
531 ot->idname = "OBJECT_OT_shape_key_clear";
532
533 /* API callbacks. */
534 ot->poll = shape_key_poll;
535 ot->exec = shape_key_clear_exec;
536
537 /* flags */
539}
540
541/* starting point and step size could be optional */
543{
544 Object *ob = context_object(C);
545 Key *key = BKE_key_from_object(ob);
546 float cfra = 0.0f;
547
548 if (!key || BLI_listbase_is_empty(&key->block)) {
549 return OPERATOR_CANCELLED;
550 }
551
552 LISTBASE_FOREACH (KeyBlock *, kb, &key->block) {
553 kb->pos = cfra;
554 cfra += 0.1f;
555 }
556
559
560 return OPERATOR_FINISHED;
561}
562
564{
565 /* identifiers */
566 ot->name = "Re-Time Shape Keys";
567 ot->description = "Resets the timing for absolute shape keys";
568 ot->idname = "OBJECT_OT_shape_key_retime";
569
570 /* API callbacks. */
571 ot->poll = shape_key_poll;
573
574 /* flags */
576}
577
579
580/* -------------------------------------------------------------------- */
583
585{
586 Object *ob = context_object(C);
587 int totmirr = 0, totfail = 0;
588 bool use_topology = RNA_boolean_get(op->ptr, "use_topology");
589
591 return OPERATOR_CANCELLED;
592 }
593
594 if (!object_shape_key_mirror(C, ob, &totmirr, &totfail, use_topology)) {
595 return OPERATOR_CANCELLED;
596 }
597
598 ED_mesh_report_mirror(op, totmirr, totfail);
599
600 return OPERATOR_FINISHED;
601}
602
604{
605 /* identifiers */
606 ot->name = "Mirror Shape Key";
607 ot->idname = "OBJECT_OT_shape_key_mirror";
608 ot->description = "Mirror the current shape key along the local X axis";
609
610 /* API callbacks. */
611 ot->poll = shape_key_mode_poll;
613
614 /* flags */
616
617 /* properties */
619 ot->srna,
620 "use_topology",
621 false,
622 "Topology Mirror",
623 "Use topology based mirroring (for when both sides of mesh have matching, unique topology)");
624}
625
627
628/* -------------------------------------------------------------------- */
631
632enum {
637};
638
640{
641 Object *ob = context_object(C);
642
643 Key *key = BKE_key_from_object(ob);
644 const int type = RNA_enum_get(op->ptr, "type");
645 const int totkey = key->totkey;
646 const int act_index = ob->shapenr - 1;
647 int new_index;
648
649 switch (type) {
650 case KB_MOVE_TOP:
651 /* Replace the ref key only if we're at the top already (only for relative keys) */
652 new_index = (ELEM(act_index, 0, 1) || key->type == KEY_NORMAL) ? 0 : 1;
653 break;
654 case KB_MOVE_BOTTOM:
655 new_index = totkey - 1;
656 break;
657 case KB_MOVE_UP:
658 case KB_MOVE_DOWN:
659 default:
660 new_index = (totkey + act_index + type) % totkey;
661 break;
662 }
663
664 if (!BKE_keyblock_move(ob, act_index, new_index)) {
665 return OPERATOR_CANCELLED;
666 }
667
670
671 return OPERATOR_FINISHED;
672}
673
675{
676 static const EnumPropertyItem slot_move[] = {
677 {KB_MOVE_TOP, "TOP", 0, "Top", "Top of the list"},
678 {KB_MOVE_UP, "UP", 0, "Up", ""},
679 {KB_MOVE_DOWN, "DOWN", 0, "Down", ""},
680 {KB_MOVE_BOTTOM, "BOTTOM", 0, "Bottom", "Bottom of the list"},
681 {0, nullptr, 0, nullptr, nullptr}};
682
683 /* identifiers */
684 ot->name = "Move Shape Key";
685 ot->idname = "OBJECT_OT_shape_key_move";
686 ot->description = "Move the active shape key up/down in the list";
687
688 /* API callbacks. */
689 ot->poll = shape_key_move_poll;
690 ot->exec = shape_key_move_exec;
691
692 /* flags */
694
695 RNA_def_enum(ot->srna, "type", slot_move, 0, "Type", "");
696}
697
699
700/* -------------------------------------------------------------------- */
703
704enum {
707};
708
710{
712 const int action = RNA_enum_get(op->ptr, "action");
713 const Key *keys = BKE_key_from_object(ob);
714
715 if (!keys || BLI_listbase_is_empty(&keys->block)) {
716 return OPERATOR_CANCELLED;
717 }
718
719 LISTBASE_FOREACH (KeyBlock *, kb, &keys->block) {
720 switch (action) {
721 case SHAPE_KEY_LOCK:
722 kb->flag |= KEYBLOCK_LOCKED_SHAPE;
723 break;
724 case SHAPE_KEY_UNLOCK:
725 kb->flag &= ~KEYBLOCK_LOCKED_SHAPE;
726 break;
727 default:
728 BLI_assert(0);
729 }
730 }
731
733
734 return OPERATOR_FINISHED;
735}
736
737static std::string shape_key_lock_get_description(bContext * /*C*/,
738 wmOperatorType * /*op*/,
740{
741 const int action = RNA_enum_get(ptr, "action");
742
743 switch (action) {
744 case SHAPE_KEY_LOCK:
745 return TIP_("Lock all shape keys of the active object");
746 break;
747 case SHAPE_KEY_UNLOCK:
748 return TIP_("Unlock all shape keys of the active object");
749 break;
750 default:
751 return "";
752 }
753}
754
756{
757 static const EnumPropertyItem shape_key_lock_actions[] = {
758 {SHAPE_KEY_LOCK, "LOCK", 0, "Lock", "Lock all shape keys"},
759 {SHAPE_KEY_UNLOCK, "UNLOCK", 0, "Unlock", "Unlock all shape keys"},
760 {0, nullptr, 0, nullptr, nullptr},
761 };
762
763 /* identifiers */
764 ot->name = "Change the Lock On Shape Keys";
765 ot->idname = "OBJECT_OT_shape_key_lock";
766 ot->description = "Change the lock state of all shape keys of active object";
767
768 /* API callbacks. */
770 ot->exec = shape_key_lock_exec;
771 ot->get_description = shape_key_lock_get_description;
772
773 /* flags */
775
776 RNA_def_enum(ot->srna,
777 "action",
778 shape_key_lock_actions,
780 "Action",
781 "Lock action to execute on vertex groups");
782}
783
785
786} // namespace blender::ed::object
Object * CTX_data_active_object(const bContext *C)
Main * CTX_data_main(const bContext *C)
KeyBlock * BKE_keyblock_from_object(Object *ob)
Definition key.cc:1922
KeyBlock * BKE_keyblock_duplicate(Key *key, KeyBlock *kb_src)
Definition key.cc:1882
bool BKE_keyblock_move(Object *ob, int org_index, int new_index)
Definition key.cc:2307
float * BKE_key_evaluate_object_ex(Object *ob, int *r_totelem, float *arr, size_t arr_size, ID *obdata)
Definition key.cc:1521
Key * BKE_key_from_object(Object *ob)
Definition key.cc:1824
int BKE_lattice_index_from_uvw(const Lattice *lt, int u, int v, int w)
Definition lattice.cc:199
General operations, lookup, etc. for blender objects.
KeyBlock * BKE_object_shapekey_insert(Main *bmain, Object *ob, const char *name, bool from_mix)
bool BKE_object_shapekey_free(Main *bmain, Object *ob)
bool BKE_object_shapekey_remove(Main *bmain, Object *ob, KeyBlock *kb)
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
#define BLI_assert(a)
Definition BLI_assert.h:46
int BLI_findindex(const ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:586
void * BLI_findlink(const ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:534
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
MINLINE float clamp_f(float value, float min, float max)
MINLINE void copy_v3_v3(float r[3], const float a[3])
#define ELEM(...)
#define STREQ(a, b)
#define TIP_(msgid)
void DEG_id_tag_update(ID *id, unsigned int flags)
void DEG_relations_tag_update(Main *bmain)
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:982
@ KEY_NORMAL
@ KEYBLOCK_LOCKED_SHAPE
@ OB_MODE_EDIT
Object is a sort of wrapper for general info.
@ OB_LATTICE
@ OB_SURF
@ OB_MESH
@ OB_CURVES_LEGACY
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
KeyBlock * ED_lattice_get_edit_shape_key(const Lattice *latt)
int mesh_get_x_mirror_vert(Object *ob, Mesh *mesh_eval, int index, bool use_topology)
Definition meshtools.cc:911
void ED_mesh_report_mirror(wmOperator *op, int totmirr, int totfail)
void ED_mesh_mirror_spatial_table_begin(Object *ob, BMEditMesh *em, Mesh *mesh_eval)
void ED_mesh_mirror_spatial_table_end(Object *ob)
KeyBlock * ED_mesh_get_edit_shape_key(const Mesh *me)
Read Guarded memory(de)allocation.
#define C
Definition RandGen.cpp:29
#define ND_DRAW
Definition WM_types.hh:458
@ OPTYPE_UNDO
Definition WM_types.hh:182
@ OPTYPE_REGISTER
Definition WM_types.hh:180
ReportList * reports
Definition WM_types.hh:1025
#define NC_OBJECT
Definition WM_types.hh:376
BMesh const char void * data
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition btQuadWord.h:119
KeyBlock * ED_curve_get_edit_shape_key(const Curve *cu)
Definition editcurve.cc:99
#define ID_IS_EDITABLE(_id)
#define ID_IS_OVERRIDE_LIBRARY(_id)
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:123
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
void OBJECT_OT_shape_key_clear(wmOperatorType *ot)
static wmOperatorStatus shape_key_clear_exec(bContext *C, wmOperator *)
static bool object_shape_key_mirror(bContext *C, Object *ob, int *r_totmirr, int *r_totfail, bool use_topology)
void OBJECT_OT_shape_key_move(wmOperatorType *ot)
static void object_shape_key_add(bContext *C, Object *ob, const bool from_mix)
static bool object_shapekey_remove(Main *bmain, Object *ob)
bool shape_key_report_if_locked(const Object *obedit, ReportList *reports)
static wmOperatorStatus shape_key_retime_exec(bContext *C, wmOperator *)
bool shape_key_report_if_any_locked(Object *ob, ReportList *reports)
static bool shape_key_exists_poll(bContext *C)
Object * context_object(const bContext *C)
static wmOperatorStatus shape_key_copy_exec(bContext *C, wmOperator *)
void OBJECT_OT_shape_key_copy(wmOperatorType *ot)
static bool shape_key_mode_exists_poll(bContext *C)
static bool shape_key_move_poll(bContext *C)
static bool shape_key_mode_poll(bContext *C)
static wmOperatorStatus shape_key_remove_exec(bContext *C, wmOperator *op)
static wmOperatorStatus shape_key_add_exec(bContext *C, wmOperator *op)
bool shape_key_report_if_active_locked(Object *ob, ReportList *reports)
static bool object_is_any_shape_key_locked(Object *ob)
void OBJECT_OT_shape_key_lock(wmOperatorType *ot)
static wmOperatorStatus shape_key_lock_exec(bContext *C, wmOperator *op)
static bool shape_key_poll(bContext *C)
void OBJECT_OT_shape_key_retime(wmOperatorType *ot)
void OBJECT_OT_shape_key_add(wmOperatorType *ot)
static bool shape_key_remove_poll_property(const bContext *, wmOperator *op, const PropertyRNA *prop)
static std::string shape_key_remove_get_description(bContext *, wmOperatorType *, PointerRNA *ptr)
void OBJECT_OT_shape_key_remove(wmOperatorType *ot)
static wmOperatorStatus shape_key_move_exec(bContext *C, wmOperator *op)
static std::string shape_key_lock_get_description(bContext *, wmOperatorType *, PointerRNA *ptr)
void OBJECT_OT_shape_key_mirror(wmOperatorType *ot)
static wmOperatorStatus shape_key_mirror_exec(bContext *C, wmOperator *op)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
int RNA_enum_get(PointerRNA *ptr, const char *name)
const char * RNA_property_identifier(const PropertyRNA *prop)
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
struct Lattice * latt
Definition DNA_ID.h:404
char name[66]
Definition DNA_ID.h:415
void * data
int totkey
char type
ListBase block
struct EditLatt * editlatt
struct ReportList * reports
struct PointerRNA * ptr
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
PointerRNA * ptr
Definition wm_files.cc:4226
wmOperatorType * ot
Definition wm_files.cc:4225