52
53
#include "bpy_util.h"
53
54
#include "bpy_rna_anim.h"
58
56
/* for keyframes and drivers */
59
57
static int pyrna_struct_anim_args_parse(
60
58
PointerRNA *ptr, const char *error_prefix, const char *path,
150
148
/* internal use for insert and delete */
151
149
static int pyrna_struct_keyframe_parse(
152
150
PointerRNA *ptr, PyObject *args, PyObject *kw, const char *parse_str, const char *error_prefix,
153
const char **path_full, int *index, float *cfra, const char **group_name) /* return values */
151
const char **path_full, int *index, float *cfra, const char **group_name, int *options) /* return values */
155
static const char *kwlist[] = {"data_path", "index", "frame", "group", NULL};
153
static const char *kwlist[] = {"data_path", "index", "frame", "group", "options", NULL};
154
PyObject *pyoptions = NULL;
156
155
const char *path;
158
/* note, parse_str MUST start with 's|ifs' */
159
if (!PyArg_ParseTupleAndKeywords(args, kw, parse_str, (char **)kwlist, &path, index, cfra, group_name))
157
/* note, parse_str MUST start with 's|ifsO!' */
158
if (!PyArg_ParseTupleAndKeywords(args, kw, parse_str, (char **)kwlist, &path, index, cfra, group_name,
159
&PySet_Type, &pyoptions)) {
162
if (pyrna_struct_anim_args_parse(ptr, error_prefix, path, path_full, index) < 0)
163
if (pyrna_struct_anim_args_parse(ptr, error_prefix, path, path_full, index) == -1)
165
166
if (*cfra == FLT_MAX)
166
167
*cfra = CTX_data_scene(BPy_GetContext())->r.cfra;
169
/* flag may be null (no option currently for remove keyframes e.g.). */
170
if (pyoptions && options && (pyrna_set_to_enum_bitfield(keying_flag_items, pyoptions, options, error_prefix) == -1))
168
173
return 0; /* success */
176
181
" :arg data_path: path to the property to key, analogous to the fcurve's data path.\n"
177
182
" :type data_path: string\n"
178
" :arg index: array index of the property to key. Defaults to -1 which will key all indices or a single channel if the property is not an array.\n"
183
" :arg index: array index of the property to key. Defaults to -1 which will key all indices or a single channel "
184
"if the property is not an array.\n"
179
185
" :type index: int\n"
180
186
" :arg frame: The frame on which the keyframe is inserted, defaulting to the current frame.\n"
181
187
" :type frame: float\n"
182
188
" :arg group: The name of the group the F-Curve should be added to if it doesn't exist yet.\n"
183
189
" :type group: str\n"
190
" :arg options: Some optional flags:\n"
191
" 'NEEDED': Only insert keyframes where they're needed in the relevant F-Curves.\n"
192
" 'VISUAL': Insert keyframes based on 'visual transforms'.\n"
193
" 'XYZ_TO_RGB': Color for newly added transformation F-Curves (Location, Rotation, Scale) "
194
"and also Color is based on the transform axis.\n"
184
196
" :return: Success of keyframe insertion.\n"
185
197
" :rtype: boolean\n"
192
204
float cfra = FLT_MAX;
193
205
const char *group_name = NULL;
195
208
PYRNA_STRUCT_CHECK_OBJ(self);
197
210
if (pyrna_struct_keyframe_parse(&self->ptr, args, kw,
198
"s|ifs:bpy_struct.keyframe_insert()", "bpy_struct.keyframe_insert()",
199
&path_full, &index, &cfra, &group_name) == -1)
211
"s|ifsO!:bpy_struct.keyframe_insert()", "bpy_struct.keyframe_insert()",
212
&path_full, &index, &cfra, &group_name, &options) == -1)
207
220
BKE_reports_init(&reports, RPT_STORE);
209
result = insert_keyframe(&reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, 0);
222
result = insert_keyframe(&reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, options);
210
223
MEM_freeN((void *)path_full);
212
if (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1)
225
if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1)
215
228
return PyBool_FromLong(result);
243
256
PYRNA_STRUCT_CHECK_OBJ(self);
245
258
if (pyrna_struct_keyframe_parse(&self->ptr, args, kw,
246
"s|ifs:bpy_struct.keyframe_delete()",
259
"s|ifsO!:bpy_struct.keyframe_delete()",
247
260
"bpy_struct.keyframe_insert()",
248
&path_full, &index, &cfra, &group_name) == -1)
261
&path_full, &index, &cfra, &group_name, NULL) == -1)
258
271
result = delete_keyframe(&reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, 0);
259
272
MEM_freeN((void *)path_full);
261
if (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1)
274
if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1)
264
277
return PyBool_FromLong(result);
288
301
if (!PyArg_ParseTuple(args, "s|i:driver_add", &path, &index))
291
if (pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_add():", path, &path_full, &index) < 0) {
304
if (pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_add():", path, &path_full, &index) == -1) {
301
314
result = ANIM_add_driver(&reports, (ID *)self->ptr.id.data, path_full, index, 0, DRIVER_TYPE_PYTHON);
303
if (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1)
316
if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1)
364
377
if (!PyArg_ParseTuple(args, "s|i:driver_remove", &path, &index))
367
if (pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_remove():", path, &path_full, &index) < 0) {
380
if (pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_remove():", path, &path_full, &index) == -1) {
378
391
MEM_freeN((void *)path_full);
380
if (BPy_reports_to_error(&reports, PyExc_RuntimeError, TRUE) == -1)
393
if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1)
383
396
WM_event_add_notifier(BPy_GetContext(), NC_ANIMATION | ND_FCURVES_ORDER, NULL);