forked from bartvdbraak/blender
python function to remove drivers.
eg: bpy.context.object.driver_remove("location") ANIM_remove_driver now accepts -1 as an index for removing all drivers from one path.
This commit is contained in:
parent
a8bca52d09
commit
ee0a217be3
@ -187,6 +187,8 @@ void copy_fcurves(ListBase *dst, ListBase *src);
|
||||
/* find matching F-Curve in the given list of F-Curves */
|
||||
struct FCurve *list_find_fcurve(ListBase *list, const char rna_path[], const int array_index);
|
||||
|
||||
struct FCurve *iter_step_fcurve (struct FCurve *fcu_iter, const char rna_path[]);
|
||||
|
||||
/* high level function to get an fcurve from C without having the rna */
|
||||
struct FCurve *id_data_find_fcurve(ID *id, void *data, struct StructRNA *type, char *prop_name, int index);
|
||||
|
||||
|
@ -234,6 +234,27 @@ FCurve *list_find_fcurve (ListBase *list, const char rna_path[], const int array
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* quick way to loop over all fcurves of a given 'path' */
|
||||
FCurve *iter_step_fcurve (FCurve *fcu_iter, const char rna_path[])
|
||||
{
|
||||
FCurve *fcu;
|
||||
|
||||
/* sanity checks */
|
||||
if (ELEM(NULL, fcu_iter, rna_path))
|
||||
return NULL;
|
||||
|
||||
/* check paths of curves, then array indices... */
|
||||
for (fcu= fcu_iter; fcu; fcu= fcu->next) {
|
||||
/* simple string-compare (this assumes that they have the same root...) */
|
||||
if (fcu->rna_path && !strcmp(fcu->rna_path, rna_path)) {
|
||||
return fcu;
|
||||
}
|
||||
}
|
||||
|
||||
/* return */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Get list of LinkData's containing pointers to the F-Curves which control the types of data indicated
|
||||
* Lists...
|
||||
* - dst: list of LinkData's matching the criteria returned.
|
||||
|
@ -197,27 +197,42 @@ short ANIM_remove_driver (struct ID *id, const char rna_path[], int array_index,
|
||||
{
|
||||
AnimData *adt;
|
||||
FCurve *fcu;
|
||||
int success= 0;
|
||||
|
||||
/* get F-Curve
|
||||
* Note: here is one of the places where we don't want new F-Curve + Driver added!
|
||||
* so 'add' var must be 0
|
||||
*/
|
||||
/* we don't check the validity of the path here yet, but it should be ok... */
|
||||
fcu= verify_driver_fcurve(id, rna_path, array_index, 0);
|
||||
adt= BKE_animdata_from_id(id);
|
||||
|
||||
/* only continue if we have an driver to remove */
|
||||
if (adt && fcu) {
|
||||
if(adt) {
|
||||
if(array_index == -1) {
|
||||
FCurve *fcu_iter= adt->drivers.first;
|
||||
while((fcu= iter_step_fcurve(fcu_iter, rna_path))) {
|
||||
/* store the next fcurve for looping */
|
||||
fcu_iter= fcu->next;
|
||||
|
||||
/* remove F-Curve from driver stack, then free it */
|
||||
BLI_remlink(&adt->drivers, fcu);
|
||||
free_fcurve(fcu);
|
||||
|
||||
/* done successfully */
|
||||
return 1;
|
||||
success |= 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
fcu= verify_driver_fcurve(id, rna_path, array_index, 0);
|
||||
if(fcu) {
|
||||
BLI_remlink(&adt->drivers, fcu);
|
||||
free_fcurve(fcu);
|
||||
|
||||
success = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* failed */
|
||||
return 0;
|
||||
return success;
|
||||
}
|
||||
|
||||
/* ************************************************** */
|
||||
@ -408,32 +423,20 @@ static int remove_driver_button_exec (bContext *C, wmOperator *op)
|
||||
PropertyRNA *prop= NULL;
|
||||
char *path;
|
||||
short success= 0;
|
||||
int a, index, length, all= RNA_boolean_get(op->ptr, "all");
|
||||
int index, all= RNA_boolean_get(op->ptr, "all");
|
||||
|
||||
/* try to find driver using property retrieved from UI */
|
||||
memset(&ptr, 0, sizeof(PointerRNA));
|
||||
uiAnimContextProperty(C, &ptr, &prop, &index);
|
||||
|
||||
if (all)
|
||||
index= -1;
|
||||
|
||||
if (ptr.data && prop) {
|
||||
path= RNA_path_from_ID_to_property(&ptr, prop);
|
||||
|
||||
if (path) {
|
||||
if (all) {
|
||||
length= RNA_property_array_length(&ptr, prop);
|
||||
|
||||
if(length) index= 0;
|
||||
else length= 1;
|
||||
}
|
||||
else
|
||||
length= 1;
|
||||
|
||||
for (a=0; a<length; a++)
|
||||
success+= ANIM_remove_driver(ptr.id.data, path, index+a, 0);
|
||||
|
||||
success= ANIM_remove_driver(ptr.id.data, path, index, 0);
|
||||
MEM_freeN(path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (success) {
|
||||
/* send updates */
|
||||
|
@ -1703,18 +1703,12 @@ static PyObject *pyrna_struct_values(BPy_PropertyRNA *self)
|
||||
return BPy_Wrap_GetValues(self->ptr.id.data, group);
|
||||
}
|
||||
|
||||
/* internal use for insert and delete */
|
||||
static int pyrna_struct_keyframe_parse(PointerRNA *ptr, PyObject *args, char *error_prefix,
|
||||
char **path_full, int *index, float *cfra, char **group_name) /* return values */
|
||||
/* for keyframes and drivers */
|
||||
static int pyrna_struct_anim_args_parse(PointerRNA *ptr, char *error_prefix, char *path,
|
||||
char **path_full, int *index)
|
||||
{
|
||||
char *path;
|
||||
PropertyRNA *prop;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s|ifs", &path, index, cfra, group_name)) {
|
||||
PyErr_Format(PyExc_TypeError, "%.200s expected a string and optionally an int, float, and string arguments", error_prefix);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ptr->data==NULL) {
|
||||
PyErr_Format(PyExc_TypeError, "%.200s this struct has no data, can't be animated", error_prefix);
|
||||
return -1;
|
||||
@ -1756,6 +1750,23 @@ static int pyrna_struct_keyframe_parse(PointerRNA *ptr, PyObject *args, char *er
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* internal use for insert and delete */
|
||||
static int pyrna_struct_keyframe_parse(PointerRNA *ptr, PyObject *args, char *error_prefix,
|
||||
char **path_full, int *index, float *cfra, char **group_name) /* return values */
|
||||
{
|
||||
char *path;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s|ifs", &path, index, cfra, group_name)) {
|
||||
PyErr_Format(PyExc_TypeError, "%.200s expected a string and optionally an int, float, and string arguments", error_prefix);
|
||||
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;
|
||||
|
||||
@ -1846,52 +1857,13 @@ static PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args)
|
||||
{
|
||||
char *path, *path_full;
|
||||
int index= -1;
|
||||
PropertyRNA *prop;
|
||||
PyObject *ret;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s|i:driver_add", &path, &index))
|
||||
return NULL;
|
||||
|
||||
if (self->ptr.data==NULL) {
|
||||
PyErr_Format( PyExc_TypeError, "bpy_struct.driver_add(): this struct has no data, cant be animated", path);
|
||||
if(pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_add():", path, &path_full, &index) < 0)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
prop = RNA_struct_find_property(&self->ptr, path);
|
||||
|
||||
if (prop==NULL) {
|
||||
PyErr_Format( PyExc_TypeError, "bpy_struct.driver_add(): property \"%s\" not found", path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!RNA_property_animateable(&self->ptr, prop)) {
|
||||
PyErr_Format( PyExc_TypeError, "bpy_struct.driver_add(): property \"%s\" not animatable", path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(RNA_property_array_check(&self->ptr, prop) == 0) {
|
||||
if(index == -1) {
|
||||
index= 0;
|
||||
}
|
||||
else {
|
||||
PyErr_Format( PyExc_TypeError, "bpy_struct.driver_add(): array index %d given while property \"%s\" is not an array", index, path);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
int array_len= RNA_property_array_length(&self->ptr, prop);
|
||||
if(index < -1 || index >= array_len) {
|
||||
PyErr_Format( PyExc_TypeError, "bpy_struct.driver_add(): index out of range \"%s\", given %d, array length is %d", path, index, array_len);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
path_full= RNA_path_from_ID_to_property(&self->ptr, prop);
|
||||
|
||||
if (path_full==NULL) {
|
||||
PyErr_Format( PyExc_TypeError, "bpy_struct.driver_add(): could not make path to \"%s\"", path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(ANIM_add_driver((ID *)self->ptr.id.data, path_full, index, 0, DRIVER_TYPE_PYTHON)) {
|
||||
ID *id= self->ptr.id.data;
|
||||
@ -1927,6 +1899,39 @@ static PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args)
|
||||
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 indicies or a single channel if the property is not an array.\n"
|
||||
" :type index: int\n"
|
||||
" :return: Success of driver removal.\n"
|
||||
" :rtype: boolean";
|
||||
|
||||
static PyObject *pyrna_struct_driver_remove(BPy_StructRNA *self, PyObject *args)
|
||||
{
|
||||
char *path, *path_full;
|
||||
int index= -1;
|
||||
PyObject *ret;
|
||||
|
||||
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;
|
||||
|
||||
ret= PyBool_FromLong(ANIM_remove_driver((ID *)self->ptr.id.data, path_full, index, 0));
|
||||
|
||||
MEM_freeN(path_full);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static char pyrna_struct_is_property_set_doc[] =
|
||||
".. method:: is_property_set(property)\n"
|
||||
"\n"
|
||||
@ -2899,6 +2904,7 @@ static struct PyMethodDef pyrna_struct_methods[] = {
|
||||
{"keyframe_insert", (PyCFunction)pyrna_struct_keyframe_insert, METH_VARARGS, pyrna_struct_keyframe_insert_doc},
|
||||
{"keyframe_delete", (PyCFunction)pyrna_struct_keyframe_delete, METH_VARARGS, 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_O, pyrna_struct_path_resolve_doc},
|
||||
|
Loading…
Reference in New Issue
Block a user