Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2011-03-02 07:51:43 +0300
committerCampbell Barton <ideasman42@gmail.com>2011-03-02 07:51:43 +0300
commite2304a4dbbf320d268581536cdc9c3e8f66cc7c3 (patch)
treef84c7b417e42580fbc69b7e8e4c36695844fb0f8 /source/blender/python
parent21067886aaa9607f0ab345c8f52dbdb9c2818033 (diff)
move anim functions out of bpy_rna.c, its getting too big.
Diffstat (limited to 'source/blender/python')
-rw-r--r--source/blender/python/intern/CMakeLists.txt2
-rw-r--r--source/blender/python/intern/bpy.c2
-rw-r--r--source/blender/python/intern/bpy_interface.c2
-rw-r--r--source/blender/python/intern/bpy_operator.c3
-rw-r--r--source/blender/python/intern/bpy_operator_wrap.c1
-rw-r--r--source/blender/python/intern/bpy_props.c5
-rw-r--r--source/blender/python/intern/bpy_rna.c334
-rw-r--r--source/blender/python/intern/bpy_rna.h40
-rw-r--r--source/blender/python/intern/bpy_rna_anim.c353
-rw-r--r--source/blender/python/intern/bpy_rna_anim.h37
-rw-r--r--source/blender/python/intern/bpy_rna_array.c4
-rw-r--r--source/blender/python/intern/bpy_rna_callback.c4
12 files changed, 452 insertions, 335 deletions
diff --git a/source/blender/python/intern/CMakeLists.txt b/source/blender/python/intern/CMakeLists.txt
index 123c8e5b3e0..bf91fd90744 100644
--- a/source/blender/python/intern/CMakeLists.txt
+++ b/source/blender/python/intern/CMakeLists.txt
@@ -46,6 +46,7 @@ set(SRC
bpy_operator_wrap.c
bpy_props.c
bpy_rna.c
+ bpy_rna_anim.c
bpy_rna_array.c
bpy_rna_callback.c
bpy_traceback.c
@@ -59,6 +60,7 @@ set(SRC
bpy_operator_wrap.h
bpy_props.h
bpy_rna.h
+ bpy_rna_anim.h
bpy_rna_callback.h
bpy_traceback.h
bpy_util.h
diff --git a/source/blender/python/intern/bpy.c b/source/blender/python/intern/bpy.c
index 1f66e106374..589da5b3cb7 100644
--- a/source/blender/python/intern/bpy.c
+++ b/source/blender/python/intern/bpy.c
@@ -48,6 +48,8 @@
#include "BKE_global.h" /* XXX, G.main only */
+#include "RNA_access.h"
+
#include "MEM_guardedalloc.h"
/* external util modules */
diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c
index ade7ff62519..03d5f528670 100644
--- a/source/blender/python/intern/bpy_interface.c
+++ b/source/blender/python/intern/bpy_interface.c
@@ -37,6 +37,8 @@
#include "MEM_guardedalloc.h"
+#include "RNA_types.h"
+
#include "bpy.h"
#include "bpy_rna.h"
#include "bpy_util.h"
diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c
index e4df94cfbc0..73a8deb1b97 100644
--- a/source/blender/python/intern/bpy_operator.c
+++ b/source/blender/python/intern/bpy_operator.c
@@ -34,6 +34,8 @@
#include <Python.h>
+#include "RNA_types.h"
+
#include "bpy_operator.h"
#include "bpy_operator_wrap.h"
#include "bpy_rna.h" /* for setting arg props only - pyrna_py_to_prop() */
@@ -41,6 +43,7 @@
#include "BLI_utildefines.h"
+#include "RNA_access.h"
#include "RNA_enum_types.h"
#include "WM_api.h"
diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c
index 78b731fdde1..0269625d906 100644
--- a/source/blender/python/intern/bpy_operator_wrap.c
+++ b/source/blender/python/intern/bpy_operator_wrap.c
@@ -36,6 +36,7 @@
#include "BLI_utildefines.h"
+#include "RNA_access.h"
#include "RNA_define.h"
#include "bpy_rna.h"
diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c
index bae32090529..09c62f8b2c8 100644
--- a/source/blender/python/intern/bpy_props.c
+++ b/source/blender/python/intern/bpy_props.c
@@ -29,12 +29,17 @@
#include <Python.h>
+#include "RNA_types.h"
+
#include "bpy_props.h"
#include "bpy_rna.h"
#include "bpy_util.h"
#include "BLI_utildefines.h"
+#include "BKE_idprop.h"
+
+#include "RNA_access.h"
#include "RNA_define.h" /* for defining our own rna */
#include "RNA_enum_types.h"
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index b1338f3b82d..32a1f387103 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -32,7 +32,10 @@
#include <stddef.h>
#include <float.h> /* FLT_MIN/MAX */
+#include "RNA_types.h"
+
#include "bpy_rna.h"
+#include "bpy_rna_anim.h"
#include "bpy_props.h"
#include "bpy_util.h"
#include "bpy_rna_callback.h"
@@ -44,6 +47,7 @@
#include "BLI_dynstr.h"
#include "BLI_string.h"
#include "BLI_listbase.h"
+#include "BLI_math_rotation.h"
#include "BLI_utildefines.h"
#ifdef USE_PYRNA_INVALIDATE_GC
@@ -52,6 +56,7 @@
#include "RNA_enum_types.h"
#include "RNA_define.h" /* RNA_def_property_free_identifier */
+#include "RNA_access.h"
#include "MEM_guardedalloc.h"
@@ -59,15 +64,11 @@
#include "BKE_context.h"
#include "BKE_global.h" /* evil G.* */
#include "BKE_report.h"
+#include "BKE_idprop.h"
#include "BKE_animsys.h"
#include "BKE_fcurve.h"
-/* only for keyframing */
-#include "DNA_scene_types.h"
-#include "DNA_anim_types.h"
-#include "ED_keyframing.h"
-
#include "../generic/IDProp.h" /* for IDprop lookups */
#include "../generic/py_capi_utils.h"
@@ -77,16 +78,7 @@
static PyObject *pyrna_prop_collection_values(BPy_PropertyRNA *self);
-#define PYRNA_STRUCT_CHECK_OBJ(obj) if(pyrna_struct_validity_check(obj) == -1) { return NULL; }
-#define PYRNA_STRUCT_CHECK_INT(obj) if(pyrna_struct_validity_check(obj) == -1) { return -1; }
-
-#define PYRNA_PROP_CHECK_OBJ(obj) if(pyrna_prop_validity_check(obj) == -1) { return NULL; }
-#define PYRNA_PROP_CHECK_INT(obj) if(pyrna_prop_validity_check(obj) == -1) { return -1; }
-
-#define PYRNA_STRUCT_IS_VALID(pysrna) (((BPy_StructRNA *)(pysrna))->ptr.type != NULL)
-#define PYRNA_PROP_IS_VALID(pysrna) (((BPy_PropertyRNA *)(pysrna))->ptr.type != NULL)
-
-static int pyrna_struct_validity_check(BPy_StructRNA *pysrna)
+int pyrna_struct_validity_check(BPy_StructRNA *pysrna)
{
if(pysrna->ptr.type)
return 0;
@@ -94,7 +86,7 @@ static int pyrna_struct_validity_check(BPy_StructRNA *pysrna)
return -1;
}
-static int pyrna_prop_validity_check(BPy_PropertyRNA *self)
+int pyrna_prop_validity_check(BPy_PropertyRNA *self)
{
if(self->ptr.type)
return 0;
@@ -527,7 +519,7 @@ static short pyrna_rotation_euler_order_get(PointerRNA *ptr, PropertyRNA **prop_
if(*prop_eul_order) {
short order= RNA_property_enum_get(ptr, *prop_eul_order);
- if (order >= ROT_MODE_XYZ && order <= ROT_MODE_ZYX) /* could be quat or axisangle */
+ if (order >= EULER_ORDER_XYZ && order <= EULER_ORDER_ZYX) /* could be quat or axisangle */
return order;
}
@@ -606,14 +598,14 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop)
if(is_thick) {
/* attempt to get order, only needed for thick types since wrapped with update via callbacks */
PropertyRNA *prop_eul_order= NULL;
- short order= pyrna_rotation_euler_order_get(ptr, &prop_eul_order, ROT_MODE_XYZ);
+ short order= pyrna_rotation_euler_order_get(ptr, &prop_eul_order, EULER_ORDER_XYZ);
ret= newEulerObject(NULL, order, Py_NEW, NULL); // TODO, get order from RNA
RNA_property_float_get_array(ptr, prop, ((EulerObject *)ret)->eul);
}
else {
/* order will be updated from callback on use */
- PyObject *eul_cb= newEulerObject_cb(ret, ROT_MODE_XYZ, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_EUL); // TODO, get order from RNA
+ PyObject *eul_cb= newEulerObject_cb(ret, EULER_ORDER_XYZ, mathutils_rna_array_cb_index, MATHUTILS_CB_SUBTYPE_EUL); // TODO, get order from RNA
Py_DECREF(ret); /* the euler owns now */
ret= eul_cb; /* return the euler instead */
}
@@ -2436,308 +2428,6 @@ static PyObject *pyrna_struct_values(BPy_PropertyRNA *self)
return BPy_Wrap_GetValues(self->ptr.id.data, group);
}
-/* for keyframes and drivers */
-static int pyrna_struct_anim_args_parse(PointerRNA *ptr, const char *error_prefix, const char *path,
- const char **path_full, int *index)
-{
- const int is_idbase= RNA_struct_is_ID(ptr->type);
- PropertyRNA *prop;
- PointerRNA r_ptr;
-
- if (ptr->data==NULL) {
- PyErr_Format(PyExc_TypeError, "%.200s this struct has no data, can't be animated", error_prefix);
- return -1;
- }
-
- /* full paths can only be given from ID base */
- if(is_idbase) {
- int r_index= -1;
- if(RNA_path_resolve_full(ptr, path, &r_ptr, &prop, &r_index)==0) {
- prop= NULL;
- }
- else if(r_index != -1) {
- PyErr_Format(PyExc_ValueError, "%.200s path includes index, must be a separate argument", error_prefix, path);
- return -1;
- }
- else if(ptr->id.data != r_ptr.id.data) {
- PyErr_Format(PyExc_ValueError, "%.200s path spans ID blocks", error_prefix, path);
- return -1;
- }
- }
- else {
- prop = RNA_struct_find_property(ptr, path);
- r_ptr= *ptr;
- }
-
- if (prop==NULL) {
- PyErr_Format(PyExc_TypeError, "%.200s property \"%s\" not found", error_prefix, path);
- return -1;
- }
-
- if (!RNA_property_animateable(&r_ptr, prop)) {
- PyErr_Format(PyExc_TypeError, "%.200s property \"%s\" not animatable", error_prefix, path);
- return -1;
- }
-
- if(RNA_property_array_check(&r_ptr, prop) == 0) {
- if((*index) == -1) {
- *index= 0;
- }
- else {
- PyErr_Format(PyExc_TypeError, "%.200s index %d was given while property \"%s\" is not an array", error_prefix, *index, path);
- return -1;
- }
- }
- else {
- int array_len= RNA_property_array_length(&r_ptr, prop);
- if((*index) < -1 || (*index) >= array_len) {
- PyErr_Format(PyExc_TypeError, "%.200s index out of range \"%s\", given %d, array length is %d", error_prefix, path, *index, array_len);
- return -1;
- }
- }
-
- if(is_idbase) {
- *path_full= BLI_strdup(path);
- }
- else {
- *path_full= RNA_path_from_ID_to_property(&r_ptr, prop);
-
- if (*path_full==NULL) {
- PyErr_Format(PyExc_TypeError, "%.200s could not make path to \"%s\"", error_prefix, path);
- return -1;
- }
- }
-
- return 0;
-}
-
-/* internal use for insert and delete */
-static int pyrna_struct_keyframe_parse(PointerRNA *ptr, PyObject *args, PyObject *kw, const char *parse_str, const char *error_prefix,
- const char **path_full, int *index, float *cfra, const char **group_name) /* return values */
-{
- static const char *kwlist[] = {"data_path", "index", "frame", "group", NULL};
- const char *path;
-
- /* note, parse_str MUST start with 's|ifs' */
- if (!PyArg_ParseTupleAndKeywords(args, kw, parse_str, (char **)kwlist, &path, index, cfra, group_name))
- return -1;
-
- if(pyrna_struct_anim_args_parse(ptr, error_prefix, path, path_full, index) < 0)
- return -1;
-
- if(*cfra==FLT_MAX)
- *cfra= CTX_data_scene(BPy_GetContext())->r.cfra;
-
- return 0; /* success */
-}
-
-static char pyrna_struct_keyframe_insert_doc[] =
-".. method:: keyframe_insert(data_path, index=-1, frame=bpy.context.scene.frame_current, group=\"\")\n"
-"\n"
-" Insert a keyframe on the property given, adding fcurves and animation data when necessary.\n"
-"\n"
-" :arg data_path: path to the property to key, analogous to the fcurve's data path.\n"
-" :type data_path: string\n"
-" :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"
-" :type index: int\n"
-" :arg frame: The frame on which the keyframe is inserted, defaulting to the current frame.\n"
-" :type frame: float\n"
-" :arg group: The name of the group the F-Curve should be added to if it doesn't exist yet.\n"
-" :type group: str\n"
-" :return: Success of keyframe insertion.\n"
-" :rtype: boolean\n"
-;
-static PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyObject *kw)
-{
- /* args, pyrna_struct_keyframe_parse handles these */
- const char *path_full= NULL;
- int index= -1;
- float cfra= FLT_MAX;
- const char *group_name= NULL;
-
- PYRNA_STRUCT_CHECK_OBJ(self)
-
- if(pyrna_struct_keyframe_parse(&self->ptr, args, kw, "s|ifs:bpy_struct.keyframe_insert()", "bpy_struct.keyframe_insert()", &path_full, &index, &cfra, &group_name) == -1) {
- return NULL;
- }
- else {
- short result;
- ReportList reports;
-
- BKE_reports_init(&reports, RPT_STORE);
-
- result= insert_keyframe(&reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, 0);
- MEM_freeN((void *)path_full);
-
- if(BPy_reports_to_error(&reports, TRUE))
- return NULL;
-
- return PyBool_FromLong(result);
- }
-}
-
-static char pyrna_struct_keyframe_delete_doc[] =
-".. method:: keyframe_delete(data_path, index=-1, frame=bpy.context.scene.frame_current, group=\"\")\n"
-"\n"
-" Remove a keyframe from this properties fcurve.\n"
-"\n"
-" :arg data_path: path to the property to remove a key, analogous to the fcurve's data path.\n"
-" :type data_path: string\n"
-" :arg index: array index of the property to remove a key. Defaults to -1 removing all indices or a single channel if the property is not an array.\n"
-" :type index: int\n"
-" :arg frame: The frame on which the keyframe is deleted, defaulting to the current frame.\n"
-" :type frame: float\n"
-" :arg group: The name of the group the F-Curve should be added to if it doesn't exist yet.\n"
-" :type group: str\n"
-" :return: Success of keyframe deleation.\n"
-" :rtype: boolean\n"
-;
-static PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args, PyObject *kw)
-{
- /* args, pyrna_struct_keyframe_parse handles these */
- const char *path_full= NULL;
- int index= -1;
- float cfra= FLT_MAX;
- const char *group_name= NULL;
-
- PYRNA_STRUCT_CHECK_OBJ(self)
-
- if(pyrna_struct_keyframe_parse(&self->ptr, args, kw, "s|ifs:bpy_struct.keyframe_delete()", "bpy_struct.keyframe_insert()", &path_full, &index, &cfra, &group_name) == -1) {
- return NULL;
- }
- else {
- short result;
- ReportList reports;
-
- BKE_reports_init(&reports, RPT_STORE);
-
- result= delete_keyframe(&reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, 0);
- MEM_freeN((void *)path_full);
-
- if(BPy_reports_to_error(&reports, TRUE))
- return NULL;
-
- return PyBool_FromLong(result);
- }
-
-}
-
-static char pyrna_struct_driver_add_doc[] =
-".. method:: driver_add(path, index=-1)\n"
-"\n"
-" Adds driver(s) to the given property\n"
-"\n"
-" :arg path: path to the property to drive, analogous to the fcurve's data path.\n"
-" :type path: string\n"
-" :arg index: array index of the property drive. Defaults to -1 for all indices or a single channel if the property is not an array.\n"
-" :type index: int\n"
-" :return: The driver(s) added.\n"
-" :rtype: :class:`FCurve` or list if index is -1 with an array property.\n"
-;
-static PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args)
-{
- const char *path, *path_full;
- int index= -1;
-
- PYRNA_STRUCT_CHECK_OBJ(self)
-
- if (!PyArg_ParseTuple(args, "s|i:driver_add", &path, &index))
- return NULL;
-
- if(pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_add():", path, &path_full, &index) < 0) {
- return NULL;
- }
- else {
- PyObject *ret= NULL;
- ReportList reports;
- int result;
-
- BKE_reports_init(&reports, RPT_STORE);
-
- result= ANIM_add_driver(&reports, (ID *)self->ptr.id.data, path_full, index, 0, DRIVER_TYPE_PYTHON);
-
- if(BPy_reports_to_error(&reports, TRUE))
- return NULL;
-
- if(result) {
- ID *id= self->ptr.id.data;
- AnimData *adt= BKE_animdata_from_id(id);
- FCurve *fcu;
-
- PointerRNA tptr;
- PyObject *item;
-
- if(index == -1) { /* all, use a list */
- int i= 0;
- ret= PyList_New(0);
- while((fcu= list_find_fcurve(&adt->drivers, path_full, i++))) {
- RNA_pointer_create(id, &RNA_FCurve, fcu, &tptr);
- item= pyrna_struct_CreatePyObject(&tptr);
- PyList_Append(ret, item);
- Py_DECREF(item);
- }
- }
- else {
- fcu= list_find_fcurve(&adt->drivers, path_full, index);
- RNA_pointer_create(id, &RNA_FCurve, fcu, &tptr);
- ret= pyrna_struct_CreatePyObject(&tptr);
- }
- }
- else {
- /* XXX, should be handled by reports, */
- PyErr_SetString(PyExc_TypeError, "bpy_struct.driver_add(): failed because of an internal error");
- return NULL;
- }
-
- MEM_freeN((void *)path_full);
-
- return ret;
- }
-}
-
-
-static char pyrna_struct_driver_remove_doc[] =
-".. method:: driver_remove(path, index=-1)\n"
-"\n"
-" Remove driver(s) from the given property\n"
-"\n"
-" :arg path: path to the property to drive, analogous to the fcurve's data path.\n"
-" :type path: string\n"
-" :arg index: array index of the property drive. Defaults to -1 for all indices or a single channel if the property is not an array.\n"
-" :type index: int\n"
-" :return: Success of driver removal.\n"
-" :rtype: boolean\n"
-;
-static PyObject *pyrna_struct_driver_remove(BPy_StructRNA *self, PyObject *args)
-{
- const char *path, *path_full;
- int index= -1;
-
- PYRNA_STRUCT_CHECK_OBJ(self)
-
- if (!PyArg_ParseTuple(args, "s|i:driver_remove", &path, &index))
- return NULL;
-
- if(pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_remove():", path, &path_full, &index) < 0) {
- return NULL;
- }
- else {
- short result;
- ReportList reports;
-
- BKE_reports_init(&reports, RPT_STORE);
-
- result= ANIM_remove_driver(&reports, (ID *)self->ptr.id.data, path_full, index, 0);
-
- MEM_freeN((void *)path_full);
-
- if(BPy_reports_to_error(&reports, TRUE))
- return NULL;
-
- return PyBool_FromLong(result);
- }
-}
-
static char pyrna_struct_is_property_set_doc[] =
".. method:: is_property_set(property)\n"
@@ -3969,10 +3659,12 @@ static struct PyMethodDef pyrna_struct_methods[] = {
{"as_pointer", (PyCFunction)pyrna_struct_as_pointer, METH_NOARGS, pyrna_struct_as_pointer_doc},
+ /* bpy_rna_anim.c */
{"keyframe_insert", (PyCFunction)pyrna_struct_keyframe_insert, METH_VARARGS|METH_KEYWORDS, pyrna_struct_keyframe_insert_doc},
{"keyframe_delete", (PyCFunction)pyrna_struct_keyframe_delete, METH_VARARGS|METH_KEYWORDS, pyrna_struct_keyframe_delete_doc},
{"driver_add", (PyCFunction)pyrna_struct_driver_add, METH_VARARGS, pyrna_struct_driver_add_doc},
{"driver_remove", (PyCFunction)pyrna_struct_driver_remove, METH_VARARGS, pyrna_struct_driver_remove_doc},
+
{"is_property_set", (PyCFunction)pyrna_struct_is_property_set, METH_VARARGS, pyrna_struct_is_property_set_doc},
{"is_property_hidden", (PyCFunction)pyrna_struct_is_property_hidden, METH_VARARGS, pyrna_struct_is_property_hidden_doc},
{"path_resolve", (PyCFunction)pyrna_struct_path_resolve, METH_VARARGS, pyrna_struct_path_resolve_doc},
diff --git a/source/blender/python/intern/bpy_rna.h b/source/blender/python/intern/bpy_rna.h
index be877344c48..77f1fa3b336 100644
--- a/source/blender/python/intern/bpy_rna.h
+++ b/source/blender/python/intern/bpy_rna.h
@@ -29,21 +29,8 @@
#ifndef BPY_RNA_H
#define BPY_RNA_H
-#include "RNA_access.h"
-#include "RNA_types.h"
-#include "BKE_idprop.h"
-
-extern PyTypeObject pyrna_struct_meta_idprop_Type;
-extern PyTypeObject pyrna_struct_Type;
-extern PyTypeObject pyrna_prop_Type;
-extern PyTypeObject pyrna_prop_array_Type;
-extern PyTypeObject pyrna_prop_collection_Type;
-
-#define BPy_StructRNA_Check(v) (PyObject_TypeCheck(v, &pyrna_struct_Type))
-#define BPy_StructRNA_CheckExact(v) (Py_TYPE(v) == &pyrna_struct_Type)
-#define BPy_PropertyRNA_Check(v) (PyObject_TypeCheck(v, &pyrna_prop_Type))
-#define BPy_PropertyRNA_CheckExact(v) (Py_TYPE(v) == &pyrna_prop_Type)
+/* --- bpy build options --- */
/* play it safe and keep optional for now, need to test further now this affects looping on 10000's of verts for eg. */
// #define USE_WEAKREFS
@@ -62,6 +49,28 @@ extern PyTypeObject pyrna_prop_collection_Type;
#if defined(USE_PYRNA_INVALIDATE_GC) && defined(USE_PYRNA_INVALIDATE_WEAKREF)
#error "Only 1 reference check method at a time!"
#endif
+/* --- end bpy build options --- */
+
+
+extern PyTypeObject pyrna_struct_meta_idprop_Type;
+extern PyTypeObject pyrna_struct_Type;
+extern PyTypeObject pyrna_prop_Type;
+extern PyTypeObject pyrna_prop_array_Type;
+extern PyTypeObject pyrna_prop_collection_Type;
+
+#define BPy_StructRNA_Check(v) (PyObject_TypeCheck(v, &pyrna_struct_Type))
+#define BPy_StructRNA_CheckExact(v) (Py_TYPE(v) == &pyrna_struct_Type)
+#define BPy_PropertyRNA_Check(v) (PyObject_TypeCheck(v, &pyrna_prop_Type))
+#define BPy_PropertyRNA_CheckExact(v) (Py_TYPE(v) == &pyrna_prop_Type)
+
+#define PYRNA_STRUCT_CHECK_OBJ(obj) if(pyrna_struct_validity_check(obj) == -1) { return NULL; }
+#define PYRNA_STRUCT_CHECK_INT(obj) if(pyrna_struct_validity_check(obj) == -1) { return -1; }
+
+#define PYRNA_PROP_CHECK_OBJ(obj) if(pyrna_prop_validity_check(obj) == -1) { return NULL; }
+#define PYRNA_PROP_CHECK_INT(obj) if(pyrna_prop_validity_check(obj) == -1) { return -1; }
+
+#define PYRNA_STRUCT_IS_VALID(pysrna) (((BPy_StructRNA *)(pysrna))->ptr.type != NULL)
+#define PYRNA_PROP_IS_VALID(pysrna) (((BPy_PropertyRNA *)(pysrna))->ptr.type != NULL)
typedef struct {
PyObject_HEAD /* required python macro */
@@ -141,6 +150,9 @@ int pyrna_array_contains_py(PointerRNA *ptr, PropertyRNA *prop, PyObject *value)
int pyrna_write_check(void);
+int pyrna_struct_validity_check(BPy_StructRNA *pysrna);
+int pyrna_prop_validity_check(BPy_PropertyRNA *self);
+
void BPY_modules_update(struct bContext *C); //XXX temp solution
/* bpy.utils.(un)register_class */
diff --git a/source/blender/python/intern/bpy_rna_anim.c b/source/blender/python/intern/bpy_rna_anim.c
new file mode 100644
index 00000000000..d85710bf388
--- /dev/null
+++ b/source/blender/python/intern/bpy_rna_anim.c
@@ -0,0 +1,353 @@
+/*
+ * $Id:
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/python/intern/bpy_rna_anim.c
+ * \ingroup pythonintern
+ */
+
+#include <Python.h>
+#include <float.h> /* FLT_MIN/MAX */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_string.h"
+
+#include "DNA_scene_types.h"
+#include "DNA_anim_types.h"
+#include "ED_keyframing.h"
+
+#include "BKE_report.h"
+#include "BKE_context.h"
+#include "BKE_animsys.h"
+#include "BKE_fcurve.h"
+
+#include "ED_keyframing.h"
+
+#include "bpy_rna.h"
+#include "bpy_util.h"
+
+#define TRUE 1
+#define FALSE 0
+
+/* for keyframes and drivers */
+static int pyrna_struct_anim_args_parse(PointerRNA *ptr, const char *error_prefix, const char *path,
+ const char **path_full, int *index)
+{
+ const int is_idbase= RNA_struct_is_ID(ptr->type);
+ PropertyRNA *prop;
+ PointerRNA r_ptr;
+
+ if (ptr->data==NULL) {
+ PyErr_Format(PyExc_TypeError, "%.200s this struct has no data, can't be animated", error_prefix);
+ return -1;
+ }
+
+ /* full paths can only be given from ID base */
+ if(is_idbase) {
+ int r_index= -1;
+ if(RNA_path_resolve_full(ptr, path, &r_ptr, &prop, &r_index)==0) {
+ prop= NULL;
+ }
+ else if(r_index != -1) {
+ PyErr_Format(PyExc_ValueError, "%.200s path includes index, must be a separate argument", error_prefix, path);
+ return -1;
+ }
+ else if(ptr->id.data != r_ptr.id.data) {
+ PyErr_Format(PyExc_ValueError, "%.200s path spans ID blocks", error_prefix, path);
+ return -1;
+ }
+ }
+ else {
+ prop = RNA_struct_find_property(ptr, path);
+ r_ptr= *ptr;
+ }
+
+ if (prop==NULL) {
+ PyErr_Format(PyExc_TypeError, "%.200s property \"%s\" not found", error_prefix, path);
+ return -1;
+ }
+
+ if (!RNA_property_animateable(&r_ptr, prop)) {
+ PyErr_Format(PyExc_TypeError, "%.200s property \"%s\" not animatable", error_prefix, path);
+ return -1;
+ }
+
+ if(RNA_property_array_check(&r_ptr, prop) == 0) {
+ if((*index) == -1) {
+ *index= 0;
+ }
+ else {
+ PyErr_Format(PyExc_TypeError, "%.200s index %d was given while property \"%s\" is not an array", error_prefix, *index, path);
+ return -1;
+ }
+ }
+ else {
+ int array_len= RNA_property_array_length(&r_ptr, prop);
+ if((*index) < -1 || (*index) >= array_len) {
+ PyErr_Format(PyExc_TypeError, "%.200s index out of range \"%s\", given %d, array length is %d", error_prefix, path, *index, array_len);
+ return -1;
+ }
+ }
+
+ if(is_idbase) {
+ *path_full= BLI_strdup(path);
+ }
+ else {
+ *path_full= RNA_path_from_ID_to_property(&r_ptr, prop);
+
+ if (*path_full==NULL) {
+ PyErr_Format(PyExc_TypeError, "%.200s could not make path to \"%s\"", error_prefix, path);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+/* internal use for insert and delete */
+static int pyrna_struct_keyframe_parse(PointerRNA *ptr, PyObject *args, PyObject *kw, const char *parse_str, const char *error_prefix,
+ const char **path_full, int *index, float *cfra, const char **group_name) /* return values */
+{
+ static const char *kwlist[] = {"data_path", "index", "frame", "group", NULL};
+ const char *path;
+
+ /* note, parse_str MUST start with 's|ifs' */
+ if (!PyArg_ParseTupleAndKeywords(args, kw, parse_str, (char **)kwlist, &path, index, cfra, group_name))
+ return -1;
+
+ if(pyrna_struct_anim_args_parse(ptr, error_prefix, path, path_full, index) < 0)
+ return -1;
+
+ if(*cfra==FLT_MAX)
+ *cfra= CTX_data_scene(BPy_GetContext())->r.cfra;
+
+ return 0; /* success */
+}
+
+char pyrna_struct_keyframe_insert_doc[] =
+".. method:: keyframe_insert(data_path, index=-1, frame=bpy.context.scene.frame_current, group=\"\")\n"
+"\n"
+" Insert a keyframe on the property given, adding fcurves and animation data when necessary.\n"
+"\n"
+" :arg data_path: path to the property to key, analogous to the fcurve's data path.\n"
+" :type data_path: string\n"
+" :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"
+" :type index: int\n"
+" :arg frame: The frame on which the keyframe is inserted, defaulting to the current frame.\n"
+" :type frame: float\n"
+" :arg group: The name of the group the F-Curve should be added to if it doesn't exist yet.\n"
+" :type group: str\n"
+" :return: Success of keyframe insertion.\n"
+" :rtype: boolean\n"
+;
+PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyObject *kw)
+{
+ /* args, pyrna_struct_keyframe_parse handles these */
+ const char *path_full= NULL;
+ int index= -1;
+ float cfra= FLT_MAX;
+ const char *group_name= NULL;
+
+ PYRNA_STRUCT_CHECK_OBJ(self)
+
+ if(pyrna_struct_keyframe_parse(&self->ptr, args, kw, "s|ifs:bpy_struct.keyframe_insert()", "bpy_struct.keyframe_insert()", &path_full, &index, &cfra, &group_name) == -1) {
+ return NULL;
+ }
+ else {
+ short result;
+ ReportList reports;
+
+ BKE_reports_init(&reports, RPT_STORE);
+
+ result= insert_keyframe(&reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, 0);
+ MEM_freeN((void *)path_full);
+
+ if(BPy_reports_to_error(&reports, TRUE))
+ return NULL;
+
+ return PyBool_FromLong(result);
+ }
+}
+
+char pyrna_struct_keyframe_delete_doc[] =
+".. method:: keyframe_delete(data_path, index=-1, frame=bpy.context.scene.frame_current, group=\"\")\n"
+"\n"
+" Remove a keyframe from this properties fcurve.\n"
+"\n"
+" :arg data_path: path to the property to remove a key, analogous to the fcurve's data path.\n"
+" :type data_path: string\n"
+" :arg index: array index of the property to remove a key. Defaults to -1 removing all indices or a single channel if the property is not an array.\n"
+" :type index: int\n"
+" :arg frame: The frame on which the keyframe is deleted, defaulting to the current frame.\n"
+" :type frame: float\n"
+" :arg group: The name of the group the F-Curve should be added to if it doesn't exist yet.\n"
+" :type group: str\n"
+" :return: Success of keyframe deleation.\n"
+" :rtype: boolean\n"
+;
+PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args, PyObject *kw)
+{
+ /* args, pyrna_struct_keyframe_parse handles these */
+ const char *path_full= NULL;
+ int index= -1;
+ float cfra= FLT_MAX;
+ const char *group_name= NULL;
+
+ PYRNA_STRUCT_CHECK_OBJ(self)
+
+ if(pyrna_struct_keyframe_parse(&self->ptr, args, kw, "s|ifs:bpy_struct.keyframe_delete()", "bpy_struct.keyframe_insert()", &path_full, &index, &cfra, &group_name) == -1) {
+ return NULL;
+ }
+ else {
+ short result;
+ ReportList reports;
+
+ BKE_reports_init(&reports, RPT_STORE);
+
+ result= delete_keyframe(&reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, 0);
+ MEM_freeN((void *)path_full);
+
+ if(BPy_reports_to_error(&reports, TRUE))
+ return NULL;
+
+ return PyBool_FromLong(result);
+ }
+
+}
+
+char pyrna_struct_driver_add_doc[] =
+".. method:: driver_add(path, index=-1)\n"
+"\n"
+" Adds driver(s) to the given property\n"
+"\n"
+" :arg path: path to the property to drive, analogous to the fcurve's data path.\n"
+" :type path: string\n"
+" :arg index: array index of the property drive. Defaults to -1 for all indices or a single channel if the property is not an array.\n"
+" :type index: int\n"
+" :return: The driver(s) added.\n"
+" :rtype: :class:`FCurve` or list if index is -1 with an array property.\n"
+;
+PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args)
+{
+ const char *path, *path_full;
+ int index= -1;
+
+ PYRNA_STRUCT_CHECK_OBJ(self)
+
+ if (!PyArg_ParseTuple(args, "s|i:driver_add", &path, &index))
+ return NULL;
+
+ if(pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_add():", path, &path_full, &index) < 0) {
+ return NULL;
+ }
+ else {
+ PyObject *ret= NULL;
+ ReportList reports;
+ int result;
+
+ BKE_reports_init(&reports, RPT_STORE);
+
+ result= ANIM_add_driver(&reports, (ID *)self->ptr.id.data, path_full, index, 0, DRIVER_TYPE_PYTHON);
+
+ if(BPy_reports_to_error(&reports, TRUE))
+ return NULL;
+
+ if(result) {
+ ID *id= self->ptr.id.data;
+ AnimData *adt= BKE_animdata_from_id(id);
+ FCurve *fcu;
+
+ PointerRNA tptr;
+ PyObject *item;
+
+ if(index == -1) { /* all, use a list */
+ int i= 0;
+ ret= PyList_New(0);
+ while((fcu= list_find_fcurve(&adt->drivers, path_full, i++))) {
+ RNA_pointer_create(id, &RNA_FCurve, fcu, &tptr);
+ item= pyrna_struct_CreatePyObject(&tptr);
+ PyList_Append(ret, item);
+ Py_DECREF(item);
+ }
+ }
+ else {
+ fcu= list_find_fcurve(&adt->drivers, path_full, index);
+ RNA_pointer_create(id, &RNA_FCurve, fcu, &tptr);
+ ret= pyrna_struct_CreatePyObject(&tptr);
+ }
+ }
+ else {
+ /* XXX, should be handled by reports, */
+ PyErr_SetString(PyExc_TypeError, "bpy_struct.driver_add(): failed because of an internal error");
+ return NULL;
+ }
+
+ MEM_freeN((void *)path_full);
+
+ return ret;
+ }
+}
+
+
+char pyrna_struct_driver_remove_doc[] =
+".. method:: driver_remove(path, index=-1)\n"
+"\n"
+" Remove driver(s) from the given property\n"
+"\n"
+" :arg path: path to the property to drive, analogous to the fcurve's data path.\n"
+" :type path: string\n"
+" :arg index: array index of the property drive. Defaults to -1 for all indices or a single channel if the property is not an array.\n"
+" :type index: int\n"
+" :return: Success of driver removal.\n"
+" :rtype: boolean\n"
+;
+PyObject *pyrna_struct_driver_remove(BPy_StructRNA *self, PyObject *args)
+{
+ const char *path, *path_full;
+ int index= -1;
+
+ PYRNA_STRUCT_CHECK_OBJ(self)
+
+ if (!PyArg_ParseTuple(args, "s|i:driver_remove", &path, &index))
+ return NULL;
+
+ if(pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_remove():", path, &path_full, &index) < 0) {
+ return NULL;
+ }
+ else {
+ short result;
+ ReportList reports;
+
+ BKE_reports_init(&reports, RPT_STORE);
+
+ result= ANIM_remove_driver(&reports, (ID *)self->ptr.id.data, path_full, index, 0);
+
+ MEM_freeN((void *)path_full);
+
+ if(BPy_reports_to_error(&reports, TRUE))
+ return NULL;
+
+ return PyBool_FromLong(result);
+ }
+}
diff --git a/source/blender/python/intern/bpy_rna_anim.h b/source/blender/python/intern/bpy_rna_anim.h
new file mode 100644
index 00000000000..bd50a1805a2
--- /dev/null
+++ b/source/blender/python/intern/bpy_rna_anim.h
@@ -0,0 +1,37 @@
+/*
+ * $Id:
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/python/intern/bpy_rna_anim.h
+ * \ingroup pythonintern
+ */
+
+extern char pyrna_struct_keyframe_insert_doc[];
+extern char pyrna_struct_keyframe_delete_doc[];
+extern char pyrna_struct_driver_add_doc[];
+extern char pyrna_struct_driver_remove_doc[];
+
+PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyObject *kw);
+PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args, PyObject *kw);
+PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args);
+PyObject *pyrna_struct_driver_remove(BPy_StructRNA *self, PyObject *args);
diff --git a/source/blender/python/intern/bpy_rna_array.c b/source/blender/python/intern/bpy_rna_array.c
index dc2f56fea99..8e7aba42a99 100644
--- a/source/blender/python/intern/bpy_rna_array.c
+++ b/source/blender/python/intern/bpy_rna_array.c
@@ -28,10 +28,14 @@
#include <Python.h>
+#include "RNA_types.h"
+
#include "bpy_rna.h"
#include "BKE_global.h"
#include "MEM_guardedalloc.h"
+#include "RNA_access.h"
+
#define MAX_ARRAY_DIMENSION 10
typedef void (*ItemConvertFunc)(PyObject *, char *);
diff --git a/source/blender/python/intern/bpy_rna_callback.c b/source/blender/python/intern/bpy_rna_callback.c
index 81ec955300a..7581eb16a9d 100644
--- a/source/blender/python/intern/bpy_rna_callback.c
+++ b/source/blender/python/intern/bpy_rna_callback.c
@@ -29,6 +29,8 @@
#include <Python.h>
+#include "RNA_types.h"
+
#include "bpy_rna.h"
#include "bpy_rna_callback.h"
#include "bpy_util.h"
@@ -37,6 +39,8 @@
#include "DNA_screen_types.h"
+#include "RNA_access.h"
+
#include "BKE_context.h"
#include "ED_space_api.h"