move anim functions out of bpy_rna.c, its getting too big.
authorCampbell Barton <ideasman42@gmail.com>
Wed, 2 Mar 2011 04:51:43 +0000 (04:51 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Wed, 2 Mar 2011 04:51:43 +0000 (04:51 +0000)
12 files changed:
source/blender/python/intern/CMakeLists.txt
source/blender/python/intern/bpy.c
source/blender/python/intern/bpy_interface.c
source/blender/python/intern/bpy_operator.c
source/blender/python/intern/bpy_operator_wrap.c
source/blender/python/intern/bpy_props.c
source/blender/python/intern/bpy_rna.c
source/blender/python/intern/bpy_rna.h
source/blender/python/intern/bpy_rna_anim.c [new file with mode: 0644]
source/blender/python/intern/bpy_rna_anim.h [new file with mode: 0644]
source/blender/python/intern/bpy_rna_array.c
source/blender/python/intern/bpy_rna_callback.c

index 123c8e5b3e044ad618a9e8f143750de5d77433b1..bf91fd90744baff6fcc453e847863ef60fcf18ed 100644 (file)
@@ -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
index 1f66e1063744cda25bac3497cd907545606bb71a..589da5b3cb7be250a18f5bea7a9d009924ead1dd 100644 (file)
@@ -48,6 +48,8 @@
 
 #include "BKE_global.h" /* XXX, G.main only */
 
+#include "RNA_access.h"
+
 #include "MEM_guardedalloc.h"
 
  /* external util modules */
index ade7ff625191f445770433a50fe2f6c501251686..03d5f528670777348adaeec6119feeae2800838a 100644 (file)
@@ -37,6 +37,8 @@
 
 #include "MEM_guardedalloc.h"
 
+#include "RNA_types.h"
+
 #include "bpy.h"
 #include "bpy_rna.h"
 #include "bpy_util.h"
index e4df94cfbc084a5ec129a44624154db8f43bc9a3..73a8deb1b97cd143d925e122352457499da20bd6 100644 (file)
@@ -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"
index 78b731fdde1094e8aa23ffdd47dacd7ef95d774e..0269625d906d963d8618024e554adea887cb73f5 100644 (file)
@@ -36,6 +36,7 @@
 
 #include "BLI_utildefines.h"
 
+#include "RNA_access.h"
 #include "RNA_define.h"
 
 #include "bpy_rna.h"
index bae320905295b51112a9ebc72ed9e8fd93ec27e4..09c62f8b2c8669b3e47ee79b1e7347117aca3f0d 100644 (file)
 
 #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"
 
index b1338f3b82d8866232f96d58137f2008eb4eea41..32a1f3871032628837a8a962a6642a9ec0990625 100644 (file)
 #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"
 
 #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"
 
 
 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},
index be877344c4807c01de50b62a9aac137874a771e9..77f1fa3b3365dbc60782b5a5b16f73136e294f65 100644 (file)
 #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 (file)
index 0000000..d85710b
--- /dev/null
@@ -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 (file)
index 0000000..bd50a18
--- /dev/null
@@ -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);
index dc2f56fea996bfbde0297690bde613366beacca5..8e7aba42a99912c3d80685ad6fc43b7fa250f417 100644 (file)
 
 #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 *);
index 81ec955300a1957e6245cacf33a0b2d39241f9fb..7581eb16a9dfb2af37c022a0b43f47fe2b62c6cc 100644 (file)
@@ -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"