[Bf-blender-cvs] [69ee6c9] master: Drivers Editing: Added "Copy/Paste" buttons beside "Add Variable" for copying all variables from one driver to another
Joshua Leung
noreply at git.blender.org
Fri Apr 15 10:19:33 CEST 2016
Commit: 69ee6c986657bf0d6bf631277751d24e72d76bac
Author: Joshua Leung
Date: Fri Apr 15 20:04:07 2016 +1200
Branches: master
https://developer.blender.org/rB69ee6c986657bf0d6bf631277751d24e72d76bac
Drivers Editing: Added "Copy/Paste" buttons beside "Add Variable" for copying all variables from one driver to another
This was a feature request from a few years back (IIRC from ZanQdo?) to make it
easier to reuse one set of driver variables across several different drivers.
Dev Notes:
* Finally it's done! All that trouble for two little buttons.
* Grr... cmake... grrr!
===================================================================
M source/blender/blenkernel/BKE_fcurve.h
M source/blender/blenkernel/intern/fcurve.c
M source/blender/editors/animation/CMakeLists.txt
M source/blender/editors/animation/drivers.c
M source/blender/editors/include/ED_keyframing.h
M source/blender/editors/space_graph/graph_buttons.c
M source/blender/editors/space_graph/graph_edit.c
M source/blender/editors/space_graph/graph_intern.h
M source/blender/editors/space_graph/graph_ops.c
M source/blender/makesrna/intern/rna_fcurve.c
M source/blender/windowmanager/intern/wm_init_exit.c
===================================================================
diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h
index 6643382..2022d11 100644
--- a/source/blender/blenkernel/BKE_fcurve.h
+++ b/source/blender/blenkernel/BKE_fcurve.h
@@ -93,7 +93,11 @@ void bezt_add_to_cfra_elem(ListBase *lb, struct BezTriple *bezt);
void fcurve_free_driver(struct FCurve *fcu);
struct ChannelDriver *fcurve_copy_driver(struct ChannelDriver *driver);
-void driver_free_variable(struct ChannelDriver *driver, struct DriverVar *dvar);
+void driver_variables_copy(struct ListBase *dst_list, const struct ListBase *src_list);
+
+void driver_free_variable(struct ListBase *variables, struct DriverVar *dvar);
+void driver_free_variable_ex(struct ChannelDriver *driver, struct DriverVar *dvar);
+
void driver_change_variable_type(struct DriverVar *dvar, int type);
void driver_variable_name_validate(struct DriverVar *dvar);
struct DriverVar *driver_add_new_variable(struct ChannelDriver *driver);
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index 11b1bbd..a2b5a05 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -1600,8 +1600,8 @@ static const DriverVarTypeInfo *get_dvar_typeinfo(int type)
/* Driver API --------------------------------- */
-/* This frees the driver variable itself */
-void driver_free_variable(ChannelDriver *driver, DriverVar *dvar)
+/* Perform actual freeing driver variable and remove it from the given list */
+void driver_free_variable(ListBase *variables, DriverVar *dvar)
{
/* sanity checks */
if (dvar == NULL)
@@ -1621,8 +1621,15 @@ void driver_free_variable(ChannelDriver *driver, DriverVar *dvar)
DRIVER_TARGETS_LOOPER_END
/* remove the variable from the driver */
- BLI_freelinkN(&driver->variables, dvar);
+ BLI_freelinkN(variables, dvar);
+}
+/* Free the driver variable and do extra updates */
+void driver_free_variable_ex(ChannelDriver *driver, DriverVar *dvar)
+{
+ /* remove and free the driver variable */
+ driver_free_variable(&driver->variables, dvar);
+
#ifdef WITH_PYTHON
/* since driver variables are cached, the expression needs re-compiling too */
if (driver->type == DRIVER_TYPE_PYTHON)
@@ -1630,6 +1637,24 @@ void driver_free_variable(ChannelDriver *driver, DriverVar *dvar)
#endif
}
+/* Copy driver variables from src_vars list to dst_vars list */
+void driver_variables_copy(ListBase *dst_vars, const ListBase *src_vars)
+{
+ BLI_assert(BLI_listbase_is_empty(dst_vars));
+ BLI_duplicatelist(dst_vars, src_vars);
+
+ for (DriverVar *dvar = dst_vars->first; dvar; dvar = dvar->next) {
+ /* need to go over all targets so that we don't leave any dangling paths */
+ DRIVER_TARGETS_LOOPER(dvar)
+ {
+ /* make a copy of target's rna path if available */
+ if (dtar->rna_path)
+ dtar->rna_path = MEM_dupallocN(dtar->rna_path);
+ }
+ DRIVER_TARGETS_LOOPER_END
+ }
+}
+
/* Change the type of driver variable */
void driver_change_variable_type(DriverVar *dvar, int type)
{
@@ -1770,7 +1795,7 @@ void fcurve_free_driver(FCurve *fcu)
/* free driver targets */
for (dvar = driver->variables.first; dvar; dvar = dvarn) {
dvarn = dvar->next;
- driver_free_variable(driver, dvar);
+ driver_free_variable_ex(driver, dvar);
}
#ifdef WITH_PYTHON
@@ -1788,7 +1813,6 @@ void fcurve_free_driver(FCurve *fcu)
ChannelDriver *fcurve_copy_driver(ChannelDriver *driver)
{
ChannelDriver *ndriver;
- DriverVar *dvar;
/* sanity checks */
if (driver == NULL)
@@ -1799,19 +1823,8 @@ ChannelDriver *fcurve_copy_driver(ChannelDriver *driver)
ndriver->expr_comp = NULL;
/* copy variables */
- BLI_listbase_clear(&ndriver->variables);
- BLI_duplicatelist(&ndriver->variables, &driver->variables);
-
- for (dvar = ndriver->variables.first; dvar; dvar = dvar->next) {
- /* need to go over all targets so that we don't leave any dangling paths */
- DRIVER_TARGETS_LOOPER(dvar)
- {
- /* make a copy of target's rna path if available */
- if (dtar->rna_path)
- dtar->rna_path = MEM_dupallocN(dtar->rna_path);
- }
- DRIVER_TARGETS_LOOPER_END
- }
+ BLI_listbase_clear(&ndriver->variables); /* to get rid of refs to non-copied data (that's still used on original) */
+ driver_variables_copy(&ndriver->variables, &driver->variables);
/* return the new driver */
return ndriver;
diff --git a/source/blender/editors/animation/CMakeLists.txt b/source/blender/editors/animation/CMakeLists.txt
index 473b0e6..1bf1bb2 100644
--- a/source/blender/editors/animation/CMakeLists.txt
+++ b/source/blender/editors/animation/CMakeLists.txt
@@ -59,6 +59,10 @@ if(WITH_INTERNATIONAL)
add_definitions(-DWITH_INTERNATIONAL)
endif()
+if(WITH_PYTHON)
+ add_definitions(-DWITH_PYTHON)
+endif()
+
add_definitions(${GL_DEFINITIONS})
blender_add_lib(bf_editor_animation "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c
index 4ddf37a..27bed69 100644
--- a/source/blender/editors/animation/drivers.c
+++ b/source/blender/editors/animation/drivers.c
@@ -600,7 +600,7 @@ bool ANIM_paste_driver(ReportList *reports, ID *id, const char rna_path[], int a
/* create Driver F-Curve, but without data which will be copied across... */
fcu = verify_driver_fcurve(id, rna_path, array_index, -1);
-
+
if (fcu) {
/* copy across the curve data from the buffer curve
* NOTE: this step needs care to not miss new settings
@@ -625,6 +625,120 @@ bool ANIM_paste_driver(ReportList *reports, ID *id, const char rna_path[], int a
}
/* ************************************************** */
+/* Driver Management API - Copy/Paste Driver Variables */
+
+/* Copy/Paste Buffer for Driver Variables... */
+static ListBase driver_vars_copybuf = {NULL, NULL};
+
+/* This function frees any MEM_calloc'ed copy/paste buffer data */
+void ANIM_driver_vars_copybuf_free(void)
+{
+ /* Free the driver variables kept in the buffer */
+ if (driver_vars_copybuf.first) {
+ /* We use a dummy driver here, as the variable freeing code assumes there's a driver */
+ ChannelDriver dummy_driver = {{NULL}};
+ dummy_driver.variables = driver_vars_copybuf;
+
+ /* Free variables (and any data they use) */
+ DriverVar *dvar, *dvarn;
+ for (dvar = driver_vars_copybuf.first; dvar; dvar = dvarn) {
+ dvarn = dvar->next;
+ driver_free_variable(&driver_vars_copybuf, dvar);
+ }
+ }
+
+ BLI_listbase_clear(&driver_vars_copybuf);
+}
+
+/* Checks if there are driver variables in the copy/paste buffer */
+bool ANIM_driver_vars_can_paste(void)
+{
+ return (BLI_listbase_is_empty(&driver_vars_copybuf) == false);
+}
+
+/* -------------------------------------------------- */
+
+/* Copy the given driver's variables to the buffer */
+bool ANIM_driver_vars_copy(ReportList *reports, FCurve *fcu)
+{
+ /* sanity checks */
+ if (ELEM(NULL, fcu, fcu->driver)) {
+ BKE_report(reports, RPT_ERROR, "No driver to copy variables from");
+ return false;
+ }
+
+ if (BLI_listbase_is_empty(&fcu->driver->variables)) {
+ BKE_report(reports, RPT_ERROR, "Driver has no variables to copy");
+ return false;
+ }
+
+ /* clear buffer */
+ ANIM_driver_vars_copybuf_free();
+
+ /* copy over the variables */
+ driver_variables_copy(&driver_vars_copybuf, &fcu->driver->variables);
+
+ return (BLI_listbase_is_empty(&driver_vars_copybuf) == false);
+}
+
+/* Paste the variables in the buffer to the given FCurve */
+bool ANIM_driver_vars_paste(ReportList *reports, FCurve *fcu, bool replace)
+{
+ ChannelDriver *driver = (fcu) ? fcu->driver : NULL;
+ ListBase tmp_list = {NULL, NULL};
+
+ /* sanity checks */
+ if (BLI_listbase_is_empty(&driver_vars_copybuf)) {
+ BKE_report(reports, RPT_ERROR, "No driver variables in clipboard to paste");
+ return false;
+ }
+
+ if (ELEM(NULL, fcu, fcu->driver)) {
+ BKE_report(reports, RPT_ERROR, "Cannot paste driver variables without a driver");
+ return false;
+ }
+
+ /* 1) Make a new copy of the variables in the buffer - these will get pasted later... */
+ driver_variables_copy(&tmp_list, &driver_vars_copybuf);
+
+ /* 2) Prepare destination array */
+ if (replace) {
+ DriverVar *dvar, *dvarn;
+
+ /* Free all existing vars first - We aren't retaining anything */
+ for (dvar = driver->variables.first; dvar; dvar = dvarn) {
+ dvarn = dvar->next;
+ driver_free_variable_ex(driver, dvar);
+ }
+
+ BLI_listbase_clear(&driver->variables);
+ }
+
+ /* 3) Add new vars */
+ if (driver->variables.last) {
+ DriverVar *last = driver->variables.last;
+ DriverVar *first = tmp_list.first;
+
+ last->next = first;
+ first->prev = last;
+
+ driver->variables.last = tmp_list.last;
+ }
+ else {
+ driver->variables.first = tmp_list.first;
+ driver->variables.last = tmp_list.last;
+ }
+
+#ifdef WITH_PYTHON
+ /* since driver variables are cached, the expression needs re-compiling too */
+ if (driver->type == DRIVER_TYPE_PYTHON)
+ driver->flag |= DRIVER_FLAG_RENAMEVAR;
+#endif
+
+ return true;
+}
+
+/* ************************************************** */
/* UI-Button Interface */
/* Add Driver - Enum Defines ------------------------- */
diff --git a/source/blender/editors/include/ED_keyframing.h b/source/blender/editors/include/ED_keyframing.h
index 9a41197..81e2558 100644
--- a/source/blender/editors/include/ED_keyframing.h
+++ b/source/blender/editors/include/ED_keyframing.h
@@ -291,6 +291,9 @@ bool ANIM_remove_driver(struct ReportList *reports, struct ID *id, const char rn
/* Clear copy-paste buffer for drivers */
void ANIM_drivers_copybuf_free(void);
+/* Clear copy-paste buffer for driver variable sets */
+void ANIM_driver_vars_copybuf_free(void);
+
/* -------- */
/* Returns whether there is a driver in the copy/paste buffer to paste */
@@ -307,6 +310,17 @@ bool ANIM_copy_driver(struct ReportList *reports, struct ID *id, const char rna_
*/
bool ANIM_paste_driver(struct ReportList *reports, struct ID *id, const char rna_path[], int array_index, short flag);
+/* -------- */
+
+/* Checks if there are driver variables in the copy/paste buffer */
+bool ANIM_driver_vars_can_paste(void);
+
+/* Copy the given driver's variables to the buffer */
+bool ANIM_driver_vars_copy(struct ReportList *reports, struct
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list