Cleanup: misc spelling fixes
[blender.git] / source / blender / python / intern / bpy_rna_anim.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16
17 /** \file
18  * \ingroup pythonintern
19  *
20  * This file defines the animation related methods used in bpy_rna.c
21  */
22
23 #include <Python.h>
24 #include <float.h> /* FLT_MAX */
25
26 #include "MEM_guardedalloc.h"
27
28 #include "BLI_utildefines.h"
29 #include "BLI_string.h"
30 #include "BLI_string_utils.h"
31
32 #include "DNA_scene_types.h"
33 #include "DNA_anim_types.h"
34
35 #include "ED_keyframing.h"
36 #include "ED_keyframes_edit.h"
37
38 #include "BKE_animsys.h"
39 #include "BKE_context.h"
40 #include "BKE_fcurve.h"
41 #include "BKE_global.h"
42 #include "BKE_idcode.h"
43 #include "BKE_library.h"
44 #include "BKE_report.h"
45
46 #include "RNA_access.h"
47 #include "RNA_enum_types.h"
48
49 #include "WM_api.h"
50 #include "WM_types.h"
51
52 #include "bpy_rna.h"
53 #include "bpy_capi_utils.h"
54 #include "bpy_rna_anim.h"
55
56 #include "../generic/python_utildefines.h"
57
58 #include "DEG_depsgraph_build.h"
59
60 /* for keyframes and drivers */
61 static int pyrna_struct_anim_args_parse_ex(PointerRNA *ptr,
62                                            const char *error_prefix,
63                                            const char *path,
64                                            const char **r_path_full,
65                                            int *r_index,
66                                            bool *r_path_no_validate)
67 {
68   const bool is_idbase = RNA_struct_is_ID(ptr->type);
69   PropertyRNA *prop;
70   PointerRNA r_ptr;
71
72   if (ptr->data == NULL) {
73     PyErr_Format(
74         PyExc_TypeError, "%.200s this struct has no data, can't be animated", error_prefix);
75     return -1;
76   }
77
78   /* full paths can only be given from ID base */
79   if (is_idbase) {
80     int path_index = -1;
81     if (RNA_path_resolve_property_full(ptr, path, &r_ptr, &prop, &path_index) == false) {
82       prop = NULL;
83     }
84     else if (path_index != -1) {
85       PyErr_Format(PyExc_ValueError,
86                    "%.200s path includes index, must be a separate argument",
87                    error_prefix,
88                    path);
89       return -1;
90     }
91     else if (ptr->id.data != r_ptr.id.data) {
92       PyErr_Format(PyExc_ValueError, "%.200s path spans ID blocks", error_prefix, path);
93       return -1;
94     }
95   }
96   else {
97     prop = RNA_struct_find_property(ptr, path);
98     r_ptr = *ptr;
99   }
100
101   if (prop == NULL) {
102     if (r_path_no_validate) {
103       *r_path_no_validate = true;
104       return -1;
105     }
106     PyErr_Format(PyExc_TypeError, "%.200s property \"%s\" not found", error_prefix, path);
107     return -1;
108   }
109
110   if (r_path_no_validate) {
111     /* Don't touch the index. */
112   }
113   else {
114     if (!RNA_property_animateable(&r_ptr, prop)) {
115       PyErr_Format(PyExc_TypeError, "%.200s property \"%s\" not animatable", error_prefix, path);
116       return -1;
117     }
118
119     if (RNA_property_array_check(prop) == 0) {
120       if ((*r_index) == -1) {
121         *r_index = 0;
122       }
123       else {
124         PyErr_Format(PyExc_TypeError,
125                      "%.200s index %d was given while property \"%s\" is not an array",
126                      error_prefix,
127                      *r_index,
128                      path);
129         return -1;
130       }
131     }
132     else {
133       int array_len = RNA_property_array_length(&r_ptr, prop);
134       if ((*r_index) < -1 || (*r_index) >= array_len) {
135         PyErr_Format(PyExc_TypeError,
136                      "%.200s index out of range \"%s\", given %d, array length is %d",
137                      error_prefix,
138                      path,
139                      *r_index,
140                      array_len);
141         return -1;
142       }
143     }
144   }
145
146   if (is_idbase) {
147     *r_path_full = BLI_strdup(path);
148   }
149   else {
150     *r_path_full = RNA_path_from_ID_to_property(&r_ptr, prop);
151
152     if (*r_path_full == NULL) {
153       PyErr_Format(PyExc_TypeError, "%.200s could not make path to \"%s\"", error_prefix, path);
154       return -1;
155     }
156   }
157
158   return 0;
159 }
160
161 static int pyrna_struct_anim_args_parse(PointerRNA *ptr,
162                                         const char *error_prefix,
163                                         const char *path,
164                                         const char **r_path_full,
165                                         int *r_index)
166 {
167   return pyrna_struct_anim_args_parse_ex(ptr, error_prefix, path, r_path_full, r_index, NULL);
168 }
169
170 /**
171  * Unlike #pyrna_struct_anim_args_parse \a r_path_full may be copied from \a path.
172  */
173 static int pyrna_struct_anim_args_parse_no_resolve(PointerRNA *ptr,
174                                                    const char *error_prefix,
175                                                    const char *path,
176                                                    const char **r_path_full)
177 {
178   const bool is_idbase = RNA_struct_is_ID(ptr->type);
179   if (is_idbase) {
180     *r_path_full = path;
181     return 0;
182   }
183   else {
184     char *path_prefix = RNA_path_from_ID_to_struct(ptr);
185     if (path_prefix == NULL) {
186       PyErr_Format(PyExc_TypeError,
187                    "%.200s could not make path for type %s",
188                    error_prefix,
189                    RNA_struct_identifier(ptr->type));
190       return -1;
191     }
192
193     if (*path == '[') {
194       *r_path_full = BLI_string_joinN(path_prefix, path);
195     }
196     else {
197       *r_path_full = BLI_string_join_by_sep_charN('.', path_prefix, path);
198     }
199     MEM_freeN(path_prefix);
200   }
201   return 0;
202 }
203
204 static int pyrna_struct_anim_args_parse_no_resolve_fallback(PointerRNA *ptr,
205                                                             const char *error_prefix,
206                                                             const char *path,
207                                                             const char **r_path_full,
208                                                             int *r_index)
209 {
210   bool path_unresolved = false;
211   if (pyrna_struct_anim_args_parse_ex(
212           ptr, error_prefix, path, r_path_full, r_index, &path_unresolved) == -1) {
213     if (path_unresolved == true) {
214       if (pyrna_struct_anim_args_parse_no_resolve(ptr, error_prefix, path, r_path_full) == -1) {
215         return -1;
216       }
217     }
218     else {
219       return -1;
220     }
221   }
222   return 0;
223 }
224
225 /* internal use for insert and delete */
226 static int pyrna_struct_keyframe_parse(PointerRNA *ptr,
227                                        PyObject *args,
228                                        PyObject *kw,
229                                        const char *parse_str,
230                                        const char *error_prefix,
231                                        /* return values */
232                                        const char **r_path_full,
233                                        int *r_index,
234                                        float *r_cfra,
235                                        const char **r_group_name,
236                                        int *r_options)
237 {
238   static const char *kwlist[] = {"data_path", "index", "frame", "group", "options", NULL};
239   PyObject *pyoptions = NULL;
240   const char *path;
241
242   /* note, parse_str MUST start with 's|ifsO!' */
243   if (!PyArg_ParseTupleAndKeywords(args,
244                                    kw,
245                                    parse_str,
246                                    (char **)kwlist,
247                                    &path,
248                                    r_index,
249                                    r_cfra,
250                                    r_group_name,
251                                    &PySet_Type,
252                                    &pyoptions)) {
253     return -1;
254   }
255
256   if (pyrna_struct_anim_args_parse(ptr, error_prefix, path, r_path_full, r_index) == -1) {
257     return -1;
258   }
259
260   if (*r_cfra == FLT_MAX) {
261     *r_cfra = CTX_data_scene(BPy_GetContext())->r.cfra;
262   }
263
264   /* flag may be null (no option currently for remove keyframes e.g.). */
265   if (r_options) {
266     if (pyoptions &&
267         (pyrna_set_to_enum_bitfield(
268              rna_enum_keying_flag_items_api, pyoptions, r_options, error_prefix) == -1)) {
269       return -1;
270     }
271
272     *r_options |= INSERTKEY_NO_USERPREF;
273   }
274
275   return 0; /* success */
276 }
277
278 char pyrna_struct_keyframe_insert_doc[] =
279     ".. method:: keyframe_insert(data_path, index=-1, frame=bpy.context.scene.frame_current, "
280     "group=\"\")\n"
281     "\n"
282     "   Insert a keyframe on the property given, adding fcurves and animation data when "
283     "necessary.\n"
284     "\n"
285     "   :arg data_path: path to the property to key, analogous to the fcurve's data path.\n"
286     "   :type data_path: string\n"
287     "   :arg index: array index of the property to key.\n"
288     "      Defaults to -1 which will key all indices or a single channel if the property is not "
289     "an array.\n"
290     "   :type index: int\n"
291     "   :arg frame: The frame on which the keyframe is inserted, defaulting to the current "
292     "frame.\n"
293     "   :type frame: float\n"
294     "   :arg group: The name of the group the F-Curve should be added to if it doesn't exist "
295     "yet.\n"
296     "   :type group: str\n"
297     "   :arg options: Optional flags:\n"
298     "\n"
299     "      - ``INSERTKEY_NEEDED`` Only insert keyframes where they're needed in the relevant "
300     "F-Curves.\n"
301     "      - ``INSERTKEY_VISUAL`` Insert keyframes based on 'visual transforms'.\n"
302     "      - ``INSERTKEY_XYZ_TO_RGB`` Color for newly added transformation F-Curves (Location, "
303     "Rotation, Scale) is based on the transform axis.\n"
304     "      - ``INSERTKEY_REPLACE`` Only replace already existing keyframes.\n"
305     "      - ``INSERTKEY_AVAILABLE`` Only insert into already existing F-Curves.\n"
306     "      - ``INSERTKEY_CYCLE_AWARE`` Take cyclic extrapolation into account "
307     "(Cycle-Aware Keying option).\n"
308     "   :type flag: set\n"
309     "   :return: Success of keyframe insertion.\n"
310     "   :rtype: boolean\n";
311 PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyObject *kw)
312 {
313   /* args, pyrna_struct_keyframe_parse handles these */
314   const char *path_full = NULL;
315   int index = -1;
316   float cfra = FLT_MAX;
317   const char *group_name = NULL;
318   char keytype = BEZT_KEYTYPE_KEYFRAME; /* XXX: Expose this as a one-off option... */
319   int options = 0;
320
321   PYRNA_STRUCT_CHECK_OBJ(self);
322
323   if (pyrna_struct_keyframe_parse(&self->ptr,
324                                   args,
325                                   kw,
326                                   "s|ifsO!:bpy_struct.keyframe_insert()",
327                                   "bpy_struct.keyframe_insert()",
328                                   &path_full,
329                                   &index,
330                                   &cfra,
331                                   &group_name,
332                                   &options) == -1) {
333     return NULL;
334   }
335   else if (self->ptr.type == &RNA_NlaStrip) {
336     /* Handle special properties for NLA Strips, whose F-Curves are stored on the
337      * strips themselves. These are stored separately or else the properties will
338      * not have any effect.
339      */
340     ReportList reports;
341     short result = 0;
342
343     PointerRNA ptr = self->ptr;
344     PropertyRNA *prop = NULL;
345     const char *prop_name;
346
347     BKE_reports_init(&reports, RPT_STORE);
348
349     /* Retrieve the property identifier from the full path, since we can't get it any other way */
350     prop_name = strrchr(path_full, '.');
351     if ((prop_name >= path_full) && (prop_name + 1 < path_full + strlen(path_full))) {
352       prop = RNA_struct_find_property(&ptr, prop_name + 1);
353     }
354
355     if (prop) {
356       NlaStrip *strip = (NlaStrip *)ptr.data;
357       FCurve *fcu = list_find_fcurve(&strip->fcurves, RNA_property_identifier(prop), index);
358
359       result = insert_keyframe_direct(&reports, ptr, prop, fcu, cfra, keytype, NULL, options);
360     }
361     else {
362       BKE_reportf(&reports, RPT_ERROR, "Could not resolve path (%s)", path_full);
363     }
364     MEM_freeN((void *)path_full);
365
366     if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1) {
367       return NULL;
368     }
369
370     return PyBool_FromLong(result);
371   }
372   else {
373     ID *id = self->ptr.id.data;
374     ReportList reports;
375     short result;
376
377     BKE_reports_init(&reports, RPT_STORE);
378
379     BLI_assert(BKE_id_is_in_global_main(id));
380     result = insert_keyframe(
381         G_MAIN, &reports, id, NULL, group_name, path_full, index, cfra, keytype, NULL, options);
382     MEM_freeN((void *)path_full);
383
384     if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1) {
385       return NULL;
386     }
387
388     return PyBool_FromLong(result);
389   }
390 }
391
392 char pyrna_struct_keyframe_delete_doc[] =
393     ".. method:: keyframe_delete(data_path, index=-1, frame=bpy.context.scene.frame_current, "
394     "group=\"\")\n"
395     "\n"
396     "   Remove a keyframe from this properties fcurve.\n"
397     "\n"
398     "   :arg data_path: path to the property to remove a key, analogous to the fcurve's data "
399     "path.\n"
400     "   :type data_path: string\n"
401     "   :arg index: array index of the property to remove a key. Defaults to -1 removing all "
402     "indices or a single channel if the property is not an array.\n"
403     "   :type index: int\n"
404     "   :arg frame: The frame on which the keyframe is deleted, defaulting to the current frame.\n"
405     "   :type frame: float\n"
406     "   :arg group: The name of the group the F-Curve should be added to if it doesn't exist "
407     "yet.\n"
408     "   :type group: str\n"
409     "   :return: Success of keyframe deleation.\n"
410     "   :rtype: boolean\n";
411 PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args, PyObject *kw)
412 {
413   /* args, pyrna_struct_keyframe_parse handles these */
414   const char *path_full = NULL;
415   int index = -1;
416   float cfra = FLT_MAX;
417   const char *group_name = NULL;
418
419   PYRNA_STRUCT_CHECK_OBJ(self);
420
421   if (pyrna_struct_keyframe_parse(&self->ptr,
422                                   args,
423                                   kw,
424                                   "s|ifsO!:bpy_struct.keyframe_delete()",
425                                   "bpy_struct.keyframe_insert()",
426                                   &path_full,
427                                   &index,
428                                   &cfra,
429                                   &group_name,
430                                   NULL) == -1) {
431     return NULL;
432   }
433   else if (self->ptr.type == &RNA_NlaStrip) {
434     /* Handle special properties for NLA Strips, whose F-Curves are stored on the
435      * strips themselves. These are stored separately or else the properties will
436      * not have any effect.
437      */
438     ReportList reports;
439     short result = 0;
440
441     PointerRNA ptr = self->ptr;
442     PropertyRNA *prop = NULL;
443     const char *prop_name;
444
445     BKE_reports_init(&reports, RPT_STORE);
446
447     /* Retrieve the property identifier from the full path, since we can't get it any other way */
448     prop_name = strrchr(path_full, '.');
449     if ((prop_name >= path_full) && (prop_name + 1 < path_full + strlen(path_full))) {
450       prop = RNA_struct_find_property(&ptr, prop_name + 1);
451     }
452
453     if (prop) {
454       ID *id = ptr.id.data;
455       NlaStrip *strip = (NlaStrip *)ptr.data;
456       FCurve *fcu = list_find_fcurve(&strip->fcurves, RNA_property_identifier(prop), index);
457
458       BLI_assert(fcu !=
459                  NULL); /* NOTE: This should be true, or else we wouldn't be able to get here */
460
461       if (BKE_fcurve_is_protected(fcu)) {
462         BKE_reportf(
463             &reports,
464             RPT_WARNING,
465             "Not deleting keyframe for locked F-Curve for NLA Strip influence on %s - %s '%s'",
466             strip->name,
467             BKE_idcode_to_name(GS(id->name)),
468             id->name + 2);
469       }
470       else {
471         /* remove the keyframe directly
472          * NOTE: cannot use delete_keyframe_fcurve(), as that will free the curve,
473          *       and delete_keyframe() expects the FCurve to be part of an action
474          */
475         bool found = false;
476         int i;
477
478         /* try to find index of beztriple to get rid of */
479         i = binarysearch_bezt_index(fcu->bezt, cfra, fcu->totvert, &found);
480         if (found) {
481           /* delete the key at the index (will sanity check + do recalc afterwards) */
482           delete_fcurve_key(fcu, i, 1);
483           result = true;
484         }
485       }
486     }
487     else {
488       BKE_reportf(&reports, RPT_ERROR, "Could not resolve path (%s)", path_full);
489     }
490     MEM_freeN((void *)path_full);
491
492     if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1) {
493       return NULL;
494     }
495
496     return PyBool_FromLong(result);
497   }
498   else {
499     short result;
500     ReportList reports;
501
502     BKE_reports_init(&reports, RPT_STORE);
503
504     result = delete_keyframe(
505         G.main, &reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, 0);
506     MEM_freeN((void *)path_full);
507
508     if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1) {
509       return NULL;
510     }
511
512     return PyBool_FromLong(result);
513   }
514 }
515
516 char pyrna_struct_driver_add_doc[] =
517     ".. method:: driver_add(path, index=-1)\n"
518     "\n"
519     "   Adds driver(s) to the given property\n"
520     "\n"
521     "   :arg path: path to the property to drive, analogous to the fcurve's data path.\n"
522     "   :type path: string\n"
523     "   :arg index: array index of the property drive. Defaults to -1 for all indices or a single "
524     "channel if the property is not an array.\n"
525     "   :type index: int\n"
526     "   :return: The driver(s) added.\n"
527     "   :rtype: :class:`bpy.types.FCurve` or list if index is -1 with an array property.\n";
528 PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args)
529 {
530   const char *path, *path_full;
531   int index = -1;
532
533   PYRNA_STRUCT_CHECK_OBJ(self);
534
535   if (!PyArg_ParseTuple(args, "s|i:driver_add", &path, &index)) {
536     return NULL;
537   }
538
539   if (pyrna_struct_anim_args_parse(
540           &self->ptr, "bpy_struct.driver_add():", path, &path_full, &index) == -1) {
541     return NULL;
542   }
543   else {
544     PyObject *ret = NULL;
545     ReportList reports;
546     int result;
547
548     BKE_reports_init(&reports, RPT_STORE);
549
550     result = ANIM_add_driver(&reports,
551                              (ID *)self->ptr.id.data,
552                              path_full,
553                              index,
554                              CREATEDRIVER_WITH_FMODIFIER,
555                              DRIVER_TYPE_PYTHON);
556
557     if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1) {
558       return NULL;
559     }
560
561     if (result) {
562       ID *id = self->ptr.id.data;
563       AnimData *adt = BKE_animdata_from_id(id);
564       FCurve *fcu;
565
566       PointerRNA tptr;
567
568       if (index == -1) { /* all, use a list */
569         int i = 0;
570         ret = PyList_New(0);
571         while ((fcu = list_find_fcurve(&adt->drivers, path_full, i++))) {
572           RNA_pointer_create(id, &RNA_FCurve, fcu, &tptr);
573           PyList_APPEND(ret, pyrna_struct_CreatePyObject(&tptr));
574         }
575       }
576       else {
577         fcu = list_find_fcurve(&adt->drivers, path_full, index);
578         RNA_pointer_create(id, &RNA_FCurve, fcu, &tptr);
579         ret = pyrna_struct_CreatePyObject(&tptr);
580       }
581
582       bContext *context = BPy_GetContext();
583       WM_event_add_notifier(BPy_GetContext(), NC_ANIMATION | ND_FCURVES_ORDER, NULL);
584       DEG_relations_tag_update(CTX_data_main(context));
585     }
586     else {
587       /* XXX, should be handled by reports, */
588       PyErr_SetString(PyExc_TypeError,
589                       "bpy_struct.driver_add(): failed because of an internal error");
590       return NULL;
591     }
592
593     MEM_freeN((void *)path_full);
594
595     return ret;
596   }
597 }
598
599 char pyrna_struct_driver_remove_doc[] =
600     ".. method:: driver_remove(path, index=-1)\n"
601     "\n"
602     "   Remove driver(s) from the given property\n"
603     "\n"
604     "   :arg path: path to the property to drive, analogous to the fcurve's data path.\n"
605     "   :type path: string\n"
606     "   :arg index: array index of the property drive. Defaults to -1 for all indices or a single "
607     "channel if the property is not an array.\n"
608     "   :type index: int\n"
609     "   :return: Success of driver removal.\n"
610     "   :rtype: boolean\n";
611 PyObject *pyrna_struct_driver_remove(BPy_StructRNA *self, PyObject *args)
612 {
613   const char *path, *path_full;
614   int index = -1;
615
616   PYRNA_STRUCT_CHECK_OBJ(self);
617
618   if (!PyArg_ParseTuple(args, "s|i:driver_remove", &path, &index)) {
619     return NULL;
620   }
621
622   if (pyrna_struct_anim_args_parse_no_resolve_fallback(
623           &self->ptr, "bpy_struct.driver_remove():", path, &path_full, &index) == -1) {
624     return NULL;
625   }
626   else {
627     short result;
628     ReportList reports;
629
630     BKE_reports_init(&reports, RPT_STORE);
631
632     result = ANIM_remove_driver(&reports, (ID *)self->ptr.id.data, path_full, index, 0);
633
634     if (path != path_full) {
635       MEM_freeN((void *)path_full);
636     }
637
638     if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1) {
639       return NULL;
640     }
641
642     bContext *context = BPy_GetContext();
643     WM_event_add_notifier(context, NC_ANIMATION | ND_FCURVES_ORDER, NULL);
644     DEG_relations_tag_update(CTX_data_main(context));
645
646     return PyBool_FromLong(result);
647   }
648 }