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:
authorJoshua Leung <aligorith@gmail.com>2016-04-15 11:04:07 +0300
committerJoshua Leung <aligorith@gmail.com>2016-04-15 11:05:09 +0300
commit69ee6c986657bf0d6bf631277751d24e72d76bac (patch)
tree664ec41aac0e2ab44e394df83684d2a73c4c7c76 /source/blender/editors
parentc97b0b14e3d7ab2980c6fad645a99382df92e52f (diff)
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!
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/animation/CMakeLists.txt4
-rw-r--r--source/blender/editors/animation/drivers.c116
-rw-r--r--source/blender/editors/include/ED_keyframing.h14
-rw-r--r--source/blender/editors/space_graph/graph_buttons.c30
-rw-r--r--source/blender/editors/space_graph/graph_edit.c128
-rw-r--r--source/blender/editors/space_graph/graph_intern.h5
-rw-r--r--source/blender/editors/space_graph/graph_ops.c4
7 files changed, 291 insertions, 10 deletions
diff --git a/source/blender/editors/animation/CMakeLists.txt b/source/blender/editors/animation/CMakeLists.txt
index 473b0e6bc5a..1bf1bb2a474 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 4ddf37aa3a1..27bed693619 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 9a411975880..81e2558e765 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 FCurve *fcu);
+
+/* Paste the variables in the buffer to the given FCurve */
+bool ANIM_driver_vars_paste(struct ReportList *reports, struct FCurve *fcu, bool replace);
+
/* ************ Auto-Keyframing ********************** */
/* Notes:
* - All the defines for this (User-Pref settings and Per-Scene settings)
diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c
index f8b081eda20..5846a439b3c 100644
--- a/source/blender/editors/space_graph/graph_buttons.c
+++ b/source/blender/editors/space_graph/graph_buttons.c
@@ -516,7 +516,7 @@ static void driver_delete_var_cb(bContext *UNUSED(C), void *driver_v, void *dvar
DriverVar *dvar = (DriverVar *)dvar_v;
/* remove the active variable */
- driver_free_variable(driver, dvar);
+ driver_free_variable_ex(driver, dvar);
}
/* callback to report why a driver variable is invalid */
@@ -825,14 +825,26 @@ static void graph_panel_drivers(const bContext *C, Panel *pa)
uiItemL(row, valBuf, ICON_NONE);
}
- /* add driver variables */
- col = uiLayoutColumn(pa->layout, false);
- block = uiLayoutGetBlock(col);
- but = uiDefIconTextBut(block, UI_BTYPE_BUT, B_IPO_DEPCHANGE, ICON_ZOOMIN, IFACE_("Add Variable"),
- 0, 0, 10 * UI_UNIT_X, UI_UNIT_Y,
- NULL, 0.0, 0.0, 0, 0,
- TIP_("Driver variables ensure that all dependencies will be accounted for and that drivers will update correctly"));
- UI_but_func_set(but, driver_add_var_cb, driver, NULL);
+ /* add/copy/paste driver variables */
+ {
+ uiLayout *row;
+
+ /* add driver variable */
+ row = uiLayoutRow(pa->layout, false);
+ block = uiLayoutGetBlock(row);
+ but = uiDefIconTextBut(block, UI_BTYPE_BUT, B_IPO_DEPCHANGE, ICON_ZOOMIN, IFACE_("Add Variable"),
+ 0, 0, 10 * UI_UNIT_X, UI_UNIT_Y,
+ NULL, 0.0, 0.0, 0, 0,
+ TIP_("Driver variables ensure that all dependencies will be accounted for and that drivers will update correctly"));
+ UI_but_func_set(but, driver_add_var_cb, driver, NULL);
+
+ /* copy/paste (as sub-row) */
+ row = uiLayoutRow(row, true);
+ block = uiLayoutGetBlock(row);
+
+ uiItemO(row, "", ICON_COPYDOWN, "GRAPH_OT_driver_variables_copy");
+ uiItemO(row, "", ICON_PASTEDOWN, "GRAPH_OT_driver_variables_paste");
+ }
/* loop over targets, drawing them */
for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index dd2ec2401a5..a54b7e141f3 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -54,6 +54,7 @@
#include "BLT_translation.h"
+#include "BKE_depsgraph.h"
#include "BKE_fcurve.h"
#include "BKE_global.h"
#include "BKE_nla.h"
@@ -2610,3 +2611,130 @@ void GRAPH_OT_fmodifier_paste(wmOperatorType *ot)
}
/* ************************************************************************** */
+/* Drivers */
+
+/* ******************** Copy Driver Vars Operator *********************** */
+
+static int graph_driver_vars_copy_exec(bContext *C, wmOperator *op)
+{
+ bAnimContext ac;
+ bAnimListElem *ale;
+ bool ok = false;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* clear buffer first */
+ ANIM_driver_vars_copybuf_free();
+
+ /* get the active F-Curve */
+ ale = get_active_fcurve_channel(&ac);
+
+ /* if this exists, call the copy driver vars API function */
+ if (ale && ale->data) {
+ FCurve *fcu = (FCurve *)ale->data;
+
+ ok = ANIM_driver_vars_copy(op->reports, fcu);
+
+ /* free temp data now */
+ MEM_freeN(ale);
+ }
+
+ /* successful or not? */
+ if (ok == 0)
+ return OPERATOR_CANCELLED;
+ else
+ return OPERATOR_FINISHED;
+}
+
+void GRAPH_OT_driver_variables_copy(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Copy Driver Variables";
+ ot->idname = "GRAPH_OT_driver_variables_copy";
+ ot->description = "Copy the driver variables of the active F-Curve";
+
+ /* api callbacks */
+ ot->exec = graph_driver_vars_copy_exec;
+ ot->poll = graphop_active_fcurve_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+/* ******************** Paste Driver Vars Operator *********************** */
+
+static int graph_driver_vars_paste_exec(bContext *C, wmOperator *op)
+{
+ bAnimContext ac;
+
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ const bool replace = RNA_boolean_get(op->ptr, "replace");
+ bool ok = false;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_ACTIVE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+
+ /* paste modifiers */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ FCurve *fcu = (FCurve *)ale->data;
+ bool paste_ok;
+
+ printf("pasting vars to %p -> %p\n", fcu, fcu->driver);
+ paste_ok = ANIM_driver_vars_paste(op->reports, fcu, replace);
+
+ if (paste_ok) {
+ //ale->update |= ANIM_UPDATE_DEPS;
+ printf("now we have: %d vars\n", BLI_listbase_count(&fcu->driver->variables));
+ ok = true;
+ }
+ }
+
+ // XXX: something causes a crash after adding the copies (to empty list), if we do an update immediately
+ if (ok) {
+ DAG_relations_tag_update(CTX_data_main(C));
+ //ANIM_animdata_update(&ac, &anim_data);
+ }
+ ANIM_animdata_freelist(&anim_data);
+
+ /* successful or not? */
+ if (ok) {
+ /* set notifier that keyframes have changed */
+ WM_event_add_notifier(C, NC_SCENE | ND_FRAME, CTX_data_scene(C));
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
+}
+
+void GRAPH_OT_driver_variables_paste(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Paste Driver Variables";
+ ot->idname = "GRAPH_OT_driver_variables_paste";
+ ot->description = "Add copied driver variables to the active driver";
+
+ /* api callbacks */
+ ot->exec = graph_driver_vars_paste_exec;
+ ot->poll = graphop_active_fcurve_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ RNA_def_boolean(ot->srna, "only_active", true, "Only Active", "Only paste F-Modifiers on active F-Curve");
+ RNA_def_boolean(ot->srna, "replace", false, "Replace Existing",
+ "Replace existing F-Modifiers, instead of just appending to the end of the existing list");
+}
+
+/* ************************************************************************** */
diff --git a/source/blender/editors/space_graph/graph_intern.h b/source/blender/editors/space_graph/graph_intern.h
index a478a86a5e2..b6b711e129f 100644
--- a/source/blender/editors/space_graph/graph_intern.h
+++ b/source/blender/editors/space_graph/graph_intern.h
@@ -148,6 +148,11 @@ void GRAPH_OT_fmodifier_paste(struct wmOperatorType *ot);
/* ----------- */
+void GRAPH_OT_driver_variables_copy(struct wmOperatorType *ot);
+void GRAPH_OT_driver_variables_paste(struct wmOperatorType *ot);
+
+/* ----------- */
+
void GRAPH_OT_ghost_curves_create(struct wmOperatorType *ot);
void GRAPH_OT_ghost_curves_clear(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c
index 59215531ac0..7ffa8250067 100644
--- a/source/blender/editors/space_graph/graph_ops.c
+++ b/source/blender/editors/space_graph/graph_ops.c
@@ -458,6 +458,10 @@ void graphedit_operatortypes(void)
WM_operatortype_append(GRAPH_OT_fmodifier_add);
WM_operatortype_append(GRAPH_OT_fmodifier_copy);
WM_operatortype_append(GRAPH_OT_fmodifier_paste);
+
+ /* Drivers */
+ WM_operatortype_append(GRAPH_OT_driver_variables_copy);
+ WM_operatortype_append(GRAPH_OT_driver_variables_paste);
}
void ED_operatormacros_graph(void)