2011-02-23 10:52:22 +00:00
|
|
|
/*
|
2009-07-02 05:25:14 +00:00
|
|
|
* ***** 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,
|
2010-02-12 13:34:04 +00:00
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2009-07-02 05:25:14 +00:00
|
|
|
*
|
|
|
|
|
* The Original Code is Copyright (C) 2009 Blender Foundation, Joshua Leung
|
|
|
|
|
* All rights reserved.
|
|
|
|
|
*
|
|
|
|
|
* The Original Code is: all of this file.
|
|
|
|
|
*
|
|
|
|
|
* Contributor(s): Joshua Leung (full recode)
|
|
|
|
|
*
|
|
|
|
|
* ***** END GPL LICENSE BLOCK *****
|
2009-04-10 13:08:12 +00:00
|
|
|
*/
|
2011-02-27 20:29:51 +00:00
|
|
|
|
|
|
|
|
/** \file blender/editors/animation/drivers.c
|
|
|
|
|
* \ingroup edanimation
|
|
|
|
|
*/
|
|
|
|
|
|
2009-04-10 13:08:12 +00:00
|
|
|
|
2011-01-14 02:06:35 +00:00
|
|
|
#include <stdio.h>
|
2009-04-10 13:08:12 +00:00
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
|
|
|
|
|
#include "BLI_blenlib.h"
|
2011-01-07 18:36:47 +00:00
|
|
|
#include "BLI_utildefines.h"
|
2009-04-10 13:08:12 +00:00
|
|
|
|
|
|
|
|
#include "DNA_anim_types.h"
|
2011-01-14 02:06:35 +00:00
|
|
|
#include "DNA_texture_types.h"
|
2009-04-10 13:08:12 +00:00
|
|
|
|
|
|
|
|
#include "BKE_animsys.h"
|
|
|
|
|
#include "BKE_fcurve.h"
|
|
|
|
|
#include "BKE_context.h"
|
2010-12-28 05:45:15 +00:00
|
|
|
#include "BKE_report.h"
|
|
|
|
|
|
|
|
|
|
#include "ED_keyframing.h"
|
2009-04-10 13:08:12 +00:00
|
|
|
|
|
|
|
|
#include "UI_interface.h"
|
|
|
|
|
|
|
|
|
|
#include "WM_api.h"
|
|
|
|
|
#include "WM_types.h"
|
|
|
|
|
|
|
|
|
|
#include "RNA_access.h"
|
|
|
|
|
#include "RNA_define.h"
|
|
|
|
|
|
2011-02-13 10:52:18 +00:00
|
|
|
#include "anim_intern.h"
|
|
|
|
|
|
|
|
|
|
/* called by WM */
|
2012-04-29 17:11:40 +00:00
|
|
|
void free_anim_drivers_copybuf(void);
|
2011-02-13 10:52:18 +00:00
|
|
|
|
2009-04-10 13:08:12 +00:00
|
|
|
/* ************************************************** */
|
|
|
|
|
/* Animation Data Validation */
|
|
|
|
|
|
|
|
|
|
/* Get (or add relevant data to be able to do so) F-Curve from the driver stack,
|
|
|
|
|
* for the given Animation Data block. This assumes that all the destinations are valid.
|
2009-09-25 04:51:04 +00:00
|
|
|
*
|
|
|
|
|
* - add: 0 - don't add anything if not found,
|
Tweaks to New Driver creation behaviour
* 'Show Debug' now enabled for all newly created drivers. For most users, it is
useful to be able to see this to help figure out what's going on
* Removed failed experiment of creating new drivers with Generator FModifiers. I
had hoped that this would make it easier to create drivers that doubled or
halved the input values, but that has proved to not be the case, and instead
made harder for most users to set things up (as they'd have to remove these
first).
Now, when adding drivers from the UI, these get created with two keyframes (at
(0,0) and (1,1) for a 1-1 mapping), which can be easily tweaked normally.
However, for backwards compatability of scripts (notably rigify, and perhaps
some others out there), when creating drivers from scripts, they will still get
created with Generator FModifiers for now. We can review this situation again
for 2.7, but for now it seems ok.
2013-09-03 00:28:23 +00:00
|
|
|
* 1 - add new Driver FCurve (with keyframes for visual tweaking),
|
2013-10-31 14:10:01 +00:00
|
|
|
* 2 - add new Driver FCurve (with generator, for script backwards compatibility)
|
2009-09-25 04:51:04 +00:00
|
|
|
* -1 - add new Driver FCurve without driver stuff (for pasting)
|
2009-04-10 13:08:12 +00:00
|
|
|
*/
|
2012-05-08 15:30:00 +00:00
|
|
|
FCurve *verify_driver_fcurve(ID *id, const char rna_path[], const int array_index, short add)
|
2009-04-10 13:08:12 +00:00
|
|
|
{
|
|
|
|
|
AnimData *adt;
|
|
|
|
|
FCurve *fcu;
|
|
|
|
|
|
|
|
|
|
/* sanity checks */
|
2012-03-25 22:35:18 +00:00
|
|
|
if (ELEM(NULL, id, rna_path))
|
2009-04-10 13:08:12 +00:00
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
/* init animdata if none available yet */
|
2012-05-08 15:30:00 +00:00
|
|
|
adt = BKE_animdata_from_id(id);
|
2009-04-10 13:08:12 +00:00
|
|
|
if ((adt == NULL) && (add))
|
2012-05-08 15:30:00 +00:00
|
|
|
adt = BKE_id_add_animdata(id);
|
2012-10-21 05:46:41 +00:00
|
|
|
if (adt == NULL) {
|
2009-04-10 13:08:12 +00:00
|
|
|
/* if still none (as not allowed to add, or ID doesn't have animdata for some reason) */
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* try to find f-curve matching for this setting
|
|
|
|
|
* - add if not found and allowed to add one
|
|
|
|
|
* TODO: add auto-grouping support? how this works will need to be resolved
|
|
|
|
|
*/
|
2012-05-08 15:30:00 +00:00
|
|
|
fcu = list_find_fcurve(&adt->drivers, rna_path, array_index);
|
2009-04-10 13:08:12 +00:00
|
|
|
|
|
|
|
|
if ((fcu == NULL) && (add)) {
|
|
|
|
|
/* use default settings to make a F-Curve */
|
2012-05-08 15:30:00 +00:00
|
|
|
fcu = MEM_callocN(sizeof(FCurve), "FCurve");
|
2009-04-10 13:08:12 +00:00
|
|
|
|
2012-05-08 15:30:00 +00:00
|
|
|
fcu->flag = (FCURVE_VISIBLE | FCURVE_SELECTED);
|
2009-04-10 13:08:12 +00:00
|
|
|
|
|
|
|
|
/* store path - make copy, and store that */
|
2014-05-29 02:09:45 +10:00
|
|
|
fcu->rna_path = BLI_strdup(rna_path);
|
2012-05-08 15:30:00 +00:00
|
|
|
fcu->array_index = array_index;
|
2009-04-10 13:08:12 +00:00
|
|
|
|
2009-09-25 04:51:04 +00:00
|
|
|
/* if add is negative, don't init this data yet, since it will be filled in by the pasted driver */
|
|
|
|
|
if (add > 0) {
|
Tweaks to New Driver creation behaviour
* 'Show Debug' now enabled for all newly created drivers. For most users, it is
useful to be able to see this to help figure out what's going on
* Removed failed experiment of creating new drivers with Generator FModifiers. I
had hoped that this would make it easier to create drivers that doubled or
halved the input values, but that has proved to not be the case, and instead
made harder for most users to set things up (as they'd have to remove these
first).
Now, when adding drivers from the UI, these get created with two keyframes (at
(0,0) and (1,1) for a 1-1 mapping), which can be easily tweaked normally.
However, for backwards compatability of scripts (notably rigify, and perhaps
some others out there), when creating drivers from scripts, they will still get
created with Generator FModifiers for now. We can review this situation again
for 2.7, but for now it seems ok.
2013-09-03 00:28:23 +00:00
|
|
|
BezTriple *bezt;
|
|
|
|
|
size_t i;
|
|
|
|
|
|
2009-09-25 04:51:04 +00:00
|
|
|
/* add some new driver data */
|
2012-05-08 15:30:00 +00:00
|
|
|
fcu->driver = MEM_callocN(sizeof(ChannelDriver), "ChannelDriver");
|
Tweaks to New Driver creation behaviour
* 'Show Debug' now enabled for all newly created drivers. For most users, it is
useful to be able to see this to help figure out what's going on
* Removed failed experiment of creating new drivers with Generator FModifiers. I
had hoped that this would make it easier to create drivers that doubled or
halved the input values, but that has proved to not be the case, and instead
made harder for most users to set things up (as they'd have to remove these
first).
Now, when adding drivers from the UI, these get created with two keyframes (at
(0,0) and (1,1) for a 1-1 mapping), which can be easily tweaked normally.
However, for backwards compatability of scripts (notably rigify, and perhaps
some others out there), when creating drivers from scripts, they will still get
created with Generator FModifiers for now. We can review this situation again
for 2.7, but for now it seems ok.
2013-09-03 00:28:23 +00:00
|
|
|
fcu->driver->flag |= DRIVER_FLAG_SHOWDEBUG;
|
2009-09-25 04:51:04 +00:00
|
|
|
|
Tweaks to New Driver creation behaviour
* 'Show Debug' now enabled for all newly created drivers. For most users, it is
useful to be able to see this to help figure out what's going on
* Removed failed experiment of creating new drivers with Generator FModifiers. I
had hoped that this would make it easier to create drivers that doubled or
halved the input values, but that has proved to not be the case, and instead
made harder for most users to set things up (as they'd have to remove these
first).
Now, when adding drivers from the UI, these get created with two keyframes (at
(0,0) and (1,1) for a 1-1 mapping), which can be easily tweaked normally.
However, for backwards compatability of scripts (notably rigify, and perhaps
some others out there), when creating drivers from scripts, they will still get
created with Generator FModifiers for now. We can review this situation again
for 2.7, but for now it seems ok.
2013-09-03 00:28:23 +00:00
|
|
|
/* F-Modifier or Keyframes? */
|
|
|
|
|
// FIXME: replace these magic numbers with defines
|
|
|
|
|
if (add == 2) {
|
2013-10-31 14:10:01 +00:00
|
|
|
/* Python API Backwards compatibility hack:
|
Tweaks to New Driver creation behaviour
* 'Show Debug' now enabled for all newly created drivers. For most users, it is
useful to be able to see this to help figure out what's going on
* Removed failed experiment of creating new drivers with Generator FModifiers. I
had hoped that this would make it easier to create drivers that doubled or
halved the input values, but that has proved to not be the case, and instead
made harder for most users to set things up (as they'd have to remove these
first).
Now, when adding drivers from the UI, these get created with two keyframes (at
(0,0) and (1,1) for a 1-1 mapping), which can be easily tweaked normally.
However, for backwards compatability of scripts (notably rigify, and perhaps
some others out there), when creating drivers from scripts, they will still get
created with Generator FModifiers for now. We can review this situation again
for 2.7, but for now it seems ok.
2013-09-03 00:28:23 +00:00
|
|
|
* Create FModifier so that old scripts won't break
|
|
|
|
|
* for now before 2.7 series -- (September 4, 2013)
|
|
|
|
|
*/
|
|
|
|
|
add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_GENERATOR);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* add 2 keyframes so that user has something to work with
|
|
|
|
|
* - These are configured to 0,0 and 1,1 to give a 1-1 mapping
|
|
|
|
|
* which can be easily tweaked from there.
|
|
|
|
|
*/
|
|
|
|
|
insert_vert_fcurve(fcu, 0.0f, 0.0f, INSERTKEY_FAST);
|
|
|
|
|
insert_vert_fcurve(fcu, 1.0f, 1.0f, INSERTKEY_FAST);
|
|
|
|
|
|
|
|
|
|
/* configure this curve to extrapolate */
|
|
|
|
|
for (i = 0, bezt = fcu->bezt; (i < fcu->totvert) && bezt; i++, bezt++) {
|
|
|
|
|
bezt->h1 = bezt->h2 = HD_VECT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fcu->extend = FCURVE_EXTRAPOLATE_LINEAR;
|
|
|
|
|
calchandles_fcurve(fcu);
|
|
|
|
|
}
|
2009-09-25 04:51:04 +00:00
|
|
|
}
|
2009-04-10 13:16:50 +00:00
|
|
|
|
2009-04-10 13:08:12 +00:00
|
|
|
/* just add F-Curve to end of driver list */
|
|
|
|
|
BLI_addtail(&adt->drivers, fcu);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* return the F-Curve */
|
|
|
|
|
return fcu;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ************************************************** */
|
|
|
|
|
/* Driver Management API */
|
|
|
|
|
|
|
|
|
|
/* Main Driver Management API calls:
|
2012-05-08 15:30:00 +00:00
|
|
|
* Add a new driver for the specified property on the given ID block
|
2009-04-10 13:08:12 +00:00
|
|
|
*/
|
2014-04-01 11:34:00 +11:00
|
|
|
int ANIM_add_driver(ReportList *reports, ID *id, const char rna_path[], int array_index, short flag, int type)
|
2009-04-10 13:08:12 +00:00
|
|
|
{
|
|
|
|
|
PointerRNA id_ptr, ptr;
|
|
|
|
|
PropertyRNA *prop;
|
|
|
|
|
FCurve *fcu;
|
2009-11-19 00:37:47 +00:00
|
|
|
int array_index_max;
|
2014-04-01 16:46:38 +11:00
|
|
|
int done_tot = 0;
|
2009-04-10 13:08:12 +00:00
|
|
|
|
|
|
|
|
/* validate pointer first - exit if failure */
|
|
|
|
|
RNA_id_pointer_create(id, &id_ptr);
|
Bugfix [#34836] Crash when driver variable has path == 'data'
Most of the places which relied on RNA_path_resolve() did so believing that if
it returned true, that it had found a valid property, and that the returned
pointer+property combination would be what the path referred to. However, it
turns out that if the property at the end of the path turns out to be a
"pointer" property (e.g. "data" for Object.data), this would automatically
become the pointer part, while the prop part would be set to null. Hence, if a
user accidentally (or otherwise) specifies a path for the single-property driver
variable type like this, then Blender would crash.
This commit introduces two convenience functions - RNA_path_resolve_property()
and RNA_path_resolve_property_full() - which mirror/wrap the existing
RNA_path_resolve() functions. The only difference though is that these include a
check to ensure that what was found from resolving the path was in fact a
property (they only return true iff this is the case), and make it explicitly
clear in the name that this is what they will do so that there's no further
confusion. It is possible to do without these wrapper functions by doing these
checks inline, but the few cases that had been patched already were pretty
hideous looking specimens. Using these just make it clearer and simpler for all.
I've also beefed up the docs on these a bit, and changed these to using bools.
2013-04-22 13:22:07 +00:00
|
|
|
if (RNA_path_resolve_property(&id_ptr, rna_path, &ptr, &prop) == false) {
|
2010-12-28 05:45:15 +00:00
|
|
|
BKE_reportf(reports, RPT_ERROR,
|
2012-10-18 16:25:58 +00:00
|
|
|
"Could not add driver, as RNA path is invalid for the given ID (ID = %s, path = %s)",
|
2012-05-08 15:30:00 +00:00
|
|
|
id->name, rna_path);
|
2009-04-10 13:08:12 +00:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2009-11-05 08:54:33 +00:00
|
|
|
/* key entire array convenience method */
|
|
|
|
|
if (array_index == -1) {
|
2012-05-08 15:30:00 +00:00
|
|
|
array_index_max = RNA_property_array_length(&ptr, prop);
|
|
|
|
|
array_index = 0;
|
2009-11-04 15:16:41 +00:00
|
|
|
}
|
2009-11-19 00:37:47 +00:00
|
|
|
else
|
2012-05-08 15:30:00 +00:00
|
|
|
array_index_max = array_index;
|
2009-11-19 00:37:47 +00:00
|
|
|
|
|
|
|
|
/* maximum index should be greater than the start index */
|
|
|
|
|
if (array_index == array_index_max)
|
|
|
|
|
array_index_max += 1;
|
2009-11-05 08:54:33 +00:00
|
|
|
|
2009-11-04 15:16:41 +00:00
|
|
|
/* will only loop once unless the array index was -1 */
|
2009-11-05 08:54:33 +00:00
|
|
|
for (; array_index < array_index_max; array_index++) {
|
Tweaks to New Driver creation behaviour
* 'Show Debug' now enabled for all newly created drivers. For most users, it is
useful to be able to see this to help figure out what's going on
* Removed failed experiment of creating new drivers with Generator FModifiers. I
had hoped that this would make it easier to create drivers that doubled or
halved the input values, but that has proved to not be the case, and instead
made harder for most users to set things up (as they'd have to remove these
first).
Now, when adding drivers from the UI, these get created with two keyframes (at
(0,0) and (1,1) for a 1-1 mapping), which can be easily tweaked normally.
However, for backwards compatability of scripts (notably rigify, and perhaps
some others out there), when creating drivers from scripts, they will still get
created with Generator FModifiers for now. We can review this situation again
for 2.7, but for now it seems ok.
2013-09-03 00:28:23 +00:00
|
|
|
short add_mode = (flag & CREATEDRIVER_WITH_FMODIFIER) ? 2 : 1;
|
|
|
|
|
|
2009-11-04 15:16:41 +00:00
|
|
|
/* create F-Curve with Driver */
|
Tweaks to New Driver creation behaviour
* 'Show Debug' now enabled for all newly created drivers. For most users, it is
useful to be able to see this to help figure out what's going on
* Removed failed experiment of creating new drivers with Generator FModifiers. I
had hoped that this would make it easier to create drivers that doubled or
halved the input values, but that has proved to not be the case, and instead
made harder for most users to set things up (as they'd have to remove these
first).
Now, when adding drivers from the UI, these get created with two keyframes (at
(0,0) and (1,1) for a 1-1 mapping), which can be easily tweaked normally.
However, for backwards compatability of scripts (notably rigify, and perhaps
some others out there), when creating drivers from scripts, they will still get
created with Generator FModifiers for now. We can review this situation again
for 2.7, but for now it seems ok.
2013-09-03 00:28:23 +00:00
|
|
|
fcu = verify_driver_fcurve(id, rna_path, array_index, add_mode);
|
2009-11-05 08:54:33 +00:00
|
|
|
|
2009-11-04 15:16:41 +00:00
|
|
|
if (fcu && fcu->driver) {
|
2012-05-08 15:30:00 +00:00
|
|
|
ChannelDriver *driver = fcu->driver;
|
2009-11-25 09:25:58 +00:00
|
|
|
|
|
|
|
|
/* set the type of the driver */
|
2012-05-08 15:30:00 +00:00
|
|
|
driver->type = type;
|
2009-09-04 11:19:12 +00:00
|
|
|
|
2010-12-28 05:45:15 +00:00
|
|
|
/* creating drivers for buttons will create the driver(s) with type
|
|
|
|
|
* "scripted expression" so that their values won't be lost immediately,
|
|
|
|
|
* so here we copy those values over to the driver's expression
|
|
|
|
|
*/
|
2009-11-04 15:16:41 +00:00
|
|
|
if (type == DRIVER_TYPE_PYTHON) {
|
2012-05-08 15:30:00 +00:00
|
|
|
PropertyType proptype = RNA_property_type(prop);
|
|
|
|
|
int array = RNA_property_array_length(&ptr, prop);
|
|
|
|
|
char *expression = driver->expression;
|
|
|
|
|
int val, maxlen = sizeof(driver->expression);
|
2009-11-04 15:16:41 +00:00
|
|
|
float fval;
|
2009-09-04 11:19:12 +00:00
|
|
|
|
2009-11-04 15:16:41 +00:00
|
|
|
if (proptype == PROP_BOOLEAN) {
|
2012-05-08 15:30:00 +00:00
|
|
|
if (!array) val = RNA_property_boolean_get(&ptr, prop);
|
|
|
|
|
else val = RNA_property_boolean_get_index(&ptr, prop, array_index);
|
2009-11-05 08:54:33 +00:00
|
|
|
|
2012-05-08 15:30:00 +00:00
|
|
|
BLI_strncpy(expression, (val) ? "True" : "False", maxlen);
|
2009-11-04 15:16:41 +00:00
|
|
|
}
|
|
|
|
|
else if (proptype == PROP_INT) {
|
2012-05-08 15:30:00 +00:00
|
|
|
if (!array) val = RNA_property_int_get(&ptr, prop);
|
|
|
|
|
else val = RNA_property_int_get_index(&ptr, prop, array_index);
|
2009-11-05 08:54:33 +00:00
|
|
|
|
2009-11-04 15:16:41 +00:00
|
|
|
BLI_snprintf(expression, maxlen, "%d", val);
|
|
|
|
|
}
|
|
|
|
|
else if (proptype == PROP_FLOAT) {
|
2012-05-08 15:30:00 +00:00
|
|
|
if (!array) fval = RNA_property_float_get(&ptr, prop);
|
|
|
|
|
else fval = RNA_property_float_get_index(&ptr, prop, array_index);
|
2009-11-05 08:54:33 +00:00
|
|
|
|
2009-11-04 15:16:41 +00:00
|
|
|
BLI_snprintf(expression, maxlen, "%.3f", fval);
|
|
|
|
|
}
|
2009-07-12 02:06:15 +00:00
|
|
|
}
|
2010-12-28 05:45:15 +00:00
|
|
|
|
|
|
|
|
/* for easier setup of drivers from UI, a driver variable should be
|
|
|
|
|
* added if flag is set (UI calls only)
|
|
|
|
|
*/
|
|
|
|
|
if (flag & CREATEDRIVER_WITH_DEFAULT_DVAR) {
|
|
|
|
|
/* assume that users will mostly want this to be of type "Transform Channel" too,
|
|
|
|
|
* since this allows the easiest setting up of common rig components
|
|
|
|
|
*/
|
|
|
|
|
DriverVar *dvar = driver_add_new_variable(driver);
|
|
|
|
|
driver_change_variable_type(dvar, DVAR_TYPE_TRANSFORM_CHAN);
|
|
|
|
|
}
|
2009-07-12 02:06:15 +00:00
|
|
|
}
|
2009-11-08 06:43:08 +00:00
|
|
|
|
|
|
|
|
/* set the done status */
|
2014-04-01 11:34:00 +11:00
|
|
|
done_tot += (fcu != NULL);
|
2009-07-12 02:06:15 +00:00
|
|
|
}
|
2009-04-10 13:08:12 +00:00
|
|
|
|
|
|
|
|
/* done */
|
2014-04-01 11:34:00 +11:00
|
|
|
return done_tot;
|
2009-04-10 13:08:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Main Driver Management API calls:
|
2012-05-08 15:30:00 +00:00
|
|
|
* Remove the driver for the specified property on the given ID block (if available)
|
2009-04-10 13:08:12 +00:00
|
|
|
*/
|
2014-04-01 11:34:00 +11:00
|
|
|
bool ANIM_remove_driver(ReportList *UNUSED(reports), ID *id, const char rna_path[], int array_index, short UNUSED(flag))
|
2009-04-10 13:08:12 +00:00
|
|
|
{
|
|
|
|
|
AnimData *adt;
|
|
|
|
|
FCurve *fcu;
|
2014-04-01 11:34:00 +11:00
|
|
|
bool success = false;
|
2009-04-10 13:08:12 +00:00
|
|
|
|
|
|
|
|
/* we don't check the validity of the path here yet, but it should be ok... */
|
2012-05-08 15:30:00 +00:00
|
|
|
adt = BKE_animdata_from_id(id);
|
2009-04-10 13:08:12 +00:00
|
|
|
|
2010-12-28 05:45:15 +00:00
|
|
|
if (adt) {
|
|
|
|
|
if (array_index == -1) {
|
|
|
|
|
/* step through all drivers, removing all of those with the same base path */
|
2012-05-08 15:30:00 +00:00
|
|
|
FCurve *fcu_iter = adt->drivers.first;
|
2010-12-28 05:45:15 +00:00
|
|
|
|
|
|
|
|
while ((fcu = iter_step_fcurve(fcu_iter, rna_path)) != NULL) {
|
2010-04-11 09:13:37 +00:00
|
|
|
/* store the next fcurve for looping */
|
2012-05-08 15:30:00 +00:00
|
|
|
fcu_iter = fcu->next;
|
2010-04-11 09:13:37 +00:00
|
|
|
|
|
|
|
|
/* remove F-Curve from driver stack, then free it */
|
|
|
|
|
BLI_remlink(&adt->drivers, fcu);
|
|
|
|
|
free_fcurve(fcu);
|
|
|
|
|
|
|
|
|
|
/* done successfully */
|
2014-04-01 11:34:00 +11:00
|
|
|
success = true;
|
2010-04-11 09:13:37 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
2010-12-28 05:45:15 +00:00
|
|
|
/* find the matching driver and remove it only
|
|
|
|
|
* Note: here is one of the places where we don't want new F-Curve + Driver added!
|
2012-05-08 15:30:00 +00:00
|
|
|
* so 'add' var must be 0
|
2010-12-28 05:45:15 +00:00
|
|
|
*/
|
2012-05-08 15:30:00 +00:00
|
|
|
fcu = verify_driver_fcurve(id, rna_path, array_index, 0);
|
2010-12-28 05:45:15 +00:00
|
|
|
if (fcu) {
|
2010-04-11 09:13:37 +00:00
|
|
|
BLI_remlink(&adt->drivers, fcu);
|
|
|
|
|
free_fcurve(fcu);
|
|
|
|
|
|
2014-04-01 11:34:00 +11:00
|
|
|
success = true;
|
2010-04-11 09:13:37 +00:00
|
|
|
}
|
|
|
|
|
}
|
2009-04-10 13:08:12 +00:00
|
|
|
}
|
2010-04-11 09:13:37 +00:00
|
|
|
|
|
|
|
|
return success;
|
2009-04-10 13:08:12 +00:00
|
|
|
}
|
|
|
|
|
|
2009-09-25 04:51:04 +00:00
|
|
|
/* ************************************************** */
|
|
|
|
|
/* Driver Management API - Copy/Paste Drivers */
|
|
|
|
|
|
|
|
|
|
/* Copy/Paste Buffer for Driver Data... */
|
|
|
|
|
static FCurve *channeldriver_copypaste_buf = NULL;
|
|
|
|
|
|
|
|
|
|
/* This function frees any MEM_calloc'ed copy/paste buffer data */
|
|
|
|
|
// XXX find some header to put this in!
|
2012-04-29 17:11:40 +00:00
|
|
|
void free_anim_drivers_copybuf(void)
|
2009-09-25 04:51:04 +00:00
|
|
|
{
|
|
|
|
|
/* free the buffer F-Curve if it exists, as if it were just another F-Curve */
|
|
|
|
|
if (channeldriver_copypaste_buf)
|
|
|
|
|
free_fcurve(channeldriver_copypaste_buf);
|
2012-05-08 15:30:00 +00:00
|
|
|
channeldriver_copypaste_buf = NULL;
|
2009-09-25 04:51:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Checks if there is a driver in the copy/paste buffer */
|
2014-04-01 11:34:00 +11:00
|
|
|
bool ANIM_driver_can_paste(void)
|
2009-09-25 04:51:04 +00:00
|
|
|
{
|
|
|
|
|
return (channeldriver_copypaste_buf != NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ------------------- */
|
|
|
|
|
|
|
|
|
|
/* Main Driver Management API calls:
|
2012-05-08 15:30:00 +00:00
|
|
|
* Make a copy of the driver for the specified property on the given ID block
|
2009-09-25 04:51:04 +00:00
|
|
|
*/
|
2014-04-01 11:34:00 +11:00
|
|
|
bool ANIM_copy_driver(ReportList *reports, ID *id, const char rna_path[], int array_index, short UNUSED(flag))
|
2009-09-25 04:51:04 +00:00
|
|
|
{
|
|
|
|
|
PointerRNA id_ptr, ptr;
|
|
|
|
|
PropertyRNA *prop;
|
|
|
|
|
FCurve *fcu;
|
|
|
|
|
|
|
|
|
|
/* validate pointer first - exit if failure */
|
|
|
|
|
RNA_id_pointer_create(id, &id_ptr);
|
Bugfix [#34836] Crash when driver variable has path == 'data'
Most of the places which relied on RNA_path_resolve() did so believing that if
it returned true, that it had found a valid property, and that the returned
pointer+property combination would be what the path referred to. However, it
turns out that if the property at the end of the path turns out to be a
"pointer" property (e.g. "data" for Object.data), this would automatically
become the pointer part, while the prop part would be set to null. Hence, if a
user accidentally (or otherwise) specifies a path for the single-property driver
variable type like this, then Blender would crash.
This commit introduces two convenience functions - RNA_path_resolve_property()
and RNA_path_resolve_property_full() - which mirror/wrap the existing
RNA_path_resolve() functions. The only difference though is that these include a
check to ensure that what was found from resolving the path was in fact a
property (they only return true iff this is the case), and make it explicitly
clear in the name that this is what they will do so that there's no further
confusion. It is possible to do without these wrapper functions by doing these
checks inline, but the few cases that had been patched already were pretty
hideous looking specimens. Using these just make it clearer and simpler for all.
I've also beefed up the docs on these a bit, and changed these to using bools.
2013-04-22 13:22:07 +00:00
|
|
|
if (RNA_path_resolve_property(&id_ptr, rna_path, &ptr, &prop) == false) {
|
2010-12-28 05:45:15 +00:00
|
|
|
BKE_reportf(reports, RPT_ERROR,
|
2012-10-18 16:25:58 +00:00
|
|
|
"Could not find driver to copy, as RNA path is invalid for the given ID (ID = %s, path = %s)",
|
2012-05-08 15:30:00 +00:00
|
|
|
id->name, rna_path);
|
2009-09-25 04:51:04 +00:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* try to get F-Curve with Driver */
|
2012-05-08 15:30:00 +00:00
|
|
|
fcu = verify_driver_fcurve(id, rna_path, array_index, 0);
|
2009-09-25 04:51:04 +00:00
|
|
|
|
|
|
|
|
/* clear copy/paste buffer first (for consistency with other copy/paste buffers) */
|
|
|
|
|
free_anim_drivers_copybuf();
|
|
|
|
|
|
|
|
|
|
/* copy this to the copy/paste buf if it exists */
|
|
|
|
|
if (fcu && fcu->driver) {
|
|
|
|
|
/* make copies of some info such as the rna_path, then clear this info from the F-Curve temporarily
|
|
|
|
|
* so that we don't end up wasting memory storing the path which won't get used ever...
|
|
|
|
|
*/
|
|
|
|
|
char *tmp_path = fcu->rna_path;
|
2012-05-08 15:30:00 +00:00
|
|
|
fcu->rna_path = NULL;
|
2009-09-25 04:51:04 +00:00
|
|
|
|
|
|
|
|
/* make a copy of the F-Curve with */
|
2012-05-08 15:30:00 +00:00
|
|
|
channeldriver_copypaste_buf = copy_fcurve(fcu);
|
2009-09-25 04:51:04 +00:00
|
|
|
|
|
|
|
|
/* restore the path */
|
2012-05-08 15:30:00 +00:00
|
|
|
fcu->rna_path = tmp_path;
|
2009-09-25 04:51:04 +00:00
|
|
|
|
|
|
|
|
/* copied... */
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* done */
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Main Driver Management API calls:
|
2012-05-08 15:30:00 +00:00
|
|
|
* Add a new driver for the specified property on the given ID block or replace an existing one
|
2009-09-25 04:51:04 +00:00
|
|
|
* with the driver + driver-curve data from the buffer
|
|
|
|
|
*/
|
2014-04-01 11:34:00 +11:00
|
|
|
bool ANIM_paste_driver(ReportList *reports, ID *id, const char rna_path[], int array_index, short UNUSED(flag))
|
2009-09-25 04:51:04 +00:00
|
|
|
{
|
|
|
|
|
PointerRNA id_ptr, ptr;
|
|
|
|
|
PropertyRNA *prop;
|
|
|
|
|
FCurve *fcu;
|
|
|
|
|
|
|
|
|
|
/* validate pointer first - exit if failure */
|
|
|
|
|
RNA_id_pointer_create(id, &id_ptr);
|
Bugfix [#34836] Crash when driver variable has path == 'data'
Most of the places which relied on RNA_path_resolve() did so believing that if
it returned true, that it had found a valid property, and that the returned
pointer+property combination would be what the path referred to. However, it
turns out that if the property at the end of the path turns out to be a
"pointer" property (e.g. "data" for Object.data), this would automatically
become the pointer part, while the prop part would be set to null. Hence, if a
user accidentally (or otherwise) specifies a path for the single-property driver
variable type like this, then Blender would crash.
This commit introduces two convenience functions - RNA_path_resolve_property()
and RNA_path_resolve_property_full() - which mirror/wrap the existing
RNA_path_resolve() functions. The only difference though is that these include a
check to ensure that what was found from resolving the path was in fact a
property (they only return true iff this is the case), and make it explicitly
clear in the name that this is what they will do so that there's no further
confusion. It is possible to do without these wrapper functions by doing these
checks inline, but the few cases that had been patched already were pretty
hideous looking specimens. Using these just make it clearer and simpler for all.
I've also beefed up the docs on these a bit, and changed these to using bools.
2013-04-22 13:22:07 +00:00
|
|
|
if (RNA_path_resolve_property(&id_ptr, rna_path, &ptr, &prop) == false) {
|
2010-12-28 05:45:15 +00:00
|
|
|
BKE_reportf(reports, RPT_ERROR,
|
2012-10-18 16:25:58 +00:00
|
|
|
"Could not paste driver, as RNA path is invalid for the given ID (ID = %s, path = %s)",
|
2012-05-08 15:30:00 +00:00
|
|
|
id->name, rna_path);
|
2009-09-25 04:51:04 +00:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* if the buffer is empty, cannot paste... */
|
|
|
|
|
if (channeldriver_copypaste_buf == NULL) {
|
2012-10-18 16:25:58 +00:00
|
|
|
BKE_report(reports, RPT_ERROR, "Paste driver: no driver to paste");
|
2009-09-25 04:51:04 +00:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* create Driver F-Curve, but without data which will be copied across... */
|
2012-05-08 15:30:00 +00:00
|
|
|
fcu = verify_driver_fcurve(id, rna_path, array_index, -1);
|
2009-09-25 04:51:04 +00:00
|
|
|
|
|
|
|
|
if (fcu) {
|
|
|
|
|
/* copy across the curve data from the buffer curve
|
|
|
|
|
* NOTE: this step needs care to not miss new settings
|
|
|
|
|
*/
|
2012-05-08 15:30:00 +00:00
|
|
|
/* keyframes/samples */
|
|
|
|
|
fcu->bezt = MEM_dupallocN(channeldriver_copypaste_buf->bezt);
|
|
|
|
|
fcu->fpt = MEM_dupallocN(channeldriver_copypaste_buf->fpt);
|
|
|
|
|
fcu->totvert = channeldriver_copypaste_buf->totvert;
|
2009-09-25 04:51:04 +00:00
|
|
|
|
2012-05-08 15:30:00 +00:00
|
|
|
/* modifiers */
|
2009-09-25 04:51:04 +00:00
|
|
|
copy_fmodifiers(&fcu->modifiers, &channeldriver_copypaste_buf->modifiers);
|
|
|
|
|
|
2012-05-08 15:30:00 +00:00
|
|
|
/* extrapolation mode */
|
|
|
|
|
fcu->extend = channeldriver_copypaste_buf->extend;
|
2009-09-25 04:51:04 +00:00
|
|
|
|
2012-05-08 15:30:00 +00:00
|
|
|
/* the 'juicy' stuff - the driver */
|
|
|
|
|
fcu->driver = fcurve_copy_driver(channeldriver_copypaste_buf->driver);
|
2009-09-25 04:51:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* done */
|
|
|
|
|
return (fcu != NULL);
|
|
|
|
|
}
|
2009-04-10 13:08:12 +00:00
|
|
|
|
|
|
|
|
/* ************************************************** */
|
|
|
|
|
/* UI-Button Interface */
|
|
|
|
|
|
|
|
|
|
/* Add Driver Button Operator ------------------------ */
|
|
|
|
|
|
2012-05-08 15:30:00 +00:00
|
|
|
static int add_driver_button_exec(bContext *C, wmOperator *op)
|
2009-04-10 13:08:12 +00:00
|
|
|
{
|
2012-05-08 15:30:00 +00:00
|
|
|
PointerRNA ptr = {{NULL}};
|
|
|
|
|
PropertyRNA *prop = NULL;
|
2014-04-01 11:34:00 +11:00
|
|
|
int success = 0;
|
2014-02-03 18:55:59 +11:00
|
|
|
int index;
|
|
|
|
|
const bool all = RNA_boolean_get(op->ptr, "all");
|
2009-04-10 13:08:12 +00:00
|
|
|
|
2009-09-04 11:19:12 +00:00
|
|
|
/* try to create driver using property retrieved from UI */
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_context_active_but_prop_get(C, &ptr, &prop, &index);
|
2011-01-14 02:06:35 +00:00
|
|
|
|
2009-11-04 15:16:41 +00:00
|
|
|
if (all)
|
2012-05-08 15:30:00 +00:00
|
|
|
index = -1;
|
2011-01-14 02:06:35 +00:00
|
|
|
|
2010-09-23 20:26:03 +00:00
|
|
|
if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
|
2014-10-06 17:03:19 +02:00
|
|
|
char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
|
2010-12-28 05:45:15 +00:00
|
|
|
short flags = CREATEDRIVER_WITH_DEFAULT_DVAR;
|
2009-04-10 13:08:12 +00:00
|
|
|
|
2012-10-21 05:46:41 +00:00
|
|
|
if (path) {
|
2012-05-08 15:30:00 +00:00
|
|
|
success += ANIM_add_driver(op->reports, ptr.id.data, path, index, flags, DRIVER_TYPE_PYTHON);
|
2009-04-10 13:08:12 +00:00
|
|
|
|
|
|
|
|
MEM_freeN(path);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (success) {
|
|
|
|
|
/* send updates */
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_context_update_anim_flag(C);
|
2010-12-28 05:45:15 +00:00
|
|
|
|
2012-05-08 15:30:00 +00:00
|
|
|
WM_event_add_notifier(C, NC_ANIMATION | ND_FCURVES_ORDER, NULL); // XXX
|
2009-04-10 13:08:12 +00:00
|
|
|
}
|
|
|
|
|
|
2012-05-08 15:30:00 +00:00
|
|
|
return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
|
2009-04-10 13:08:12 +00:00
|
|
|
}
|
|
|
|
|
|
2012-04-29 17:11:40 +00:00
|
|
|
void ANIM_OT_driver_button_add(wmOperatorType *ot)
|
2009-04-10 13:08:12 +00:00
|
|
|
{
|
|
|
|
|
/* identifiers */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Add Driver";
|
|
|
|
|
ot->idname = "ANIM_OT_driver_button_add";
|
|
|
|
|
ot->description = "Add driver(s) for the property(s) connected represented by the highlighted button";
|
2009-04-10 13:08:12 +00:00
|
|
|
|
|
|
|
|
/* callbacks */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = add_driver_button_exec;
|
2012-05-27 19:40:36 +00:00
|
|
|
//op->poll = ??? // TODO: need to have some animatable property to do this
|
2009-04-10 13:08:12 +00:00
|
|
|
|
|
|
|
|
/* flags */
|
2014-02-26 18:54:40 +01:00
|
|
|
ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
|
2009-04-10 13:08:12 +00:00
|
|
|
|
|
|
|
|
/* properties */
|
2011-09-19 12:26:20 +00:00
|
|
|
RNA_def_boolean(ot->srna, "all", 1, "All", "Create drivers for all elements of the array");
|
2009-04-10 13:08:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Remove Driver Button Operator ------------------------ */
|
|
|
|
|
|
2012-05-08 15:30:00 +00:00
|
|
|
static int remove_driver_button_exec(bContext *C, wmOperator *op)
|
2009-04-10 13:08:12 +00:00
|
|
|
{
|
2012-05-08 15:30:00 +00:00
|
|
|
PointerRNA ptr = {{NULL}};
|
|
|
|
|
PropertyRNA *prop = NULL;
|
|
|
|
|
short success = 0;
|
2014-02-03 18:55:59 +11:00
|
|
|
int index;
|
|
|
|
|
const bool all = RNA_boolean_get(op->ptr, "all");
|
2009-04-10 13:08:12 +00:00
|
|
|
|
2009-09-04 11:19:12 +00:00
|
|
|
/* try to find driver using property retrieved from UI */
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_context_active_but_prop_get(C, &ptr, &prop, &index);
|
2010-04-11 09:13:37 +00:00
|
|
|
|
|
|
|
|
if (all)
|
2012-05-08 15:30:00 +00:00
|
|
|
index = -1;
|
2011-01-14 02:06:35 +00:00
|
|
|
|
2010-09-23 20:26:03 +00:00
|
|
|
if (ptr.id.data && ptr.data && prop) {
|
2014-10-06 17:03:19 +02:00
|
|
|
char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
|
2010-12-28 05:45:15 +00:00
|
|
|
|
2012-05-08 15:30:00 +00:00
|
|
|
success = ANIM_remove_driver(op->reports, ptr.id.data, path, index, 0);
|
2010-04-11 09:13:37 +00:00
|
|
|
MEM_freeN(path);
|
2009-04-10 13:08:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (success) {
|
|
|
|
|
/* send updates */
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_context_update_anim_flag(C);
|
2010-12-28 05:45:15 +00:00
|
|
|
|
2012-05-08 15:30:00 +00:00
|
|
|
WM_event_add_notifier(C, NC_ANIMATION | ND_FCURVES_ORDER, NULL); // XXX
|
2009-04-10 13:08:12 +00:00
|
|
|
}
|
|
|
|
|
|
2012-05-08 15:30:00 +00:00
|
|
|
return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
|
2009-04-10 13:08:12 +00:00
|
|
|
}
|
|
|
|
|
|
2012-04-29 17:11:40 +00:00
|
|
|
void ANIM_OT_driver_button_remove(wmOperatorType *ot)
|
2009-04-10 13:08:12 +00:00
|
|
|
{
|
|
|
|
|
/* identifiers */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Remove Driver";
|
|
|
|
|
ot->idname = "ANIM_OT_driver_button_remove";
|
|
|
|
|
ot->description = "Remove the driver(s) for the property(s) connected represented by the highlighted button";
|
2009-04-10 13:08:12 +00:00
|
|
|
|
|
|
|
|
/* callbacks */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = remove_driver_button_exec;
|
2012-05-27 19:40:36 +00:00
|
|
|
//op->poll = ??? // TODO: need to have some driver to be able to do this...
|
2009-04-10 13:08:12 +00:00
|
|
|
|
|
|
|
|
/* flags */
|
2014-02-26 18:54:40 +01:00
|
|
|
ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
|
2009-04-10 13:08:12 +00:00
|
|
|
|
|
|
|
|
/* properties */
|
2011-09-19 12:26:20 +00:00
|
|
|
RNA_def_boolean(ot->srna, "all", 1, "All", "Delete drivers for all elements of the array");
|
2009-04-10 13:08:12 +00:00
|
|
|
}
|
|
|
|
|
|
2009-09-25 04:51:04 +00:00
|
|
|
/* Copy Driver Button Operator ------------------------ */
|
|
|
|
|
|
2012-05-08 15:30:00 +00:00
|
|
|
static int copy_driver_button_exec(bContext *C, wmOperator *op)
|
2009-09-25 04:51:04 +00:00
|
|
|
{
|
2012-05-08 15:30:00 +00:00
|
|
|
PointerRNA ptr = {{NULL}};
|
|
|
|
|
PropertyRNA *prop = NULL;
|
|
|
|
|
short success = 0;
|
2009-09-25 04:51:04 +00:00
|
|
|
int index;
|
|
|
|
|
|
|
|
|
|
/* try to create driver using property retrieved from UI */
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_context_active_but_prop_get(C, &ptr, &prop, &index);
|
2009-09-25 04:51:04 +00:00
|
|
|
|
2010-09-23 20:26:03 +00:00
|
|
|
if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
|
2014-10-06 17:03:19 +02:00
|
|
|
char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
|
2009-09-25 04:51:04 +00:00
|
|
|
|
|
|
|
|
if (path) {
|
|
|
|
|
/* only copy the driver for the button that this was involved for */
|
2012-05-08 15:30:00 +00:00
|
|
|
success = ANIM_copy_driver(op->reports, ptr.id.data, path, index, 0);
|
2010-12-28 05:45:15 +00:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_context_update_anim_flag(C);
|
2009-09-25 04:51:04 +00:00
|
|
|
|
|
|
|
|
MEM_freeN(path);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* since we're just copying, we don't really need to do anything else...*/
|
2012-05-08 15:30:00 +00:00
|
|
|
return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
|
2009-09-25 04:51:04 +00:00
|
|
|
}
|
|
|
|
|
|
2012-04-29 17:11:40 +00:00
|
|
|
void ANIM_OT_copy_driver_button(wmOperatorType *ot)
|
2009-09-25 04:51:04 +00:00
|
|
|
{
|
|
|
|
|
/* identifiers */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Copy Driver";
|
|
|
|
|
ot->idname = "ANIM_OT_copy_driver_button";
|
|
|
|
|
ot->description = "Copy the driver for the highlighted button";
|
2009-09-25 04:51:04 +00:00
|
|
|
|
|
|
|
|
/* callbacks */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = copy_driver_button_exec;
|
2012-05-27 19:40:36 +00:00
|
|
|
//op->poll = ??? // TODO: need to have some driver to be able to do this...
|
2009-09-25 04:51:04 +00:00
|
|
|
|
|
|
|
|
/* flags */
|
2014-02-26 18:54:40 +01:00
|
|
|
ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
|
2009-09-25 04:51:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Paste Driver Button Operator ------------------------ */
|
|
|
|
|
|
2012-05-08 15:30:00 +00:00
|
|
|
static int paste_driver_button_exec(bContext *C, wmOperator *op)
|
2009-09-25 04:51:04 +00:00
|
|
|
{
|
2012-05-08 15:30:00 +00:00
|
|
|
PointerRNA ptr = {{NULL}};
|
|
|
|
|
PropertyRNA *prop = NULL;
|
|
|
|
|
short success = 0;
|
2009-09-25 04:51:04 +00:00
|
|
|
int index;
|
|
|
|
|
|
|
|
|
|
/* try to create driver using property retrieved from UI */
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_context_active_but_prop_get(C, &ptr, &prop, &index);
|
2009-09-25 04:51:04 +00:00
|
|
|
|
2010-09-23 20:26:03 +00:00
|
|
|
if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
|
2014-10-06 17:03:19 +02:00
|
|
|
char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
|
2009-09-25 04:51:04 +00:00
|
|
|
|
|
|
|
|
if (path) {
|
|
|
|
|
/* only copy the driver for the button that this was involved for */
|
2012-05-08 15:30:00 +00:00
|
|
|
success = ANIM_paste_driver(op->reports, ptr.id.data, path, index, 0);
|
2010-12-28 05:45:15 +00:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_context_update_anim_flag(C);
|
2009-09-25 04:51:04 +00:00
|
|
|
|
|
|
|
|
MEM_freeN(path);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* since we're just copying, we don't really need to do anything else...*/
|
2012-05-08 15:30:00 +00:00
|
|
|
return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
|
2009-09-25 04:51:04 +00:00
|
|
|
}
|
|
|
|
|
|
2012-04-29 17:11:40 +00:00
|
|
|
void ANIM_OT_paste_driver_button(wmOperatorType *ot)
|
2009-09-25 04:51:04 +00:00
|
|
|
{
|
|
|
|
|
/* identifiers */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Paste Driver";
|
|
|
|
|
ot->idname = "ANIM_OT_paste_driver_button";
|
|
|
|
|
ot->description = "Paste the driver in the copy/paste buffer for the highlighted button";
|
2009-09-25 04:51:04 +00:00
|
|
|
|
|
|
|
|
/* callbacks */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = paste_driver_button_exec;
|
2012-05-27 19:40:36 +00:00
|
|
|
//op->poll = ??? // TODO: need to have some driver to be able to do this...
|
2009-09-25 04:51:04 +00:00
|
|
|
|
|
|
|
|
/* flags */
|
2014-02-26 18:54:40 +01:00
|
|
|
ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
|
2009-09-25 04:51:04 +00:00
|
|
|
}
|
|
|
|
|
|
2009-04-10 13:08:12 +00:00
|
|
|
/* ************************************************** */
|