36 #include "RNA_prototypes.h"
45 #include "../generic/py_capi_rna.h"
46 #include "../generic/python_utildefines.h"
52 const char *error_prefix,
54 const char **r_path_full,
56 bool *r_path_no_validate)
64 PyExc_TypeError,
"%.200s this struct has no data, can't be animated", error_prefix);
74 else if (path_index != -1) {
75 PyErr_Format(PyExc_ValueError,
76 "%.200s path includes index, must be a separate argument",
82 PyErr_Format(PyExc_ValueError,
"%.200s path spans ID blocks", error_prefix, path);
92 if (r_path_no_validate) {
93 *r_path_no_validate =
true;
96 PyErr_Format(PyExc_TypeError,
"%.200s property \"%s\" not found", error_prefix, path);
100 if (r_path_no_validate) {
105 PyErr_Format(PyExc_TypeError,
"%.200s property \"%s\" not animatable", error_prefix, path);
110 if ((*r_index) == -1) {
114 PyErr_Format(PyExc_TypeError,
115 "%.200s index %d was given while property \"%s\" is not an array",
124 if ((*r_index) < -1 || (*r_index) >= array_len) {
125 PyErr_Format(PyExc_TypeError,
126 "%.200s index out of range \"%s\", given %d, array length is %d",
142 if (*r_path_full ==
NULL) {
143 PyErr_Format(PyExc_TypeError,
"%.200s could not make path to \"%s\"", error_prefix, path);
152 const char *error_prefix,
154 const char **r_path_full,
164 const char *error_prefix,
166 const char **r_path_full)
175 if (path_prefix ==
NULL) {
176 PyErr_Format(PyExc_TypeError,
177 "%.200s could not make path for type %s",
195 const char *error_prefix,
197 const char **r_path_full,
200 bool path_unresolved =
false;
202 ptr, error_prefix, path, r_path_full, r_index, &path_unresolved) == -1) {
203 if (path_unresolved ==
true) {
219 const char *parse_str,
220 const char *error_prefix,
222 const char **r_path_full,
225 const char **r_group_name,
228 static const char *kwlist[] = {
"data_path",
"index",
"frame",
"group",
"options",
NULL};
229 PyObject *pyoptions =
NULL;
233 if (!PyArg_ParseTupleAndKeywords(args,
250 if (*r_cfra == FLT_MAX) {
269 ".. method:: keyframe_insert(data_path, index=-1, frame=bpy.context.scene.frame_current, "
270 "group=\"\", options=set())\n"
272 " Insert a keyframe on the property given, adding fcurves and animation data when "
275 " :arg data_path: path to the property to key, analogous to the fcurve's data path.\n"
276 " :type data_path: string\n"
277 " :arg index: array index of the property to key.\n"
278 " Defaults to -1 which will key all indices or a single channel if the property is not "
280 " :type index: int\n"
281 " :arg frame: The frame on which the keyframe is inserted, defaulting to the current "
283 " :type frame: float\n"
284 " :arg group: The name of the group the F-Curve should be added to if it doesn't exist "
286 " :type group: str\n"
287 " :arg options: Optional set of flags:\n"
289 " - ``INSERTKEY_NEEDED`` Only insert keyframes where they're needed in the relevant "
291 " - ``INSERTKEY_VISUAL`` Insert keyframes based on 'visual transforms'.\n"
292 " - ``INSERTKEY_XYZ_TO_RGB`` Color for newly added transformation F-Curves (Location, "
293 "Rotation, Scale) is based on the transform axis.\n"
294 " - ``INSERTKEY_REPLACE`` Only replace already existing keyframes.\n"
295 " - ``INSERTKEY_AVAILABLE`` Only insert into already existing F-Curves.\n"
296 " - ``INSERTKEY_CYCLE_AWARE`` Take cyclic extrapolation into account "
297 "(Cycle-Aware Keying option).\n"
299 " :return: Success of keyframe insertion.\n"
300 " :rtype: boolean\n";
304 const char *path_full =
NULL;
306 float cfra = FLT_MAX;
307 const char *group_name =
NULL;
316 "s|$ifsO!:bpy_struct.keyframe_insert()",
317 "bpy_struct.keyframe_insert()",
343 if (
self->ptr.type == &RNA_NlaStrip) {
351 const char *prop_name;
354 prop_name = strrchr(path_full,
'.');
355 if ((prop_name >= path_full) && (prop_name + 1 < path_full + strlen(path_full))) {
363 &reports,
ptr, prop, fcu, &anim_eval_context, keytype,
NULL,
options);
370 ID *
id =
self->ptr.owner_id;
396 return PyBool_FromLong(
result);
400 ".. method:: keyframe_delete(data_path, index=-1, frame=bpy.context.scene.frame_current, "
403 " Remove a keyframe from this properties fcurve.\n"
405 " :arg data_path: path to the property to remove a key, analogous to the fcurve's data "
407 " :type data_path: string\n"
408 " :arg index: array index of the property to remove a key. Defaults to -1 removing all "
409 "indices or a single channel if the property is not an array.\n"
410 " :type index: int\n"
411 " :arg frame: The frame on which the keyframe is deleted, defaulting to the current frame.\n"
412 " :type frame: float\n"
413 " :arg group: The name of the group the F-Curve should be added to if it doesn't exist "
415 " :type group: str\n"
416 " :return: Success of keyframe deletion.\n"
417 " :rtype: boolean\n";
421 const char *path_full =
NULL;
423 float cfra = FLT_MAX;
424 const char *group_name =
NULL;
431 "s|$ifsO!:bpy_struct.keyframe_delete()",
432 "bpy_struct.keyframe_insert()",
446 if (
self->ptr.type == &RNA_NlaStrip) {
454 const char *prop_name;
457 prop_name = strrchr(path_full,
'.');
458 if ((prop_name >= path_full) && (prop_name + 1 < path_full + strlen(path_full))) {
474 "Not deleting keyframe for locked F-Curve for NLA Strip influence on %s - %s '%s'",
503 G.main, &reports,
self->ptr.owner_id,
NULL, path_full, index, cfra) != 0);
512 return PyBool_FromLong(
result);
516 ".. method:: driver_add(path, index=-1)\n"
518 " Adds driver(s) to the given property\n"
520 " :arg path: path to the property to drive, analogous to the fcurve's data path.\n"
521 " :type path: string\n"
522 " :arg index: array index of the property drive. Defaults to -1 for all indices or a single "
523 "channel if the property is not an array.\n"
524 " :type index: int\n"
525 " :return: The driver(s) added.\n"
526 " :rtype: :class:`bpy.types.FCurve` or list if index is -1 with an array property.\n";
529 const char *path, *path_full;
534 if (!PyArg_ParseTuple(args,
"s|i:driver_add", &path, &index)) {
539 &
self->ptr,
"bpy_struct.driver_add():", path, &path_full, &index) == -1) {
561 ID *
id =
self->ptr.owner_id;
587 PyErr_SetString(PyExc_TypeError,
588 "bpy_struct.driver_add(): failed because of an internal error");
598 ".. method:: driver_remove(path, index=-1)\n"
600 " Remove driver(s) from the given property\n"
602 " :arg path: path to the property to drive, analogous to the fcurve's data path.\n"
603 " :type path: string\n"
604 " :arg index: array index of the property drive. Defaults to -1 for all indices or a single "
605 "channel if the property is not an array.\n"
606 " :type index: int\n"
607 " :return: Success of driver removal.\n"
608 " :rtype: boolean\n";
611 const char *path, *path_full;
616 if (!PyArg_ParseTuple(args,
"s|i:driver_remove", &path, &index)) {
621 &
self->ptr,
"bpy_struct.driver_remove():", path, &path_full, &index) == -1) {
632 if (path != path_full) {
644 return PyBool_FromLong(
result);
struct AnimData * BKE_animdata_from_id(const struct ID *id)
AnimationEvalContext BKE_animsys_eval_context_construct(struct Depsgraph *depsgraph, float eval_time)
struct Scene * CTX_data_scene(const bContext *C)
struct Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
struct Main * CTX_data_main(const bContext *C)
int BKE_fcurve_bezt_binarysearch_index(const struct BezTriple array[], float frame, int arraylen, bool *r_replace)
bool BKE_fcurve_is_protected(struct FCurve *fcu)
void BKE_fcurve_handles_recalc(struct FCurve *fcu)
void BKE_fcurve_delete_key(struct FCurve *fcu, int index)
struct FCurve * BKE_fcurve_find(ListBase *list, const char rna_path[], int array_index)
const char * BKE_idtype_idcode_to_name(short idcode)
bool BKE_id_is_in_global_main(struct ID *id)
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
void BKE_reports_init(ReportList *reports, int flag)
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL() ATTR_MALLOC
#define BLI_string_joinN(...)
#define BLI_string_join_by_sep_charN(sep,...)
struct Depsgraph Depsgraph
void DEG_relations_tag_update(struct Main *bmain)
@ CREATEDRIVER_WITH_FMODIFIER
Read Guarded memory(de)allocation.
short BPy_reports_to_error(ReportList *reports, PyObject *exception, const bool clear)
struct bContext * BPY_context_get(void)
PyObject * pyrna_struct_CreatePyObject(PointerRNA *ptr)
#define PYRNA_STRUCT_CHECK_OBJ(obj)
PyObject * pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyObject *kw)
char pyrna_struct_driver_add_doc[]
char pyrna_struct_keyframe_insert_doc[]
static int pyrna_struct_anim_args_parse_no_resolve(PointerRNA *ptr, const char *error_prefix, const char *path, const char **r_path_full)
PyObject * pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args, PyObject *kw)
static int pyrna_struct_anim_args_parse_ex(PointerRNA *ptr, const char *error_prefix, const char *path, const char **r_path_full, int *r_index, bool *r_path_no_validate)
static int pyrna_struct_keyframe_parse(PointerRNA *ptr, PyObject *args, PyObject *kw, const char *parse_str, const char *error_prefix, const char **r_path_full, int *r_index, float *r_cfra, const char **r_group_name, int *r_options)
char pyrna_struct_driver_remove_doc[]
static int pyrna_struct_anim_args_parse_no_resolve_fallback(PointerRNA *ptr, const char *error_prefix, const char *path, const char **r_path_full, int *r_index)
char pyrna_struct_keyframe_delete_doc[]
PyObject * pyrna_struct_driver_remove(BPy_StructRNA *self, PyObject *args)
static int pyrna_struct_anim_args_parse(PointerRNA *ptr, const char *error_prefix, const char *path, const char **r_path_full, int *r_index)
PyObject * pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args)
CCL_NAMESPACE_BEGIN struct Options options
const Depsgraph * depsgraph
bool ANIM_remove_driver(ReportList *UNUSED(reports), ID *id, const char rna_path[], int array_index, short UNUSED(flag))
int ANIM_add_driver(ReportList *reports, ID *id, const char rna_path[], int array_index, short flag, int type)
Main Driver Management API calls.
int delete_keyframe(Main *bmain, ReportList *reports, ID *id, bAction *act, const char rna_path[], int array_index, float cfra)
Main Delete Key-Framing API call.
bool insert_keyframe_direct(ReportList *reports, PointerRNA ptr, PropertyRNA *prop, FCurve *fcu, const AnimationEvalContext *anim_eval_context, eBezTriple_KeyframeType keytype, struct NlaKeyframingContext *nla_context, eInsertKeyFlags flag)
int insert_keyframe(Main *bmain, ReportList *reports, ID *id, bAction *act, const char group[], const char rna_path[], int array_index, const AnimationEvalContext *anim_eval_context, eBezTriple_KeyframeType keytype, ListBase *nla_cache, eInsertKeyFlags flag)
void(* MEM_freeN)(void *vmemh)
int pyrna_enum_bitfield_from_set(const EnumPropertyItem *items, PyObject *value, int *r_value, const char *error_prefix)
const char * RNA_struct_identifier(const StructRNA *type)
bool RNA_property_array_check(PropertyRNA *prop)
void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
bool RNA_struct_is_ID(const StructRNA *type)
const char * RNA_property_identifier(const PropertyRNA *prop)
bool RNA_property_animateable(const PointerRNA *ptr, PropertyRNA *prop)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
const EnumPropertyItem rna_enum_keying_flag_items_api[]
char * RNA_path_from_ID_to_struct(const PointerRNA *ptr)
char * RNA_path_from_ID_to_property(const PointerRNA *ptr, PropertyRNA *prop)
bool RNA_path_resolve_property_full(const PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop, int *r_index)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)