2011-02-23 10:52:22 +00:00
|
|
|
/*
|
2009-07-02 05:25:14 +00:00
|
|
|
* 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.
|
2009-04-10 13:08:12 +00:00
|
|
|
*/
|
2011-02-27 20:29:51 +00:00
|
|
|
|
2019-02-18 08:08:12 +11:00
|
|
|
/** \file
|
|
|
|
|
* \ingroup edanimation
|
2011-02-27 20:29:51 +00:00
|
|
|
*/
|
|
|
|
|
|
2018-06-04 09:31:30 +02: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"
|
Driver Setup Workflow Improvement: Property Eyedropper
This commit brings some long requested improvements to the workflow for setting up
drivers, which should make it easier and faster to set up new drivers in a more
interactive fashion.
The new workflow is as follows:
1) Hover over the property (e.g. "Lamp Energy" or "Y Location") or properties ("Rotation")
you wish to add drivers to. We'll refer to this as the "destination"
2) Ctrl-D to active the new "Add Drivers" eyedropper
3) Click on the property you want to use as the source/target. The property under the
mouse will be used to drive the property you invoked Ctrl-D on.
For example, to drive the X, Y, and Z location of the Cube using the Y Location of the Lamp,
hover over any of the X/Y/Z location buttons, hit Ctrl-D, then click on the Y-Location
button of the Lamp object. Drivers will be added to the X, Y, and Z Location properties
of the Cube; each driver will have a single variable, which uses the Y-Location Transform
Channel of the Lamp.
Tips:
- Transform properties will automatically create "Transform Channel" driver variables.
Everything else will use "Single Property" ones
- Due to the way that Blender's UI Context works, you'll need two Properties Panel instances
open (and to have pinned one of the two to show the properties for the unselected
object). It's slightly clunky, but necessary for implementing a workflow like this,
as the UI cannot be manipulated while using eyedroppers to pick data.
- The eyedropper operator implemented here actually has three modes of operation.
1) The "1-N" (one to many) mode is the default used for Ctrl-D, and "Add Driver to All"
in the RMB Menu. This is the behaviour described above.
2) There's also a "1-1" (one to one) mode that is used for the "Add Single Driver" in the
RMB Menu.
3) Finally, there's the "N-N" mode (many to many), which isn't currently exposed.
The point of this is to allow mapping XYZ to XYZ elementwise (i.e. direct copying)
which is useful for things like locations, rotations, scaling, and colours.
Implementation Notes:
- The bulk of the driver adding logic is in editors/animation/drivers.c, where most of
the Driver UI operators and tools are defined
- The property eyedropper code is in interface_eyedropper.c along with all the other
eyedroppers (even though they don't share much actual code in common). However, this
turns out to be necessary, as we can't get access to many of the low-level buttons API's
otherwise.
Todo:
- It may be necessary to restore a way to access the old behaviour (i.e. "manual setup")
in case it is not practical to immediately pick a property.
- Other things to investigate here include extra hotkeys (e.g. Ctrl-Shift-D for Add Single?),
and to expose the N-N mode.
- Other things we could try include interactively applying scaling factors, picking
multiple targets (e.g. for location difference and rotation difference drivers),
and/or other ways of using these property picking methods.
2016-03-26 17:55:42 +13:00
|
|
|
#include "BLI_string.h"
|
2009-04-10 13:08:12 +00:00
|
|
|
|
|
|
|
|
#include "DNA_anim_types.h"
|
2017-09-26 12:13:33 +10:00
|
|
|
#include "DNA_object_types.h"
|
2018-05-24 18:08:32 +02:00
|
|
|
#include "DNA_space_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"
|
|
|
|
|
|
2017-09-26 14:57:14 +10:00
|
|
|
#include "DEG_depsgraph.h"
|
2017-06-08 10:14:53 +02:00
|
|
|
#include "DEG_depsgraph_build.h"
|
|
|
|
|
|
2010-12-28 05:45:15 +00:00
|
|
|
#include "ED_keyframing.h"
|
2009-04-10 13:08:12 +00:00
|
|
|
|
|
|
|
|
#include "UI_interface.h"
|
2016-03-30 03:18:01 +13:00
|
|
|
#include "UI_resources.h"
|
2009-04-10 13:08:12 +00:00
|
|
|
|
|
|
|
|
#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"
|
|
|
|
|
|
2009-04-10 13:08:12 +00:00
|
|
|
/* ************************************************** */
|
|
|
|
|
/* Animation Data Validation */
|
|
|
|
|
|
2018-06-04 09:31:30 +02:00
|
|
|
/* Get (or add relevant data to be able to do so) F-Curve from the driver stack,
|
2009-04-10 13:08:12 +00:00
|
|
|
* for the given Animation Data block. This assumes that all the destinations are valid.
|
2018-06-01 18:19:39 +02:00
|
|
|
*
|
2018-11-14 12:53:15 +11:00
|
|
|
* - add: 0 - don't add anything if not found,
|
|
|
|
|
* 1 - add new Driver FCurve (with keyframes for visual tweaking),
|
|
|
|
|
* 2 - add new Driver FCurve (with generator, for script backwards compatibility)
|
|
|
|
|
* -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;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-04-10 13:08:12 +00:00
|
|
|
/* 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;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-04-10 13:08:12 +00:00
|
|
|
/* 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))
|
2015-04-04 15:13:56 +11:00
|
|
|
adt = BKE_animdata_add_id(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;
|
|
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
|
|
|
|
/* try to find f-curve matching for this setting
|
2018-11-14 12:53:15 +11:00
|
|
|
* - add if not found and allowed to add one
|
|
|
|
|
* TODO: add auto-grouping support? how this works will need to be resolved
|
2009-04-10 13:08:12 +00:00
|
|
|
*/
|
2012-05-08 15:30:00 +00:00
|
|
|
fcu = list_find_fcurve(&adt->drivers, rna_path, array_index);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
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");
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2012-05-08 15:30:00 +00:00
|
|
|
fcu->flag = (FCURVE_VISIBLE | FCURVE_SELECTED);
|
2017-11-01 21:34:30 +03:00
|
|
|
fcu->auto_smoothing = FCURVE_SMOOTH_CONT_ACCEL;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
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;
|
2018-06-04 09:31:30 +02: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;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
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");
|
2018-06-04 09:31:30 +02: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)
|
|
|
|
|
*/
|
2017-10-17 19:39:10 +03:00
|
|
|
add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_GENERATOR, fcu);
|
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
|
|
|
}
|
|
|
|
|
else {
|
2018-06-04 09:31:30 +02:00
|
|
|
/* add 2 keyframes so that user has something to work with
|
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
|
|
|
* - These are configured to 0,0 and 1,1 to give a 1-1 mapping
|
|
|
|
|
* which can be easily tweaked from there.
|
|
|
|
|
*/
|
2016-03-13 03:49:26 +13:00
|
|
|
insert_vert_fcurve(fcu, 0.0f, 0.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_FAST);
|
|
|
|
|
insert_vert_fcurve(fcu, 1.0f, 1.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_FAST);
|
2018-06-04 09:31:30 +02: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
|
|
|
/* configure this curve to extrapolate */
|
|
|
|
|
for (i = 0, bezt = fcu->bezt; (i < fcu->totvert) && bezt; i++, bezt++) {
|
|
|
|
|
bezt->h1 = bezt->h2 = HD_VECT;
|
|
|
|
|
}
|
2018-06-04 09:31:30 +02: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
|
|
|
fcu->extend = FCURVE_EXTRAPOLATE_LINEAR;
|
|
|
|
|
calchandles_fcurve(fcu);
|
|
|
|
|
}
|
2009-09-25 04:51:04 +00:00
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-04-10 13:08:12 +00:00
|
|
|
/* just add F-Curve to end of driver list */
|
|
|
|
|
BLI_addtail(&adt->drivers, fcu);
|
|
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-04-10 13:08:12 +00:00
|
|
|
/* return the F-Curve */
|
|
|
|
|
return fcu;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ************************************************** */
|
|
|
|
|
/* Driver Management API */
|
|
|
|
|
|
Driver Setup Workflow Improvement: Property Eyedropper
This commit brings some long requested improvements to the workflow for setting up
drivers, which should make it easier and faster to set up new drivers in a more
interactive fashion.
The new workflow is as follows:
1) Hover over the property (e.g. "Lamp Energy" or "Y Location") or properties ("Rotation")
you wish to add drivers to. We'll refer to this as the "destination"
2) Ctrl-D to active the new "Add Drivers" eyedropper
3) Click on the property you want to use as the source/target. The property under the
mouse will be used to drive the property you invoked Ctrl-D on.
For example, to drive the X, Y, and Z location of the Cube using the Y Location of the Lamp,
hover over any of the X/Y/Z location buttons, hit Ctrl-D, then click on the Y-Location
button of the Lamp object. Drivers will be added to the X, Y, and Z Location properties
of the Cube; each driver will have a single variable, which uses the Y-Location Transform
Channel of the Lamp.
Tips:
- Transform properties will automatically create "Transform Channel" driver variables.
Everything else will use "Single Property" ones
- Due to the way that Blender's UI Context works, you'll need two Properties Panel instances
open (and to have pinned one of the two to show the properties for the unselected
object). It's slightly clunky, but necessary for implementing a workflow like this,
as the UI cannot be manipulated while using eyedroppers to pick data.
- The eyedropper operator implemented here actually has three modes of operation.
1) The "1-N" (one to many) mode is the default used for Ctrl-D, and "Add Driver to All"
in the RMB Menu. This is the behaviour described above.
2) There's also a "1-1" (one to one) mode that is used for the "Add Single Driver" in the
RMB Menu.
3) Finally, there's the "N-N" mode (many to many), which isn't currently exposed.
The point of this is to allow mapping XYZ to XYZ elementwise (i.e. direct copying)
which is useful for things like locations, rotations, scaling, and colours.
Implementation Notes:
- The bulk of the driver adding logic is in editors/animation/drivers.c, where most of
the Driver UI operators and tools are defined
- The property eyedropper code is in interface_eyedropper.c along with all the other
eyedroppers (even though they don't share much actual code in common). However, this
turns out to be necessary, as we can't get access to many of the low-level buttons API's
otherwise.
Todo:
- It may be necessary to restore a way to access the old behaviour (i.e. "manual setup")
in case it is not practical to immediately pick a property.
- Other things to investigate here include extra hotkeys (e.g. Ctrl-Shift-D for Add Single?),
and to expose the N-N mode.
- Other things we could try include interactively applying scaling factors, picking
multiple targets (e.g. for location difference and rotation difference drivers),
and/or other ways of using these property picking methods.
2016-03-26 17:55:42 +13:00
|
|
|
/* Helper for ANIM_add_driver_with_target - Adds the actual driver */
|
|
|
|
|
static int add_driver_with_target(
|
2016-03-27 12:33:34 +02:00
|
|
|
ReportList *UNUSED(reports),
|
Driver Setup Workflow Improvement: Property Eyedropper
This commit brings some long requested improvements to the workflow for setting up
drivers, which should make it easier and faster to set up new drivers in a more
interactive fashion.
The new workflow is as follows:
1) Hover over the property (e.g. "Lamp Energy" or "Y Location") or properties ("Rotation")
you wish to add drivers to. We'll refer to this as the "destination"
2) Ctrl-D to active the new "Add Drivers" eyedropper
3) Click on the property you want to use as the source/target. The property under the
mouse will be used to drive the property you invoked Ctrl-D on.
For example, to drive the X, Y, and Z location of the Cube using the Y Location of the Lamp,
hover over any of the X/Y/Z location buttons, hit Ctrl-D, then click on the Y-Location
button of the Lamp object. Drivers will be added to the X, Y, and Z Location properties
of the Cube; each driver will have a single variable, which uses the Y-Location Transform
Channel of the Lamp.
Tips:
- Transform properties will automatically create "Transform Channel" driver variables.
Everything else will use "Single Property" ones
- Due to the way that Blender's UI Context works, you'll need two Properties Panel instances
open (and to have pinned one of the two to show the properties for the unselected
object). It's slightly clunky, but necessary for implementing a workflow like this,
as the UI cannot be manipulated while using eyedroppers to pick data.
- The eyedropper operator implemented here actually has three modes of operation.
1) The "1-N" (one to many) mode is the default used for Ctrl-D, and "Add Driver to All"
in the RMB Menu. This is the behaviour described above.
2) There's also a "1-1" (one to one) mode that is used for the "Add Single Driver" in the
RMB Menu.
3) Finally, there's the "N-N" mode (many to many), which isn't currently exposed.
The point of this is to allow mapping XYZ to XYZ elementwise (i.e. direct copying)
which is useful for things like locations, rotations, scaling, and colours.
Implementation Notes:
- The bulk of the driver adding logic is in editors/animation/drivers.c, where most of
the Driver UI operators and tools are defined
- The property eyedropper code is in interface_eyedropper.c along with all the other
eyedroppers (even though they don't share much actual code in common). However, this
turns out to be necessary, as we can't get access to many of the low-level buttons API's
otherwise.
Todo:
- It may be necessary to restore a way to access the old behaviour (i.e. "manual setup")
in case it is not practical to immediately pick a property.
- Other things to investigate here include extra hotkeys (e.g. Ctrl-Shift-D for Add Single?),
and to expose the N-N mode.
- Other things we could try include interactively applying scaling factors, picking
multiple targets (e.g. for location difference and rotation difference drivers),
and/or other ways of using these property picking methods.
2016-03-26 17:55:42 +13:00
|
|
|
ID *dst_id, const char dst_path[], int dst_index,
|
|
|
|
|
ID *src_id, const char src_path[], int src_index,
|
2016-06-27 19:01:25 +12:00
|
|
|
PointerRNA *dst_ptr, PropertyRNA *dst_prop,
|
Driver Setup Workflow Improvement: Property Eyedropper
This commit brings some long requested improvements to the workflow for setting up
drivers, which should make it easier and faster to set up new drivers in a more
interactive fashion.
The new workflow is as follows:
1) Hover over the property (e.g. "Lamp Energy" or "Y Location") or properties ("Rotation")
you wish to add drivers to. We'll refer to this as the "destination"
2) Ctrl-D to active the new "Add Drivers" eyedropper
3) Click on the property you want to use as the source/target. The property under the
mouse will be used to drive the property you invoked Ctrl-D on.
For example, to drive the X, Y, and Z location of the Cube using the Y Location of the Lamp,
hover over any of the X/Y/Z location buttons, hit Ctrl-D, then click on the Y-Location
button of the Lamp object. Drivers will be added to the X, Y, and Z Location properties
of the Cube; each driver will have a single variable, which uses the Y-Location Transform
Channel of the Lamp.
Tips:
- Transform properties will automatically create "Transform Channel" driver variables.
Everything else will use "Single Property" ones
- Due to the way that Blender's UI Context works, you'll need two Properties Panel instances
open (and to have pinned one of the two to show the properties for the unselected
object). It's slightly clunky, but necessary for implementing a workflow like this,
as the UI cannot be manipulated while using eyedroppers to pick data.
- The eyedropper operator implemented here actually has three modes of operation.
1) The "1-N" (one to many) mode is the default used for Ctrl-D, and "Add Driver to All"
in the RMB Menu. This is the behaviour described above.
2) There's also a "1-1" (one to one) mode that is used for the "Add Single Driver" in the
RMB Menu.
3) Finally, there's the "N-N" mode (many to many), which isn't currently exposed.
The point of this is to allow mapping XYZ to XYZ elementwise (i.e. direct copying)
which is useful for things like locations, rotations, scaling, and colours.
Implementation Notes:
- The bulk of the driver adding logic is in editors/animation/drivers.c, where most of
the Driver UI operators and tools are defined
- The property eyedropper code is in interface_eyedropper.c along with all the other
eyedroppers (even though they don't share much actual code in common). However, this
turns out to be necessary, as we can't get access to many of the low-level buttons API's
otherwise.
Todo:
- It may be necessary to restore a way to access the old behaviour (i.e. "manual setup")
in case it is not practical to immediately pick a property.
- Other things to investigate here include extra hotkeys (e.g. Ctrl-Shift-D for Add Single?),
and to expose the N-N mode.
- Other things we could try include interactively applying scaling factors, picking
multiple targets (e.g. for location difference and rotation difference drivers),
and/or other ways of using these property picking methods.
2016-03-26 17:55:42 +13:00
|
|
|
PointerRNA *src_ptr, PropertyRNA *src_prop,
|
|
|
|
|
short flag, int driver_type)
|
|
|
|
|
{
|
|
|
|
|
FCurve *fcu;
|
|
|
|
|
short add_mode = (flag & CREATEDRIVER_WITH_FMODIFIER) ? 2 : 1;
|
|
|
|
|
const char *prop_name = RNA_property_identifier(src_prop);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
Driver Setup Workflow Improvement: Property Eyedropper
This commit brings some long requested improvements to the workflow for setting up
drivers, which should make it easier and faster to set up new drivers in a more
interactive fashion.
The new workflow is as follows:
1) Hover over the property (e.g. "Lamp Energy" or "Y Location") or properties ("Rotation")
you wish to add drivers to. We'll refer to this as the "destination"
2) Ctrl-D to active the new "Add Drivers" eyedropper
3) Click on the property you want to use as the source/target. The property under the
mouse will be used to drive the property you invoked Ctrl-D on.
For example, to drive the X, Y, and Z location of the Cube using the Y Location of the Lamp,
hover over any of the X/Y/Z location buttons, hit Ctrl-D, then click on the Y-Location
button of the Lamp object. Drivers will be added to the X, Y, and Z Location properties
of the Cube; each driver will have a single variable, which uses the Y-Location Transform
Channel of the Lamp.
Tips:
- Transform properties will automatically create "Transform Channel" driver variables.
Everything else will use "Single Property" ones
- Due to the way that Blender's UI Context works, you'll need two Properties Panel instances
open (and to have pinned one of the two to show the properties for the unselected
object). It's slightly clunky, but necessary for implementing a workflow like this,
as the UI cannot be manipulated while using eyedroppers to pick data.
- The eyedropper operator implemented here actually has three modes of operation.
1) The "1-N" (one to many) mode is the default used for Ctrl-D, and "Add Driver to All"
in the RMB Menu. This is the behaviour described above.
2) There's also a "1-1" (one to one) mode that is used for the "Add Single Driver" in the
RMB Menu.
3) Finally, there's the "N-N" mode (many to many), which isn't currently exposed.
The point of this is to allow mapping XYZ to XYZ elementwise (i.e. direct copying)
which is useful for things like locations, rotations, scaling, and colours.
Implementation Notes:
- The bulk of the driver adding logic is in editors/animation/drivers.c, where most of
the Driver UI operators and tools are defined
- The property eyedropper code is in interface_eyedropper.c along with all the other
eyedroppers (even though they don't share much actual code in common). However, this
turns out to be necessary, as we can't get access to many of the low-level buttons API's
otherwise.
Todo:
- It may be necessary to restore a way to access the old behaviour (i.e. "manual setup")
in case it is not practical to immediately pick a property.
- Other things to investigate here include extra hotkeys (e.g. Ctrl-Shift-D for Add Single?),
and to expose the N-N mode.
- Other things we could try include interactively applying scaling factors, picking
multiple targets (e.g. for location difference and rotation difference drivers),
and/or other ways of using these property picking methods.
2016-03-26 17:55:42 +13:00
|
|
|
/* Create F-Curve with Driver */
|
|
|
|
|
fcu = verify_driver_fcurve(dst_id, dst_path, dst_index, add_mode);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
Driver Setup Workflow Improvement: Property Eyedropper
This commit brings some long requested improvements to the workflow for setting up
drivers, which should make it easier and faster to set up new drivers in a more
interactive fashion.
The new workflow is as follows:
1) Hover over the property (e.g. "Lamp Energy" or "Y Location") or properties ("Rotation")
you wish to add drivers to. We'll refer to this as the "destination"
2) Ctrl-D to active the new "Add Drivers" eyedropper
3) Click on the property you want to use as the source/target. The property under the
mouse will be used to drive the property you invoked Ctrl-D on.
For example, to drive the X, Y, and Z location of the Cube using the Y Location of the Lamp,
hover over any of the X/Y/Z location buttons, hit Ctrl-D, then click on the Y-Location
button of the Lamp object. Drivers will be added to the X, Y, and Z Location properties
of the Cube; each driver will have a single variable, which uses the Y-Location Transform
Channel of the Lamp.
Tips:
- Transform properties will automatically create "Transform Channel" driver variables.
Everything else will use "Single Property" ones
- Due to the way that Blender's UI Context works, you'll need two Properties Panel instances
open (and to have pinned one of the two to show the properties for the unselected
object). It's slightly clunky, but necessary for implementing a workflow like this,
as the UI cannot be manipulated while using eyedroppers to pick data.
- The eyedropper operator implemented here actually has three modes of operation.
1) The "1-N" (one to many) mode is the default used for Ctrl-D, and "Add Driver to All"
in the RMB Menu. This is the behaviour described above.
2) There's also a "1-1" (one to one) mode that is used for the "Add Single Driver" in the
RMB Menu.
3) Finally, there's the "N-N" mode (many to many), which isn't currently exposed.
The point of this is to allow mapping XYZ to XYZ elementwise (i.e. direct copying)
which is useful for things like locations, rotations, scaling, and colours.
Implementation Notes:
- The bulk of the driver adding logic is in editors/animation/drivers.c, where most of
the Driver UI operators and tools are defined
- The property eyedropper code is in interface_eyedropper.c along with all the other
eyedroppers (even though they don't share much actual code in common). However, this
turns out to be necessary, as we can't get access to many of the low-level buttons API's
otherwise.
Todo:
- It may be necessary to restore a way to access the old behaviour (i.e. "manual setup")
in case it is not practical to immediately pick a property.
- Other things to investigate here include extra hotkeys (e.g. Ctrl-Shift-D for Add Single?),
and to expose the N-N mode.
- Other things we could try include interactively applying scaling factors, picking
multiple targets (e.g. for location difference and rotation difference drivers),
and/or other ways of using these property picking methods.
2016-03-26 17:55:42 +13:00
|
|
|
if (fcu && fcu->driver) {
|
|
|
|
|
ChannelDriver *driver = fcu->driver;
|
|
|
|
|
DriverVar *dvar;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
Driver Setup Workflow Improvement: Property Eyedropper
This commit brings some long requested improvements to the workflow for setting up
drivers, which should make it easier and faster to set up new drivers in a more
interactive fashion.
The new workflow is as follows:
1) Hover over the property (e.g. "Lamp Energy" or "Y Location") or properties ("Rotation")
you wish to add drivers to. We'll refer to this as the "destination"
2) Ctrl-D to active the new "Add Drivers" eyedropper
3) Click on the property you want to use as the source/target. The property under the
mouse will be used to drive the property you invoked Ctrl-D on.
For example, to drive the X, Y, and Z location of the Cube using the Y Location of the Lamp,
hover over any of the X/Y/Z location buttons, hit Ctrl-D, then click on the Y-Location
button of the Lamp object. Drivers will be added to the X, Y, and Z Location properties
of the Cube; each driver will have a single variable, which uses the Y-Location Transform
Channel of the Lamp.
Tips:
- Transform properties will automatically create "Transform Channel" driver variables.
Everything else will use "Single Property" ones
- Due to the way that Blender's UI Context works, you'll need two Properties Panel instances
open (and to have pinned one of the two to show the properties for the unselected
object). It's slightly clunky, but necessary for implementing a workflow like this,
as the UI cannot be manipulated while using eyedroppers to pick data.
- The eyedropper operator implemented here actually has three modes of operation.
1) The "1-N" (one to many) mode is the default used for Ctrl-D, and "Add Driver to All"
in the RMB Menu. This is the behaviour described above.
2) There's also a "1-1" (one to one) mode that is used for the "Add Single Driver" in the
RMB Menu.
3) Finally, there's the "N-N" mode (many to many), which isn't currently exposed.
The point of this is to allow mapping XYZ to XYZ elementwise (i.e. direct copying)
which is useful for things like locations, rotations, scaling, and colours.
Implementation Notes:
- The bulk of the driver adding logic is in editors/animation/drivers.c, where most of
the Driver UI operators and tools are defined
- The property eyedropper code is in interface_eyedropper.c along with all the other
eyedroppers (even though they don't share much actual code in common). However, this
turns out to be necessary, as we can't get access to many of the low-level buttons API's
otherwise.
Todo:
- It may be necessary to restore a way to access the old behaviour (i.e. "manual setup")
in case it is not practical to immediately pick a property.
- Other things to investigate here include extra hotkeys (e.g. Ctrl-Shift-D for Add Single?),
and to expose the N-N mode.
- Other things we could try include interactively applying scaling factors, picking
multiple targets (e.g. for location difference and rotation difference drivers),
and/or other ways of using these property picking methods.
2016-03-26 17:55:42 +13:00
|
|
|
/* Set the type of the driver */
|
|
|
|
|
driver->type = driver_type;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2016-03-27 17:57:27 +13:00
|
|
|
/* Set driver expression, so that the driver works out of the box
|
|
|
|
|
*
|
|
|
|
|
* The following checks define a bit of "autodetection magic" we use
|
|
|
|
|
* to ensure that the drivers will behave as expected out of the box
|
|
|
|
|
* when faced with properties with different units.
|
|
|
|
|
*/
|
|
|
|
|
/* XXX: if we have N-1 mapping, should we include all those in the expression? */
|
2018-06-04 09:31:30 +02:00
|
|
|
if ((RNA_property_unit(dst_prop) == PROP_UNIT_ROTATION) &&
|
2016-03-27 17:57:27 +13:00
|
|
|
(RNA_property_unit(src_prop) != PROP_UNIT_ROTATION))
|
|
|
|
|
{
|
|
|
|
|
/* Rotation Destination: normal -> radians, so convert src to radians
|
|
|
|
|
* (However, if both input and output is a rotation, don't apply such corrections)
|
|
|
|
|
*/
|
|
|
|
|
BLI_strncpy(driver->expression, "radians(var)", sizeof(driver->expression));
|
|
|
|
|
}
|
|
|
|
|
else if ((RNA_property_unit(src_prop) == PROP_UNIT_ROTATION) &&
|
|
|
|
|
(RNA_property_unit(dst_prop) != PROP_UNIT_ROTATION))
|
|
|
|
|
{
|
|
|
|
|
/* Rotation Source: radians -> normal, so convert src to degrees
|
|
|
|
|
* (However, if both input and output is a rotation, don't apply such corrections)
|
|
|
|
|
*/
|
|
|
|
|
BLI_strncpy(driver->expression, "degrees(var)", sizeof(driver->expression));
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* Just a normal property without any unit problems */
|
|
|
|
|
BLI_strncpy(driver->expression, "var", sizeof(driver->expression));
|
|
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
Driver Setup Workflow Improvement: Property Eyedropper
This commit brings some long requested improvements to the workflow for setting up
drivers, which should make it easier and faster to set up new drivers in a more
interactive fashion.
The new workflow is as follows:
1) Hover over the property (e.g. "Lamp Energy" or "Y Location") or properties ("Rotation")
you wish to add drivers to. We'll refer to this as the "destination"
2) Ctrl-D to active the new "Add Drivers" eyedropper
3) Click on the property you want to use as the source/target. The property under the
mouse will be used to drive the property you invoked Ctrl-D on.
For example, to drive the X, Y, and Z location of the Cube using the Y Location of the Lamp,
hover over any of the X/Y/Z location buttons, hit Ctrl-D, then click on the Y-Location
button of the Lamp object. Drivers will be added to the X, Y, and Z Location properties
of the Cube; each driver will have a single variable, which uses the Y-Location Transform
Channel of the Lamp.
Tips:
- Transform properties will automatically create "Transform Channel" driver variables.
Everything else will use "Single Property" ones
- Due to the way that Blender's UI Context works, you'll need two Properties Panel instances
open (and to have pinned one of the two to show the properties for the unselected
object). It's slightly clunky, but necessary for implementing a workflow like this,
as the UI cannot be manipulated while using eyedroppers to pick data.
- The eyedropper operator implemented here actually has three modes of operation.
1) The "1-N" (one to many) mode is the default used for Ctrl-D, and "Add Driver to All"
in the RMB Menu. This is the behaviour described above.
2) There's also a "1-1" (one to one) mode that is used for the "Add Single Driver" in the
RMB Menu.
3) Finally, there's the "N-N" mode (many to many), which isn't currently exposed.
The point of this is to allow mapping XYZ to XYZ elementwise (i.e. direct copying)
which is useful for things like locations, rotations, scaling, and colours.
Implementation Notes:
- The bulk of the driver adding logic is in editors/animation/drivers.c, where most of
the Driver UI operators and tools are defined
- The property eyedropper code is in interface_eyedropper.c along with all the other
eyedroppers (even though they don't share much actual code in common). However, this
turns out to be necessary, as we can't get access to many of the low-level buttons API's
otherwise.
Todo:
- It may be necessary to restore a way to access the old behaviour (i.e. "manual setup")
in case it is not practical to immediately pick a property.
- Other things to investigate here include extra hotkeys (e.g. Ctrl-Shift-D for Add Single?),
and to expose the N-N mode.
- Other things we could try include interactively applying scaling factors, picking
multiple targets (e.g. for location difference and rotation difference drivers),
and/or other ways of using these property picking methods.
2016-03-26 17:55:42 +13:00
|
|
|
/* Create a driver variable for the target
|
|
|
|
|
* - For transform properties, we want to automatically use "transform channel" instead
|
|
|
|
|
* (The only issue is with quat rotations vs euler channels...)
|
2016-06-27 19:01:25 +12:00
|
|
|
* - To avoid problems with transform properties depending on the final transform that they
|
|
|
|
|
* control (thus creating pseudo-cycles - see T48734), we don't use transform channels
|
2016-06-29 20:37:54 +10:00
|
|
|
* when both the source and destinations are in same places.
|
Driver Setup Workflow Improvement: Property Eyedropper
This commit brings some long requested improvements to the workflow for setting up
drivers, which should make it easier and faster to set up new drivers in a more
interactive fashion.
The new workflow is as follows:
1) Hover over the property (e.g. "Lamp Energy" or "Y Location") or properties ("Rotation")
you wish to add drivers to. We'll refer to this as the "destination"
2) Ctrl-D to active the new "Add Drivers" eyedropper
3) Click on the property you want to use as the source/target. The property under the
mouse will be used to drive the property you invoked Ctrl-D on.
For example, to drive the X, Y, and Z location of the Cube using the Y Location of the Lamp,
hover over any of the X/Y/Z location buttons, hit Ctrl-D, then click on the Y-Location
button of the Lamp object. Drivers will be added to the X, Y, and Z Location properties
of the Cube; each driver will have a single variable, which uses the Y-Location Transform
Channel of the Lamp.
Tips:
- Transform properties will automatically create "Transform Channel" driver variables.
Everything else will use "Single Property" ones
- Due to the way that Blender's UI Context works, you'll need two Properties Panel instances
open (and to have pinned one of the two to show the properties for the unselected
object). It's slightly clunky, but necessary for implementing a workflow like this,
as the UI cannot be manipulated while using eyedroppers to pick data.
- The eyedropper operator implemented here actually has three modes of operation.
1) The "1-N" (one to many) mode is the default used for Ctrl-D, and "Add Driver to All"
in the RMB Menu. This is the behaviour described above.
2) There's also a "1-1" (one to one) mode that is used for the "Add Single Driver" in the
RMB Menu.
3) Finally, there's the "N-N" mode (many to many), which isn't currently exposed.
The point of this is to allow mapping XYZ to XYZ elementwise (i.e. direct copying)
which is useful for things like locations, rotations, scaling, and colours.
Implementation Notes:
- The bulk of the driver adding logic is in editors/animation/drivers.c, where most of
the Driver UI operators and tools are defined
- The property eyedropper code is in interface_eyedropper.c along with all the other
eyedroppers (even though they don't share much actual code in common). However, this
turns out to be necessary, as we can't get access to many of the low-level buttons API's
otherwise.
Todo:
- It may be necessary to restore a way to access the old behaviour (i.e. "manual setup")
in case it is not practical to immediately pick a property.
- Other things to investigate here include extra hotkeys (e.g. Ctrl-Shift-D for Add Single?),
and to expose the N-N mode.
- Other things we could try include interactively applying scaling factors, picking
multiple targets (e.g. for location difference and rotation difference drivers),
and/or other ways of using these property picking methods.
2016-03-26 17:55:42 +13:00
|
|
|
*/
|
|
|
|
|
dvar = driver_add_new_variable(driver);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
|
|
|
|
if (ELEM(src_ptr->type, &RNA_Object, &RNA_PoseBone) &&
|
2016-06-27 19:01:25 +12:00
|
|
|
(STREQ(prop_name, "location") || STREQ(prop_name, "scale") || STRPREFIX(prop_name, "rotation_")) &&
|
|
|
|
|
(src_ptr->data != dst_ptr->data))
|
Driver Setup Workflow Improvement: Property Eyedropper
This commit brings some long requested improvements to the workflow for setting up
drivers, which should make it easier and faster to set up new drivers in a more
interactive fashion.
The new workflow is as follows:
1) Hover over the property (e.g. "Lamp Energy" or "Y Location") or properties ("Rotation")
you wish to add drivers to. We'll refer to this as the "destination"
2) Ctrl-D to active the new "Add Drivers" eyedropper
3) Click on the property you want to use as the source/target. The property under the
mouse will be used to drive the property you invoked Ctrl-D on.
For example, to drive the X, Y, and Z location of the Cube using the Y Location of the Lamp,
hover over any of the X/Y/Z location buttons, hit Ctrl-D, then click on the Y-Location
button of the Lamp object. Drivers will be added to the X, Y, and Z Location properties
of the Cube; each driver will have a single variable, which uses the Y-Location Transform
Channel of the Lamp.
Tips:
- Transform properties will automatically create "Transform Channel" driver variables.
Everything else will use "Single Property" ones
- Due to the way that Blender's UI Context works, you'll need two Properties Panel instances
open (and to have pinned one of the two to show the properties for the unselected
object). It's slightly clunky, but necessary for implementing a workflow like this,
as the UI cannot be manipulated while using eyedroppers to pick data.
- The eyedropper operator implemented here actually has three modes of operation.
1) The "1-N" (one to many) mode is the default used for Ctrl-D, and "Add Driver to All"
in the RMB Menu. This is the behaviour described above.
2) There's also a "1-1" (one to one) mode that is used for the "Add Single Driver" in the
RMB Menu.
3) Finally, there's the "N-N" mode (many to many), which isn't currently exposed.
The point of this is to allow mapping XYZ to XYZ elementwise (i.e. direct copying)
which is useful for things like locations, rotations, scaling, and colours.
Implementation Notes:
- The bulk of the driver adding logic is in editors/animation/drivers.c, where most of
the Driver UI operators and tools are defined
- The property eyedropper code is in interface_eyedropper.c along with all the other
eyedroppers (even though they don't share much actual code in common). However, this
turns out to be necessary, as we can't get access to many of the low-level buttons API's
otherwise.
Todo:
- It may be necessary to restore a way to access the old behaviour (i.e. "manual setup")
in case it is not practical to immediately pick a property.
- Other things to investigate here include extra hotkeys (e.g. Ctrl-Shift-D for Add Single?),
and to expose the N-N mode.
- Other things we could try include interactively applying scaling factors, picking
multiple targets (e.g. for location difference and rotation difference drivers),
and/or other ways of using these property picking methods.
2016-03-26 17:55:42 +13:00
|
|
|
{
|
|
|
|
|
/* Transform Channel */
|
|
|
|
|
DriverTarget *dtar;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
Driver Setup Workflow Improvement: Property Eyedropper
This commit brings some long requested improvements to the workflow for setting up
drivers, which should make it easier and faster to set up new drivers in a more
interactive fashion.
The new workflow is as follows:
1) Hover over the property (e.g. "Lamp Energy" or "Y Location") or properties ("Rotation")
you wish to add drivers to. We'll refer to this as the "destination"
2) Ctrl-D to active the new "Add Drivers" eyedropper
3) Click on the property you want to use as the source/target. The property under the
mouse will be used to drive the property you invoked Ctrl-D on.
For example, to drive the X, Y, and Z location of the Cube using the Y Location of the Lamp,
hover over any of the X/Y/Z location buttons, hit Ctrl-D, then click on the Y-Location
button of the Lamp object. Drivers will be added to the X, Y, and Z Location properties
of the Cube; each driver will have a single variable, which uses the Y-Location Transform
Channel of the Lamp.
Tips:
- Transform properties will automatically create "Transform Channel" driver variables.
Everything else will use "Single Property" ones
- Due to the way that Blender's UI Context works, you'll need two Properties Panel instances
open (and to have pinned one of the two to show the properties for the unselected
object). It's slightly clunky, but necessary for implementing a workflow like this,
as the UI cannot be manipulated while using eyedroppers to pick data.
- The eyedropper operator implemented here actually has three modes of operation.
1) The "1-N" (one to many) mode is the default used for Ctrl-D, and "Add Driver to All"
in the RMB Menu. This is the behaviour described above.
2) There's also a "1-1" (one to one) mode that is used for the "Add Single Driver" in the
RMB Menu.
3) Finally, there's the "N-N" mode (many to many), which isn't currently exposed.
The point of this is to allow mapping XYZ to XYZ elementwise (i.e. direct copying)
which is useful for things like locations, rotations, scaling, and colours.
Implementation Notes:
- The bulk of the driver adding logic is in editors/animation/drivers.c, where most of
the Driver UI operators and tools are defined
- The property eyedropper code is in interface_eyedropper.c along with all the other
eyedroppers (even though they don't share much actual code in common). However, this
turns out to be necessary, as we can't get access to many of the low-level buttons API's
otherwise.
Todo:
- It may be necessary to restore a way to access the old behaviour (i.e. "manual setup")
in case it is not practical to immediately pick a property.
- Other things to investigate here include extra hotkeys (e.g. Ctrl-Shift-D for Add Single?),
and to expose the N-N mode.
- Other things we could try include interactively applying scaling factors, picking
multiple targets (e.g. for location difference and rotation difference drivers),
and/or other ways of using these property picking methods.
2016-03-26 17:55:42 +13:00
|
|
|
driver_change_variable_type(dvar, DVAR_TYPE_TRANSFORM_CHAN);
|
|
|
|
|
dtar = &dvar->targets[0];
|
2018-06-04 09:31:30 +02:00
|
|
|
|
Driver Setup Workflow Improvement: Property Eyedropper
This commit brings some long requested improvements to the workflow for setting up
drivers, which should make it easier and faster to set up new drivers in a more
interactive fashion.
The new workflow is as follows:
1) Hover over the property (e.g. "Lamp Energy" or "Y Location") or properties ("Rotation")
you wish to add drivers to. We'll refer to this as the "destination"
2) Ctrl-D to active the new "Add Drivers" eyedropper
3) Click on the property you want to use as the source/target. The property under the
mouse will be used to drive the property you invoked Ctrl-D on.
For example, to drive the X, Y, and Z location of the Cube using the Y Location of the Lamp,
hover over any of the X/Y/Z location buttons, hit Ctrl-D, then click on the Y-Location
button of the Lamp object. Drivers will be added to the X, Y, and Z Location properties
of the Cube; each driver will have a single variable, which uses the Y-Location Transform
Channel of the Lamp.
Tips:
- Transform properties will automatically create "Transform Channel" driver variables.
Everything else will use "Single Property" ones
- Due to the way that Blender's UI Context works, you'll need two Properties Panel instances
open (and to have pinned one of the two to show the properties for the unselected
object). It's slightly clunky, but necessary for implementing a workflow like this,
as the UI cannot be manipulated while using eyedroppers to pick data.
- The eyedropper operator implemented here actually has three modes of operation.
1) The "1-N" (one to many) mode is the default used for Ctrl-D, and "Add Driver to All"
in the RMB Menu. This is the behaviour described above.
2) There's also a "1-1" (one to one) mode that is used for the "Add Single Driver" in the
RMB Menu.
3) Finally, there's the "N-N" mode (many to many), which isn't currently exposed.
The point of this is to allow mapping XYZ to XYZ elementwise (i.e. direct copying)
which is useful for things like locations, rotations, scaling, and colours.
Implementation Notes:
- The bulk of the driver adding logic is in editors/animation/drivers.c, where most of
the Driver UI operators and tools are defined
- The property eyedropper code is in interface_eyedropper.c along with all the other
eyedroppers (even though they don't share much actual code in common). However, this
turns out to be necessary, as we can't get access to many of the low-level buttons API's
otherwise.
Todo:
- It may be necessary to restore a way to access the old behaviour (i.e. "manual setup")
in case it is not practical to immediately pick a property.
- Other things to investigate here include extra hotkeys (e.g. Ctrl-Shift-D for Add Single?),
and to expose the N-N mode.
- Other things we could try include interactively applying scaling factors, picking
multiple targets (e.g. for location difference and rotation difference drivers),
and/or other ways of using these property picking methods.
2016-03-26 17:55:42 +13:00
|
|
|
/* Bone or Object target? */
|
|
|
|
|
dtar->id = src_id;
|
|
|
|
|
dtar->idtype = GS(src_id->name);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
Driver Setup Workflow Improvement: Property Eyedropper
This commit brings some long requested improvements to the workflow for setting up
drivers, which should make it easier and faster to set up new drivers in a more
interactive fashion.
The new workflow is as follows:
1) Hover over the property (e.g. "Lamp Energy" or "Y Location") or properties ("Rotation")
you wish to add drivers to. We'll refer to this as the "destination"
2) Ctrl-D to active the new "Add Drivers" eyedropper
3) Click on the property you want to use as the source/target. The property under the
mouse will be used to drive the property you invoked Ctrl-D on.
For example, to drive the X, Y, and Z location of the Cube using the Y Location of the Lamp,
hover over any of the X/Y/Z location buttons, hit Ctrl-D, then click on the Y-Location
button of the Lamp object. Drivers will be added to the X, Y, and Z Location properties
of the Cube; each driver will have a single variable, which uses the Y-Location Transform
Channel of the Lamp.
Tips:
- Transform properties will automatically create "Transform Channel" driver variables.
Everything else will use "Single Property" ones
- Due to the way that Blender's UI Context works, you'll need two Properties Panel instances
open (and to have pinned one of the two to show the properties for the unselected
object). It's slightly clunky, but necessary for implementing a workflow like this,
as the UI cannot be manipulated while using eyedroppers to pick data.
- The eyedropper operator implemented here actually has three modes of operation.
1) The "1-N" (one to many) mode is the default used for Ctrl-D, and "Add Driver to All"
in the RMB Menu. This is the behaviour described above.
2) There's also a "1-1" (one to one) mode that is used for the "Add Single Driver" in the
RMB Menu.
3) Finally, there's the "N-N" mode (many to many), which isn't currently exposed.
The point of this is to allow mapping XYZ to XYZ elementwise (i.e. direct copying)
which is useful for things like locations, rotations, scaling, and colours.
Implementation Notes:
- The bulk of the driver adding logic is in editors/animation/drivers.c, where most of
the Driver UI operators and tools are defined
- The property eyedropper code is in interface_eyedropper.c along with all the other
eyedroppers (even though they don't share much actual code in common). However, this
turns out to be necessary, as we can't get access to many of the low-level buttons API's
otherwise.
Todo:
- It may be necessary to restore a way to access the old behaviour (i.e. "manual setup")
in case it is not practical to immediately pick a property.
- Other things to investigate here include extra hotkeys (e.g. Ctrl-Shift-D for Add Single?),
and to expose the N-N mode.
- Other things we could try include interactively applying scaling factors, picking
multiple targets (e.g. for location difference and rotation difference drivers),
and/or other ways of using these property picking methods.
2016-03-26 17:55:42 +13:00
|
|
|
if (src_ptr->type == &RNA_PoseBone) {
|
|
|
|
|
RNA_string_get(src_ptr, "name", dtar->pchan_name);
|
|
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
Driver Setup Workflow Improvement: Property Eyedropper
This commit brings some long requested improvements to the workflow for setting up
drivers, which should make it easier and faster to set up new drivers in a more
interactive fashion.
The new workflow is as follows:
1) Hover over the property (e.g. "Lamp Energy" or "Y Location") or properties ("Rotation")
you wish to add drivers to. We'll refer to this as the "destination"
2) Ctrl-D to active the new "Add Drivers" eyedropper
3) Click on the property you want to use as the source/target. The property under the
mouse will be used to drive the property you invoked Ctrl-D on.
For example, to drive the X, Y, and Z location of the Cube using the Y Location of the Lamp,
hover over any of the X/Y/Z location buttons, hit Ctrl-D, then click on the Y-Location
button of the Lamp object. Drivers will be added to the X, Y, and Z Location properties
of the Cube; each driver will have a single variable, which uses the Y-Location Transform
Channel of the Lamp.
Tips:
- Transform properties will automatically create "Transform Channel" driver variables.
Everything else will use "Single Property" ones
- Due to the way that Blender's UI Context works, you'll need two Properties Panel instances
open (and to have pinned one of the two to show the properties for the unselected
object). It's slightly clunky, but necessary for implementing a workflow like this,
as the UI cannot be manipulated while using eyedroppers to pick data.
- The eyedropper operator implemented here actually has three modes of operation.
1) The "1-N" (one to many) mode is the default used for Ctrl-D, and "Add Driver to All"
in the RMB Menu. This is the behaviour described above.
2) There's also a "1-1" (one to one) mode that is used for the "Add Single Driver" in the
RMB Menu.
3) Finally, there's the "N-N" mode (many to many), which isn't currently exposed.
The point of this is to allow mapping XYZ to XYZ elementwise (i.e. direct copying)
which is useful for things like locations, rotations, scaling, and colours.
Implementation Notes:
- The bulk of the driver adding logic is in editors/animation/drivers.c, where most of
the Driver UI operators and tools are defined
- The property eyedropper code is in interface_eyedropper.c along with all the other
eyedroppers (even though they don't share much actual code in common). However, this
turns out to be necessary, as we can't get access to many of the low-level buttons API's
otherwise.
Todo:
- It may be necessary to restore a way to access the old behaviour (i.e. "manual setup")
in case it is not practical to immediately pick a property.
- Other things to investigate here include extra hotkeys (e.g. Ctrl-Shift-D for Add Single?),
and to expose the N-N mode.
- Other things we could try include interactively applying scaling factors, picking
multiple targets (e.g. for location difference and rotation difference drivers),
and/or other ways of using these property picking methods.
2016-03-26 17:55:42 +13:00
|
|
|
/* Transform channel depends on type */
|
|
|
|
|
if (STREQ(prop_name, "location")) {
|
|
|
|
|
if (src_index == 2)
|
|
|
|
|
dtar->transChan = DTAR_TRANSCHAN_LOCZ;
|
|
|
|
|
else if (src_index == 1)
|
|
|
|
|
dtar->transChan = DTAR_TRANSCHAN_LOCY;
|
|
|
|
|
else
|
|
|
|
|
dtar->transChan = DTAR_TRANSCHAN_LOCX;
|
|
|
|
|
}
|
|
|
|
|
else if (STREQ(prop_name, "scale")) {
|
|
|
|
|
if (src_index == 2)
|
|
|
|
|
dtar->transChan = DTAR_TRANSCHAN_SCALEZ;
|
|
|
|
|
else if (src_index == 1)
|
|
|
|
|
dtar->transChan = DTAR_TRANSCHAN_SCALEY;
|
|
|
|
|
else
|
|
|
|
|
dtar->transChan = DTAR_TRANSCHAN_SCALEX;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* XXX: With quaternions and axis-angle, this mapping might not be correct...
|
|
|
|
|
* But since those have 4 elements instead, there's not much we can do
|
|
|
|
|
*/
|
|
|
|
|
if (src_index == 2)
|
|
|
|
|
dtar->transChan = DTAR_TRANSCHAN_ROTZ;
|
|
|
|
|
else if (src_index == 1)
|
|
|
|
|
dtar->transChan = DTAR_TRANSCHAN_ROTY;
|
|
|
|
|
else
|
|
|
|
|
dtar->transChan = DTAR_TRANSCHAN_ROTX;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* Single RNA Property */
|
|
|
|
|
DriverTarget *dtar = &dvar->targets[0];
|
2018-06-04 09:31:30 +02:00
|
|
|
|
Driver Setup Workflow Improvement: Property Eyedropper
This commit brings some long requested improvements to the workflow for setting up
drivers, which should make it easier and faster to set up new drivers in a more
interactive fashion.
The new workflow is as follows:
1) Hover over the property (e.g. "Lamp Energy" or "Y Location") or properties ("Rotation")
you wish to add drivers to. We'll refer to this as the "destination"
2) Ctrl-D to active the new "Add Drivers" eyedropper
3) Click on the property you want to use as the source/target. The property under the
mouse will be used to drive the property you invoked Ctrl-D on.
For example, to drive the X, Y, and Z location of the Cube using the Y Location of the Lamp,
hover over any of the X/Y/Z location buttons, hit Ctrl-D, then click on the Y-Location
button of the Lamp object. Drivers will be added to the X, Y, and Z Location properties
of the Cube; each driver will have a single variable, which uses the Y-Location Transform
Channel of the Lamp.
Tips:
- Transform properties will automatically create "Transform Channel" driver variables.
Everything else will use "Single Property" ones
- Due to the way that Blender's UI Context works, you'll need two Properties Panel instances
open (and to have pinned one of the two to show the properties for the unselected
object). It's slightly clunky, but necessary for implementing a workflow like this,
as the UI cannot be manipulated while using eyedroppers to pick data.
- The eyedropper operator implemented here actually has three modes of operation.
1) The "1-N" (one to many) mode is the default used for Ctrl-D, and "Add Driver to All"
in the RMB Menu. This is the behaviour described above.
2) There's also a "1-1" (one to one) mode that is used for the "Add Single Driver" in the
RMB Menu.
3) Finally, there's the "N-N" mode (many to many), which isn't currently exposed.
The point of this is to allow mapping XYZ to XYZ elementwise (i.e. direct copying)
which is useful for things like locations, rotations, scaling, and colours.
Implementation Notes:
- The bulk of the driver adding logic is in editors/animation/drivers.c, where most of
the Driver UI operators and tools are defined
- The property eyedropper code is in interface_eyedropper.c along with all the other
eyedroppers (even though they don't share much actual code in common). However, this
turns out to be necessary, as we can't get access to many of the low-level buttons API's
otherwise.
Todo:
- It may be necessary to restore a way to access the old behaviour (i.e. "manual setup")
in case it is not practical to immediately pick a property.
- Other things to investigate here include extra hotkeys (e.g. Ctrl-Shift-D for Add Single?),
and to expose the N-N mode.
- Other things we could try include interactively applying scaling factors, picking
multiple targets (e.g. for location difference and rotation difference drivers),
and/or other ways of using these property picking methods.
2016-03-26 17:55:42 +13:00
|
|
|
/* ID is as-is */
|
|
|
|
|
dtar->id = src_id;
|
|
|
|
|
dtar->idtype = GS(src_id->name);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
Driver Setup Workflow Improvement: Property Eyedropper
This commit brings some long requested improvements to the workflow for setting up
drivers, which should make it easier and faster to set up new drivers in a more
interactive fashion.
The new workflow is as follows:
1) Hover over the property (e.g. "Lamp Energy" or "Y Location") or properties ("Rotation")
you wish to add drivers to. We'll refer to this as the "destination"
2) Ctrl-D to active the new "Add Drivers" eyedropper
3) Click on the property you want to use as the source/target. The property under the
mouse will be used to drive the property you invoked Ctrl-D on.
For example, to drive the X, Y, and Z location of the Cube using the Y Location of the Lamp,
hover over any of the X/Y/Z location buttons, hit Ctrl-D, then click on the Y-Location
button of the Lamp object. Drivers will be added to the X, Y, and Z Location properties
of the Cube; each driver will have a single variable, which uses the Y-Location Transform
Channel of the Lamp.
Tips:
- Transform properties will automatically create "Transform Channel" driver variables.
Everything else will use "Single Property" ones
- Due to the way that Blender's UI Context works, you'll need two Properties Panel instances
open (and to have pinned one of the two to show the properties for the unselected
object). It's slightly clunky, but necessary for implementing a workflow like this,
as the UI cannot be manipulated while using eyedroppers to pick data.
- The eyedropper operator implemented here actually has three modes of operation.
1) The "1-N" (one to many) mode is the default used for Ctrl-D, and "Add Driver to All"
in the RMB Menu. This is the behaviour described above.
2) There's also a "1-1" (one to one) mode that is used for the "Add Single Driver" in the
RMB Menu.
3) Finally, there's the "N-N" mode (many to many), which isn't currently exposed.
The point of this is to allow mapping XYZ to XYZ elementwise (i.e. direct copying)
which is useful for things like locations, rotations, scaling, and colours.
Implementation Notes:
- The bulk of the driver adding logic is in editors/animation/drivers.c, where most of
the Driver UI operators and tools are defined
- The property eyedropper code is in interface_eyedropper.c along with all the other
eyedroppers (even though they don't share much actual code in common). However, this
turns out to be necessary, as we can't get access to many of the low-level buttons API's
otherwise.
Todo:
- It may be necessary to restore a way to access the old behaviour (i.e. "manual setup")
in case it is not practical to immediately pick a property.
- Other things to investigate here include extra hotkeys (e.g. Ctrl-Shift-D for Add Single?),
and to expose the N-N mode.
- Other things we could try include interactively applying scaling factors, picking
multiple targets (e.g. for location difference and rotation difference drivers),
and/or other ways of using these property picking methods.
2016-03-26 17:55:42 +13:00
|
|
|
/* Need to make a copy of the path (or build one with array index built in) */
|
|
|
|
|
if (RNA_property_array_check(src_prop)) {
|
|
|
|
|
dtar->rna_path = BLI_sprintfN("%s[%d]", src_path, src_index);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
dtar->rna_path = BLI_strdup(src_path);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
Driver Setup Workflow Improvement: Property Eyedropper
This commit brings some long requested improvements to the workflow for setting up
drivers, which should make it easier and faster to set up new drivers in a more
interactive fashion.
The new workflow is as follows:
1) Hover over the property (e.g. "Lamp Energy" or "Y Location") or properties ("Rotation")
you wish to add drivers to. We'll refer to this as the "destination"
2) Ctrl-D to active the new "Add Drivers" eyedropper
3) Click on the property you want to use as the source/target. The property under the
mouse will be used to drive the property you invoked Ctrl-D on.
For example, to drive the X, Y, and Z location of the Cube using the Y Location of the Lamp,
hover over any of the X/Y/Z location buttons, hit Ctrl-D, then click on the Y-Location
button of the Lamp object. Drivers will be added to the X, Y, and Z Location properties
of the Cube; each driver will have a single variable, which uses the Y-Location Transform
Channel of the Lamp.
Tips:
- Transform properties will automatically create "Transform Channel" driver variables.
Everything else will use "Single Property" ones
- Due to the way that Blender's UI Context works, you'll need two Properties Panel instances
open (and to have pinned one of the two to show the properties for the unselected
object). It's slightly clunky, but necessary for implementing a workflow like this,
as the UI cannot be manipulated while using eyedroppers to pick data.
- The eyedropper operator implemented here actually has three modes of operation.
1) The "1-N" (one to many) mode is the default used for Ctrl-D, and "Add Driver to All"
in the RMB Menu. This is the behaviour described above.
2) There's also a "1-1" (one to one) mode that is used for the "Add Single Driver" in the
RMB Menu.
3) Finally, there's the "N-N" mode (many to many), which isn't currently exposed.
The point of this is to allow mapping XYZ to XYZ elementwise (i.e. direct copying)
which is useful for things like locations, rotations, scaling, and colours.
Implementation Notes:
- The bulk of the driver adding logic is in editors/animation/drivers.c, where most of
the Driver UI operators and tools are defined
- The property eyedropper code is in interface_eyedropper.c along with all the other
eyedroppers (even though they don't share much actual code in common). However, this
turns out to be necessary, as we can't get access to many of the low-level buttons API's
otherwise.
Todo:
- It may be necessary to restore a way to access the old behaviour (i.e. "manual setup")
in case it is not practical to immediately pick a property.
- Other things to investigate here include extra hotkeys (e.g. Ctrl-Shift-D for Add Single?),
and to expose the N-N mode.
- Other things we could try include interactively applying scaling factors, picking
multiple targets (e.g. for location difference and rotation difference drivers),
and/or other ways of using these property picking methods.
2016-03-26 17:55:42 +13:00
|
|
|
/* set the done status */
|
|
|
|
|
return (fcu != NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Main Driver Management API calls:
|
2018-09-02 18:28:27 +10:00
|
|
|
* Add a new driver for the specified property on the given ID block,
|
|
|
|
|
* and make it be driven by the specified target.
|
Driver Setup Workflow Improvement: Property Eyedropper
This commit brings some long requested improvements to the workflow for setting up
drivers, which should make it easier and faster to set up new drivers in a more
interactive fashion.
The new workflow is as follows:
1) Hover over the property (e.g. "Lamp Energy" or "Y Location") or properties ("Rotation")
you wish to add drivers to. We'll refer to this as the "destination"
2) Ctrl-D to active the new "Add Drivers" eyedropper
3) Click on the property you want to use as the source/target. The property under the
mouse will be used to drive the property you invoked Ctrl-D on.
For example, to drive the X, Y, and Z location of the Cube using the Y Location of the Lamp,
hover over any of the X/Y/Z location buttons, hit Ctrl-D, then click on the Y-Location
button of the Lamp object. Drivers will be added to the X, Y, and Z Location properties
of the Cube; each driver will have a single variable, which uses the Y-Location Transform
Channel of the Lamp.
Tips:
- Transform properties will automatically create "Transform Channel" driver variables.
Everything else will use "Single Property" ones
- Due to the way that Blender's UI Context works, you'll need two Properties Panel instances
open (and to have pinned one of the two to show the properties for the unselected
object). It's slightly clunky, but necessary for implementing a workflow like this,
as the UI cannot be manipulated while using eyedroppers to pick data.
- The eyedropper operator implemented here actually has three modes of operation.
1) The "1-N" (one to many) mode is the default used for Ctrl-D, and "Add Driver to All"
in the RMB Menu. This is the behaviour described above.
2) There's also a "1-1" (one to one) mode that is used for the "Add Single Driver" in the
RMB Menu.
3) Finally, there's the "N-N" mode (many to many), which isn't currently exposed.
The point of this is to allow mapping XYZ to XYZ elementwise (i.e. direct copying)
which is useful for things like locations, rotations, scaling, and colours.
Implementation Notes:
- The bulk of the driver adding logic is in editors/animation/drivers.c, where most of
the Driver UI operators and tools are defined
- The property eyedropper code is in interface_eyedropper.c along with all the other
eyedroppers (even though they don't share much actual code in common). However, this
turns out to be necessary, as we can't get access to many of the low-level buttons API's
otherwise.
Todo:
- It may be necessary to restore a way to access the old behaviour (i.e. "manual setup")
in case it is not practical to immediately pick a property.
- Other things to investigate here include extra hotkeys (e.g. Ctrl-Shift-D for Add Single?),
and to expose the N-N mode.
- Other things we could try include interactively applying scaling factors, picking
multiple targets (e.g. for location difference and rotation difference drivers),
and/or other ways of using these property picking methods.
2016-03-26 17:55:42 +13:00
|
|
|
*
|
|
|
|
|
* This is intended to be used in conjunction with a modal "eyedropper"
|
|
|
|
|
* for picking the variable that is going to be used to drive this one.
|
|
|
|
|
*
|
|
|
|
|
* - flag: eCreateDriverFlags
|
|
|
|
|
* - driver_type: eDriver_Types
|
|
|
|
|
* - mapping_type: eCreateDriver_MappingTypes
|
|
|
|
|
*/
|
|
|
|
|
int ANIM_add_driver_with_target(
|
2018-06-04 09:31:30 +02:00
|
|
|
ReportList *reports,
|
Driver Setup Workflow Improvement: Property Eyedropper
This commit brings some long requested improvements to the workflow for setting up
drivers, which should make it easier and faster to set up new drivers in a more
interactive fashion.
The new workflow is as follows:
1) Hover over the property (e.g. "Lamp Energy" or "Y Location") or properties ("Rotation")
you wish to add drivers to. We'll refer to this as the "destination"
2) Ctrl-D to active the new "Add Drivers" eyedropper
3) Click on the property you want to use as the source/target. The property under the
mouse will be used to drive the property you invoked Ctrl-D on.
For example, to drive the X, Y, and Z location of the Cube using the Y Location of the Lamp,
hover over any of the X/Y/Z location buttons, hit Ctrl-D, then click on the Y-Location
button of the Lamp object. Drivers will be added to the X, Y, and Z Location properties
of the Cube; each driver will have a single variable, which uses the Y-Location Transform
Channel of the Lamp.
Tips:
- Transform properties will automatically create "Transform Channel" driver variables.
Everything else will use "Single Property" ones
- Due to the way that Blender's UI Context works, you'll need two Properties Panel instances
open (and to have pinned one of the two to show the properties for the unselected
object). It's slightly clunky, but necessary for implementing a workflow like this,
as the UI cannot be manipulated while using eyedroppers to pick data.
- The eyedropper operator implemented here actually has three modes of operation.
1) The "1-N" (one to many) mode is the default used for Ctrl-D, and "Add Driver to All"
in the RMB Menu. This is the behaviour described above.
2) There's also a "1-1" (one to one) mode that is used for the "Add Single Driver" in the
RMB Menu.
3) Finally, there's the "N-N" mode (many to many), which isn't currently exposed.
The point of this is to allow mapping XYZ to XYZ elementwise (i.e. direct copying)
which is useful for things like locations, rotations, scaling, and colours.
Implementation Notes:
- The bulk of the driver adding logic is in editors/animation/drivers.c, where most of
the Driver UI operators and tools are defined
- The property eyedropper code is in interface_eyedropper.c along with all the other
eyedroppers (even though they don't share much actual code in common). However, this
turns out to be necessary, as we can't get access to many of the low-level buttons API's
otherwise.
Todo:
- It may be necessary to restore a way to access the old behaviour (i.e. "manual setup")
in case it is not practical to immediately pick a property.
- Other things to investigate here include extra hotkeys (e.g. Ctrl-Shift-D for Add Single?),
and to expose the N-N mode.
- Other things we could try include interactively applying scaling factors, picking
multiple targets (e.g. for location difference and rotation difference drivers),
and/or other ways of using these property picking methods.
2016-03-26 17:55:42 +13:00
|
|
|
ID *dst_id, const char dst_path[], int dst_index,
|
|
|
|
|
ID *src_id, const char src_path[], int src_index,
|
|
|
|
|
short flag, int driver_type, short mapping_type)
|
|
|
|
|
{
|
|
|
|
|
PointerRNA id_ptr, ptr;
|
|
|
|
|
PropertyRNA *prop;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
Driver Setup Workflow Improvement: Property Eyedropper
This commit brings some long requested improvements to the workflow for setting up
drivers, which should make it easier and faster to set up new drivers in a more
interactive fashion.
The new workflow is as follows:
1) Hover over the property (e.g. "Lamp Energy" or "Y Location") or properties ("Rotation")
you wish to add drivers to. We'll refer to this as the "destination"
2) Ctrl-D to active the new "Add Drivers" eyedropper
3) Click on the property you want to use as the source/target. The property under the
mouse will be used to drive the property you invoked Ctrl-D on.
For example, to drive the X, Y, and Z location of the Cube using the Y Location of the Lamp,
hover over any of the X/Y/Z location buttons, hit Ctrl-D, then click on the Y-Location
button of the Lamp object. Drivers will be added to the X, Y, and Z Location properties
of the Cube; each driver will have a single variable, which uses the Y-Location Transform
Channel of the Lamp.
Tips:
- Transform properties will automatically create "Transform Channel" driver variables.
Everything else will use "Single Property" ones
- Due to the way that Blender's UI Context works, you'll need two Properties Panel instances
open (and to have pinned one of the two to show the properties for the unselected
object). It's slightly clunky, but necessary for implementing a workflow like this,
as the UI cannot be manipulated while using eyedroppers to pick data.
- The eyedropper operator implemented here actually has three modes of operation.
1) The "1-N" (one to many) mode is the default used for Ctrl-D, and "Add Driver to All"
in the RMB Menu. This is the behaviour described above.
2) There's also a "1-1" (one to one) mode that is used for the "Add Single Driver" in the
RMB Menu.
3) Finally, there's the "N-N" mode (many to many), which isn't currently exposed.
The point of this is to allow mapping XYZ to XYZ elementwise (i.e. direct copying)
which is useful for things like locations, rotations, scaling, and colours.
Implementation Notes:
- The bulk of the driver adding logic is in editors/animation/drivers.c, where most of
the Driver UI operators and tools are defined
- The property eyedropper code is in interface_eyedropper.c along with all the other
eyedroppers (even though they don't share much actual code in common). However, this
turns out to be necessary, as we can't get access to many of the low-level buttons API's
otherwise.
Todo:
- It may be necessary to restore a way to access the old behaviour (i.e. "manual setup")
in case it is not practical to immediately pick a property.
- Other things to investigate here include extra hotkeys (e.g. Ctrl-Shift-D for Add Single?),
and to expose the N-N mode.
- Other things we could try include interactively applying scaling factors, picking
multiple targets (e.g. for location difference and rotation difference drivers),
and/or other ways of using these property picking methods.
2016-03-26 17:55:42 +13:00
|
|
|
PointerRNA id_ptr2, ptr2;
|
|
|
|
|
PropertyRNA *prop2;
|
|
|
|
|
int done_tot = 0;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
Driver Setup Workflow Improvement: Property Eyedropper
This commit brings some long requested improvements to the workflow for setting up
drivers, which should make it easier and faster to set up new drivers in a more
interactive fashion.
The new workflow is as follows:
1) Hover over the property (e.g. "Lamp Energy" or "Y Location") or properties ("Rotation")
you wish to add drivers to. We'll refer to this as the "destination"
2) Ctrl-D to active the new "Add Drivers" eyedropper
3) Click on the property you want to use as the source/target. The property under the
mouse will be used to drive the property you invoked Ctrl-D on.
For example, to drive the X, Y, and Z location of the Cube using the Y Location of the Lamp,
hover over any of the X/Y/Z location buttons, hit Ctrl-D, then click on the Y-Location
button of the Lamp object. Drivers will be added to the X, Y, and Z Location properties
of the Cube; each driver will have a single variable, which uses the Y-Location Transform
Channel of the Lamp.
Tips:
- Transform properties will automatically create "Transform Channel" driver variables.
Everything else will use "Single Property" ones
- Due to the way that Blender's UI Context works, you'll need two Properties Panel instances
open (and to have pinned one of the two to show the properties for the unselected
object). It's slightly clunky, but necessary for implementing a workflow like this,
as the UI cannot be manipulated while using eyedroppers to pick data.
- The eyedropper operator implemented here actually has three modes of operation.
1) The "1-N" (one to many) mode is the default used for Ctrl-D, and "Add Driver to All"
in the RMB Menu. This is the behaviour described above.
2) There's also a "1-1" (one to one) mode that is used for the "Add Single Driver" in the
RMB Menu.
3) Finally, there's the "N-N" mode (many to many), which isn't currently exposed.
The point of this is to allow mapping XYZ to XYZ elementwise (i.e. direct copying)
which is useful for things like locations, rotations, scaling, and colours.
Implementation Notes:
- The bulk of the driver adding logic is in editors/animation/drivers.c, where most of
the Driver UI operators and tools are defined
- The property eyedropper code is in interface_eyedropper.c along with all the other
eyedroppers (even though they don't share much actual code in common). However, this
turns out to be necessary, as we can't get access to many of the low-level buttons API's
otherwise.
Todo:
- It may be necessary to restore a way to access the old behaviour (i.e. "manual setup")
in case it is not practical to immediately pick a property.
- Other things to investigate here include extra hotkeys (e.g. Ctrl-Shift-D for Add Single?),
and to expose the N-N mode.
- Other things we could try include interactively applying scaling factors, picking
multiple targets (e.g. for location difference and rotation difference drivers),
and/or other ways of using these property picking methods.
2016-03-26 17:55:42 +13:00
|
|
|
/* validate pointers first - exit if failure */
|
|
|
|
|
RNA_id_pointer_create(dst_id, &id_ptr);
|
|
|
|
|
if (RNA_path_resolve_property(&id_ptr, dst_path, &ptr, &prop) == false) {
|
2018-06-04 09:31:30 +02:00
|
|
|
BKE_reportf(reports, RPT_ERROR,
|
Driver Setup Workflow Improvement: Property Eyedropper
This commit brings some long requested improvements to the workflow for setting up
drivers, which should make it easier and faster to set up new drivers in a more
interactive fashion.
The new workflow is as follows:
1) Hover over the property (e.g. "Lamp Energy" or "Y Location") or properties ("Rotation")
you wish to add drivers to. We'll refer to this as the "destination"
2) Ctrl-D to active the new "Add Drivers" eyedropper
3) Click on the property you want to use as the source/target. The property under the
mouse will be used to drive the property you invoked Ctrl-D on.
For example, to drive the X, Y, and Z location of the Cube using the Y Location of the Lamp,
hover over any of the X/Y/Z location buttons, hit Ctrl-D, then click on the Y-Location
button of the Lamp object. Drivers will be added to the X, Y, and Z Location properties
of the Cube; each driver will have a single variable, which uses the Y-Location Transform
Channel of the Lamp.
Tips:
- Transform properties will automatically create "Transform Channel" driver variables.
Everything else will use "Single Property" ones
- Due to the way that Blender's UI Context works, you'll need two Properties Panel instances
open (and to have pinned one of the two to show the properties for the unselected
object). It's slightly clunky, but necessary for implementing a workflow like this,
as the UI cannot be manipulated while using eyedroppers to pick data.
- The eyedropper operator implemented here actually has three modes of operation.
1) The "1-N" (one to many) mode is the default used for Ctrl-D, and "Add Driver to All"
in the RMB Menu. This is the behaviour described above.
2) There's also a "1-1" (one to one) mode that is used for the "Add Single Driver" in the
RMB Menu.
3) Finally, there's the "N-N" mode (many to many), which isn't currently exposed.
The point of this is to allow mapping XYZ to XYZ elementwise (i.e. direct copying)
which is useful for things like locations, rotations, scaling, and colours.
Implementation Notes:
- The bulk of the driver adding logic is in editors/animation/drivers.c, where most of
the Driver UI operators and tools are defined
- The property eyedropper code is in interface_eyedropper.c along with all the other
eyedroppers (even though they don't share much actual code in common). However, this
turns out to be necessary, as we can't get access to many of the low-level buttons API's
otherwise.
Todo:
- It may be necessary to restore a way to access the old behaviour (i.e. "manual setup")
in case it is not practical to immediately pick a property.
- Other things to investigate here include extra hotkeys (e.g. Ctrl-Shift-D for Add Single?),
and to expose the N-N mode.
- Other things we could try include interactively applying scaling factors, picking
multiple targets (e.g. for location difference and rotation difference drivers),
and/or other ways of using these property picking methods.
2016-03-26 17:55:42 +13:00
|
|
|
"Could not add driver, as RNA path is invalid for the given ID (ID = %s, path = %s)",
|
|
|
|
|
dst_id->name, dst_path);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
Driver Setup Workflow Improvement: Property Eyedropper
This commit brings some long requested improvements to the workflow for setting up
drivers, which should make it easier and faster to set up new drivers in a more
interactive fashion.
The new workflow is as follows:
1) Hover over the property (e.g. "Lamp Energy" or "Y Location") or properties ("Rotation")
you wish to add drivers to. We'll refer to this as the "destination"
2) Ctrl-D to active the new "Add Drivers" eyedropper
3) Click on the property you want to use as the source/target. The property under the
mouse will be used to drive the property you invoked Ctrl-D on.
For example, to drive the X, Y, and Z location of the Cube using the Y Location of the Lamp,
hover over any of the X/Y/Z location buttons, hit Ctrl-D, then click on the Y-Location
button of the Lamp object. Drivers will be added to the X, Y, and Z Location properties
of the Cube; each driver will have a single variable, which uses the Y-Location Transform
Channel of the Lamp.
Tips:
- Transform properties will automatically create "Transform Channel" driver variables.
Everything else will use "Single Property" ones
- Due to the way that Blender's UI Context works, you'll need two Properties Panel instances
open (and to have pinned one of the two to show the properties for the unselected
object). It's slightly clunky, but necessary for implementing a workflow like this,
as the UI cannot be manipulated while using eyedroppers to pick data.
- The eyedropper operator implemented here actually has three modes of operation.
1) The "1-N" (one to many) mode is the default used for Ctrl-D, and "Add Driver to All"
in the RMB Menu. This is the behaviour described above.
2) There's also a "1-1" (one to one) mode that is used for the "Add Single Driver" in the
RMB Menu.
3) Finally, there's the "N-N" mode (many to many), which isn't currently exposed.
The point of this is to allow mapping XYZ to XYZ elementwise (i.e. direct copying)
which is useful for things like locations, rotations, scaling, and colours.
Implementation Notes:
- The bulk of the driver adding logic is in editors/animation/drivers.c, where most of
the Driver UI operators and tools are defined
- The property eyedropper code is in interface_eyedropper.c along with all the other
eyedroppers (even though they don't share much actual code in common). However, this
turns out to be necessary, as we can't get access to many of the low-level buttons API's
otherwise.
Todo:
- It may be necessary to restore a way to access the old behaviour (i.e. "manual setup")
in case it is not practical to immediately pick a property.
- Other things to investigate here include extra hotkeys (e.g. Ctrl-Shift-D for Add Single?),
and to expose the N-N mode.
- Other things we could try include interactively applying scaling factors, picking
multiple targets (e.g. for location difference and rotation difference drivers),
and/or other ways of using these property picking methods.
2016-03-26 17:55:42 +13:00
|
|
|
RNA_id_pointer_create(src_id, &id_ptr2);
|
2018-06-04 09:31:30 +02:00
|
|
|
if ((RNA_path_resolve_property(&id_ptr2, src_path, &ptr2, &prop2) == false) ||
|
2016-03-27 17:02:53 +13:00
|
|
|
(mapping_type == CREATEDRIVER_MAPPING_NONE))
|
|
|
|
|
{
|
Driver Setup Workflow Improvement: Property Eyedropper
This commit brings some long requested improvements to the workflow for setting up
drivers, which should make it easier and faster to set up new drivers in a more
interactive fashion.
The new workflow is as follows:
1) Hover over the property (e.g. "Lamp Energy" or "Y Location") or properties ("Rotation")
you wish to add drivers to. We'll refer to this as the "destination"
2) Ctrl-D to active the new "Add Drivers" eyedropper
3) Click on the property you want to use as the source/target. The property under the
mouse will be used to drive the property you invoked Ctrl-D on.
For example, to drive the X, Y, and Z location of the Cube using the Y Location of the Lamp,
hover over any of the X/Y/Z location buttons, hit Ctrl-D, then click on the Y-Location
button of the Lamp object. Drivers will be added to the X, Y, and Z Location properties
of the Cube; each driver will have a single variable, which uses the Y-Location Transform
Channel of the Lamp.
Tips:
- Transform properties will automatically create "Transform Channel" driver variables.
Everything else will use "Single Property" ones
- Due to the way that Blender's UI Context works, you'll need two Properties Panel instances
open (and to have pinned one of the two to show the properties for the unselected
object). It's slightly clunky, but necessary for implementing a workflow like this,
as the UI cannot be manipulated while using eyedroppers to pick data.
- The eyedropper operator implemented here actually has three modes of operation.
1) The "1-N" (one to many) mode is the default used for Ctrl-D, and "Add Driver to All"
in the RMB Menu. This is the behaviour described above.
2) There's also a "1-1" (one to one) mode that is used for the "Add Single Driver" in the
RMB Menu.
3) Finally, there's the "N-N" mode (many to many), which isn't currently exposed.
The point of this is to allow mapping XYZ to XYZ elementwise (i.e. direct copying)
which is useful for things like locations, rotations, scaling, and colours.
Implementation Notes:
- The bulk of the driver adding logic is in editors/animation/drivers.c, where most of
the Driver UI operators and tools are defined
- The property eyedropper code is in interface_eyedropper.c along with all the other
eyedroppers (even though they don't share much actual code in common). However, this
turns out to be necessary, as we can't get access to many of the low-level buttons API's
otherwise.
Todo:
- It may be necessary to restore a way to access the old behaviour (i.e. "manual setup")
in case it is not practical to immediately pick a property.
- Other things to investigate here include extra hotkeys (e.g. Ctrl-Shift-D for Add Single?),
and to expose the N-N mode.
- Other things we could try include interactively applying scaling factors, picking
multiple targets (e.g. for location difference and rotation difference drivers),
and/or other ways of using these property picking methods.
2016-03-26 17:55:42 +13:00
|
|
|
/* No target - So, fall back to default method for adding a "simple" driver normally */
|
2016-03-27 17:02:53 +13:00
|
|
|
return ANIM_add_driver(reports, dst_id, dst_path, dst_index, flag | CREATEDRIVER_WITH_DEFAULT_DVAR, driver_type);
|
Driver Setup Workflow Improvement: Property Eyedropper
This commit brings some long requested improvements to the workflow for setting up
drivers, which should make it easier and faster to set up new drivers in a more
interactive fashion.
The new workflow is as follows:
1) Hover over the property (e.g. "Lamp Energy" or "Y Location") or properties ("Rotation")
you wish to add drivers to. We'll refer to this as the "destination"
2) Ctrl-D to active the new "Add Drivers" eyedropper
3) Click on the property you want to use as the source/target. The property under the
mouse will be used to drive the property you invoked Ctrl-D on.
For example, to drive the X, Y, and Z location of the Cube using the Y Location of the Lamp,
hover over any of the X/Y/Z location buttons, hit Ctrl-D, then click on the Y-Location
button of the Lamp object. Drivers will be added to the X, Y, and Z Location properties
of the Cube; each driver will have a single variable, which uses the Y-Location Transform
Channel of the Lamp.
Tips:
- Transform properties will automatically create "Transform Channel" driver variables.
Everything else will use "Single Property" ones
- Due to the way that Blender's UI Context works, you'll need two Properties Panel instances
open (and to have pinned one of the two to show the properties for the unselected
object). It's slightly clunky, but necessary for implementing a workflow like this,
as the UI cannot be manipulated while using eyedroppers to pick data.
- The eyedropper operator implemented here actually has three modes of operation.
1) The "1-N" (one to many) mode is the default used for Ctrl-D, and "Add Driver to All"
in the RMB Menu. This is the behaviour described above.
2) There's also a "1-1" (one to one) mode that is used for the "Add Single Driver" in the
RMB Menu.
3) Finally, there's the "N-N" mode (many to many), which isn't currently exposed.
The point of this is to allow mapping XYZ to XYZ elementwise (i.e. direct copying)
which is useful for things like locations, rotations, scaling, and colours.
Implementation Notes:
- The bulk of the driver adding logic is in editors/animation/drivers.c, where most of
the Driver UI operators and tools are defined
- The property eyedropper code is in interface_eyedropper.c along with all the other
eyedroppers (even though they don't share much actual code in common). However, this
turns out to be necessary, as we can't get access to many of the low-level buttons API's
otherwise.
Todo:
- It may be necessary to restore a way to access the old behaviour (i.e. "manual setup")
in case it is not practical to immediately pick a property.
- Other things to investigate here include extra hotkeys (e.g. Ctrl-Shift-D for Add Single?),
and to expose the N-N mode.
- Other things we could try include interactively applying scaling factors, picking
multiple targets (e.g. for location difference and rotation difference drivers),
and/or other ways of using these property picking methods.
2016-03-26 17:55:42 +13:00
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
Driver Setup Workflow Improvement: Property Eyedropper
This commit brings some long requested improvements to the workflow for setting up
drivers, which should make it easier and faster to set up new drivers in a more
interactive fashion.
The new workflow is as follows:
1) Hover over the property (e.g. "Lamp Energy" or "Y Location") or properties ("Rotation")
you wish to add drivers to. We'll refer to this as the "destination"
2) Ctrl-D to active the new "Add Drivers" eyedropper
3) Click on the property you want to use as the source/target. The property under the
mouse will be used to drive the property you invoked Ctrl-D on.
For example, to drive the X, Y, and Z location of the Cube using the Y Location of the Lamp,
hover over any of the X/Y/Z location buttons, hit Ctrl-D, then click on the Y-Location
button of the Lamp object. Drivers will be added to the X, Y, and Z Location properties
of the Cube; each driver will have a single variable, which uses the Y-Location Transform
Channel of the Lamp.
Tips:
- Transform properties will automatically create "Transform Channel" driver variables.
Everything else will use "Single Property" ones
- Due to the way that Blender's UI Context works, you'll need two Properties Panel instances
open (and to have pinned one of the two to show the properties for the unselected
object). It's slightly clunky, but necessary for implementing a workflow like this,
as the UI cannot be manipulated while using eyedroppers to pick data.
- The eyedropper operator implemented here actually has three modes of operation.
1) The "1-N" (one to many) mode is the default used for Ctrl-D, and "Add Driver to All"
in the RMB Menu. This is the behaviour described above.
2) There's also a "1-1" (one to one) mode that is used for the "Add Single Driver" in the
RMB Menu.
3) Finally, there's the "N-N" mode (many to many), which isn't currently exposed.
The point of this is to allow mapping XYZ to XYZ elementwise (i.e. direct copying)
which is useful for things like locations, rotations, scaling, and colours.
Implementation Notes:
- The bulk of the driver adding logic is in editors/animation/drivers.c, where most of
the Driver UI operators and tools are defined
- The property eyedropper code is in interface_eyedropper.c along with all the other
eyedroppers (even though they don't share much actual code in common). However, this
turns out to be necessary, as we can't get access to many of the low-level buttons API's
otherwise.
Todo:
- It may be necessary to restore a way to access the old behaviour (i.e. "manual setup")
in case it is not practical to immediately pick a property.
- Other things to investigate here include extra hotkeys (e.g. Ctrl-Shift-D for Add Single?),
and to expose the N-N mode.
- Other things we could try include interactively applying scaling factors, picking
multiple targets (e.g. for location difference and rotation difference drivers),
and/or other ways of using these property picking methods.
2016-03-26 17:55:42 +13:00
|
|
|
/* handle curve-property mappings based on mapping_type */
|
|
|
|
|
switch (mapping_type) {
|
2019-01-15 23:24:20 +11:00
|
|
|
case CREATEDRIVER_MAPPING_N_N: /* N-N - Try to match as much as possible,
|
|
|
|
|
* then use the first one */
|
Driver Setup Workflow Improvement: Property Eyedropper
This commit brings some long requested improvements to the workflow for setting up
drivers, which should make it easier and faster to set up new drivers in a more
interactive fashion.
The new workflow is as follows:
1) Hover over the property (e.g. "Lamp Energy" or "Y Location") or properties ("Rotation")
you wish to add drivers to. We'll refer to this as the "destination"
2) Ctrl-D to active the new "Add Drivers" eyedropper
3) Click on the property you want to use as the source/target. The property under the
mouse will be used to drive the property you invoked Ctrl-D on.
For example, to drive the X, Y, and Z location of the Cube using the Y Location of the Lamp,
hover over any of the X/Y/Z location buttons, hit Ctrl-D, then click on the Y-Location
button of the Lamp object. Drivers will be added to the X, Y, and Z Location properties
of the Cube; each driver will have a single variable, which uses the Y-Location Transform
Channel of the Lamp.
Tips:
- Transform properties will automatically create "Transform Channel" driver variables.
Everything else will use "Single Property" ones
- Due to the way that Blender's UI Context works, you'll need two Properties Panel instances
open (and to have pinned one of the two to show the properties for the unselected
object). It's slightly clunky, but necessary for implementing a workflow like this,
as the UI cannot be manipulated while using eyedroppers to pick data.
- The eyedropper operator implemented here actually has three modes of operation.
1) The "1-N" (one to many) mode is the default used for Ctrl-D, and "Add Driver to All"
in the RMB Menu. This is the behaviour described above.
2) There's also a "1-1" (one to one) mode that is used for the "Add Single Driver" in the
RMB Menu.
3) Finally, there's the "N-N" mode (many to many), which isn't currently exposed.
The point of this is to allow mapping XYZ to XYZ elementwise (i.e. direct copying)
which is useful for things like locations, rotations, scaling, and colours.
Implementation Notes:
- The bulk of the driver adding logic is in editors/animation/drivers.c, where most of
the Driver UI operators and tools are defined
- The property eyedropper code is in interface_eyedropper.c along with all the other
eyedroppers (even though they don't share much actual code in common). However, this
turns out to be necessary, as we can't get access to many of the low-level buttons API's
otherwise.
Todo:
- It may be necessary to restore a way to access the old behaviour (i.e. "manual setup")
in case it is not practical to immediately pick a property.
- Other things to investigate here include extra hotkeys (e.g. Ctrl-Shift-D for Add Single?),
and to expose the N-N mode.
- Other things we could try include interactively applying scaling factors, picking
multiple targets (e.g. for location difference and rotation difference drivers),
and/or other ways of using these property picking methods.
2016-03-26 17:55:42 +13:00
|
|
|
{
|
|
|
|
|
/* Use the shorter of the two (to avoid out of bounds access) */
|
|
|
|
|
int dst_len = (RNA_property_array_check(prop)) ? RNA_property_array_length(&ptr, prop) : 1;
|
|
|
|
|
int src_len = (RNA_property_array_check(prop)) ? RNA_property_array_length(&ptr2, prop2) : 1;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
Driver Setup Workflow Improvement: Property Eyedropper
This commit brings some long requested improvements to the workflow for setting up
drivers, which should make it easier and faster to set up new drivers in a more
interactive fashion.
The new workflow is as follows:
1) Hover over the property (e.g. "Lamp Energy" or "Y Location") or properties ("Rotation")
you wish to add drivers to. We'll refer to this as the "destination"
2) Ctrl-D to active the new "Add Drivers" eyedropper
3) Click on the property you want to use as the source/target. The property under the
mouse will be used to drive the property you invoked Ctrl-D on.
For example, to drive the X, Y, and Z location of the Cube using the Y Location of the Lamp,
hover over any of the X/Y/Z location buttons, hit Ctrl-D, then click on the Y-Location
button of the Lamp object. Drivers will be added to the X, Y, and Z Location properties
of the Cube; each driver will have a single variable, which uses the Y-Location Transform
Channel of the Lamp.
Tips:
- Transform properties will automatically create "Transform Channel" driver variables.
Everything else will use "Single Property" ones
- Due to the way that Blender's UI Context works, you'll need two Properties Panel instances
open (and to have pinned one of the two to show the properties for the unselected
object). It's slightly clunky, but necessary for implementing a workflow like this,
as the UI cannot be manipulated while using eyedroppers to pick data.
- The eyedropper operator implemented here actually has three modes of operation.
1) The "1-N" (one to many) mode is the default used for Ctrl-D, and "Add Driver to All"
in the RMB Menu. This is the behaviour described above.
2) There's also a "1-1" (one to one) mode that is used for the "Add Single Driver" in the
RMB Menu.
3) Finally, there's the "N-N" mode (many to many), which isn't currently exposed.
The point of this is to allow mapping XYZ to XYZ elementwise (i.e. direct copying)
which is useful for things like locations, rotations, scaling, and colours.
Implementation Notes:
- The bulk of the driver adding logic is in editors/animation/drivers.c, where most of
the Driver UI operators and tools are defined
- The property eyedropper code is in interface_eyedropper.c along with all the other
eyedroppers (even though they don't share much actual code in common). However, this
turns out to be necessary, as we can't get access to many of the low-level buttons API's
otherwise.
Todo:
- It may be necessary to restore a way to access the old behaviour (i.e. "manual setup")
in case it is not practical to immediately pick a property.
- Other things to investigate here include extra hotkeys (e.g. Ctrl-Shift-D for Add Single?),
and to expose the N-N mode.
- Other things we could try include interactively applying scaling factors, picking
multiple targets (e.g. for location difference and rotation difference drivers),
and/or other ways of using these property picking methods.
2016-03-26 17:55:42 +13:00
|
|
|
int len = MIN2(dst_len, src_len);
|
|
|
|
|
int i;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
Driver Setup Workflow Improvement: Property Eyedropper
This commit brings some long requested improvements to the workflow for setting up
drivers, which should make it easier and faster to set up new drivers in a more
interactive fashion.
The new workflow is as follows:
1) Hover over the property (e.g. "Lamp Energy" or "Y Location") or properties ("Rotation")
you wish to add drivers to. We'll refer to this as the "destination"
2) Ctrl-D to active the new "Add Drivers" eyedropper
3) Click on the property you want to use as the source/target. The property under the
mouse will be used to drive the property you invoked Ctrl-D on.
For example, to drive the X, Y, and Z location of the Cube using the Y Location of the Lamp,
hover over any of the X/Y/Z location buttons, hit Ctrl-D, then click on the Y-Location
button of the Lamp object. Drivers will be added to the X, Y, and Z Location properties
of the Cube; each driver will have a single variable, which uses the Y-Location Transform
Channel of the Lamp.
Tips:
- Transform properties will automatically create "Transform Channel" driver variables.
Everything else will use "Single Property" ones
- Due to the way that Blender's UI Context works, you'll need two Properties Panel instances
open (and to have pinned one of the two to show the properties for the unselected
object). It's slightly clunky, but necessary for implementing a workflow like this,
as the UI cannot be manipulated while using eyedroppers to pick data.
- The eyedropper operator implemented here actually has three modes of operation.
1) The "1-N" (one to many) mode is the default used for Ctrl-D, and "Add Driver to All"
in the RMB Menu. This is the behaviour described above.
2) There's also a "1-1" (one to one) mode that is used for the "Add Single Driver" in the
RMB Menu.
3) Finally, there's the "N-N" mode (many to many), which isn't currently exposed.
The point of this is to allow mapping XYZ to XYZ elementwise (i.e. direct copying)
which is useful for things like locations, rotations, scaling, and colours.
Implementation Notes:
- The bulk of the driver adding logic is in editors/animation/drivers.c, where most of
the Driver UI operators and tools are defined
- The property eyedropper code is in interface_eyedropper.c along with all the other
eyedroppers (even though they don't share much actual code in common). However, this
turns out to be necessary, as we can't get access to many of the low-level buttons API's
otherwise.
Todo:
- It may be necessary to restore a way to access the old behaviour (i.e. "manual setup")
in case it is not practical to immediately pick a property.
- Other things to investigate here include extra hotkeys (e.g. Ctrl-Shift-D for Add Single?),
and to expose the N-N mode.
- Other things we could try include interactively applying scaling factors, picking
multiple targets (e.g. for location difference and rotation difference drivers),
and/or other ways of using these property picking methods.
2016-03-26 17:55:42 +13:00
|
|
|
for (i = 0; i < len; i++) {
|
2016-03-27 17:57:27 +13:00
|
|
|
done_tot += add_driver_with_target(reports, dst_id, dst_path, i, src_id, src_path, i, &ptr, prop, &ptr2, prop2, flag, driver_type);
|
Driver Setup Workflow Improvement: Property Eyedropper
This commit brings some long requested improvements to the workflow for setting up
drivers, which should make it easier and faster to set up new drivers in a more
interactive fashion.
The new workflow is as follows:
1) Hover over the property (e.g. "Lamp Energy" or "Y Location") or properties ("Rotation")
you wish to add drivers to. We'll refer to this as the "destination"
2) Ctrl-D to active the new "Add Drivers" eyedropper
3) Click on the property you want to use as the source/target. The property under the
mouse will be used to drive the property you invoked Ctrl-D on.
For example, to drive the X, Y, and Z location of the Cube using the Y Location of the Lamp,
hover over any of the X/Y/Z location buttons, hit Ctrl-D, then click on the Y-Location
button of the Lamp object. Drivers will be added to the X, Y, and Z Location properties
of the Cube; each driver will have a single variable, which uses the Y-Location Transform
Channel of the Lamp.
Tips:
- Transform properties will automatically create "Transform Channel" driver variables.
Everything else will use "Single Property" ones
- Due to the way that Blender's UI Context works, you'll need two Properties Panel instances
open (and to have pinned one of the two to show the properties for the unselected
object). It's slightly clunky, but necessary for implementing a workflow like this,
as the UI cannot be manipulated while using eyedroppers to pick data.
- The eyedropper operator implemented here actually has three modes of operation.
1) The "1-N" (one to many) mode is the default used for Ctrl-D, and "Add Driver to All"
in the RMB Menu. This is the behaviour described above.
2) There's also a "1-1" (one to one) mode that is used for the "Add Single Driver" in the
RMB Menu.
3) Finally, there's the "N-N" mode (many to many), which isn't currently exposed.
The point of this is to allow mapping XYZ to XYZ elementwise (i.e. direct copying)
which is useful for things like locations, rotations, scaling, and colours.
Implementation Notes:
- The bulk of the driver adding logic is in editors/animation/drivers.c, where most of
the Driver UI operators and tools are defined
- The property eyedropper code is in interface_eyedropper.c along with all the other
eyedroppers (even though they don't share much actual code in common). However, this
turns out to be necessary, as we can't get access to many of the low-level buttons API's
otherwise.
Todo:
- It may be necessary to restore a way to access the old behaviour (i.e. "manual setup")
in case it is not practical to immediately pick a property.
- Other things to investigate here include extra hotkeys (e.g. Ctrl-Shift-D for Add Single?),
and to expose the N-N mode.
- Other things we could try include interactively applying scaling factors, picking
multiple targets (e.g. for location difference and rotation difference drivers),
and/or other ways of using these property picking methods.
2016-03-26 17:55:42 +13:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
Driver Setup Workflow Improvement: Property Eyedropper
This commit brings some long requested improvements to the workflow for setting up
drivers, which should make it easier and faster to set up new drivers in a more
interactive fashion.
The new workflow is as follows:
1) Hover over the property (e.g. "Lamp Energy" or "Y Location") or properties ("Rotation")
you wish to add drivers to. We'll refer to this as the "destination"
2) Ctrl-D to active the new "Add Drivers" eyedropper
3) Click on the property you want to use as the source/target. The property under the
mouse will be used to drive the property you invoked Ctrl-D on.
For example, to drive the X, Y, and Z location of the Cube using the Y Location of the Lamp,
hover over any of the X/Y/Z location buttons, hit Ctrl-D, then click on the Y-Location
button of the Lamp object. Drivers will be added to the X, Y, and Z Location properties
of the Cube; each driver will have a single variable, which uses the Y-Location Transform
Channel of the Lamp.
Tips:
- Transform properties will automatically create "Transform Channel" driver variables.
Everything else will use "Single Property" ones
- Due to the way that Blender's UI Context works, you'll need two Properties Panel instances
open (and to have pinned one of the two to show the properties for the unselected
object). It's slightly clunky, but necessary for implementing a workflow like this,
as the UI cannot be manipulated while using eyedroppers to pick data.
- The eyedropper operator implemented here actually has three modes of operation.
1) The "1-N" (one to many) mode is the default used for Ctrl-D, and "Add Driver to All"
in the RMB Menu. This is the behaviour described above.
2) There's also a "1-1" (one to one) mode that is used for the "Add Single Driver" in the
RMB Menu.
3) Finally, there's the "N-N" mode (many to many), which isn't currently exposed.
The point of this is to allow mapping XYZ to XYZ elementwise (i.e. direct copying)
which is useful for things like locations, rotations, scaling, and colours.
Implementation Notes:
- The bulk of the driver adding logic is in editors/animation/drivers.c, where most of
the Driver UI operators and tools are defined
- The property eyedropper code is in interface_eyedropper.c along with all the other
eyedroppers (even though they don't share much actual code in common). However, this
turns out to be necessary, as we can't get access to many of the low-level buttons API's
otherwise.
Todo:
- It may be necessary to restore a way to access the old behaviour (i.e. "manual setup")
in case it is not practical to immediately pick a property.
- Other things to investigate here include extra hotkeys (e.g. Ctrl-Shift-D for Add Single?),
and to expose the N-N mode.
- Other things we could try include interactively applying scaling factors, picking
multiple targets (e.g. for location difference and rotation difference drivers),
and/or other ways of using these property picking methods.
2016-03-26 17:55:42 +13:00
|
|
|
case CREATEDRIVER_MAPPING_1_N: /* 1-N - Specified target index for all */
|
|
|
|
|
default:
|
|
|
|
|
{
|
|
|
|
|
int len = (RNA_property_array_check(prop)) ? RNA_property_array_length(&ptr, prop) : 1;
|
|
|
|
|
int i;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
Driver Setup Workflow Improvement: Property Eyedropper
This commit brings some long requested improvements to the workflow for setting up
drivers, which should make it easier and faster to set up new drivers in a more
interactive fashion.
The new workflow is as follows:
1) Hover over the property (e.g. "Lamp Energy" or "Y Location") or properties ("Rotation")
you wish to add drivers to. We'll refer to this as the "destination"
2) Ctrl-D to active the new "Add Drivers" eyedropper
3) Click on the property you want to use as the source/target. The property under the
mouse will be used to drive the property you invoked Ctrl-D on.
For example, to drive the X, Y, and Z location of the Cube using the Y Location of the Lamp,
hover over any of the X/Y/Z location buttons, hit Ctrl-D, then click on the Y-Location
button of the Lamp object. Drivers will be added to the X, Y, and Z Location properties
of the Cube; each driver will have a single variable, which uses the Y-Location Transform
Channel of the Lamp.
Tips:
- Transform properties will automatically create "Transform Channel" driver variables.
Everything else will use "Single Property" ones
- Due to the way that Blender's UI Context works, you'll need two Properties Panel instances
open (and to have pinned one of the two to show the properties for the unselected
object). It's slightly clunky, but necessary for implementing a workflow like this,
as the UI cannot be manipulated while using eyedroppers to pick data.
- The eyedropper operator implemented here actually has three modes of operation.
1) The "1-N" (one to many) mode is the default used for Ctrl-D, and "Add Driver to All"
in the RMB Menu. This is the behaviour described above.
2) There's also a "1-1" (one to one) mode that is used for the "Add Single Driver" in the
RMB Menu.
3) Finally, there's the "N-N" mode (many to many), which isn't currently exposed.
The point of this is to allow mapping XYZ to XYZ elementwise (i.e. direct copying)
which is useful for things like locations, rotations, scaling, and colours.
Implementation Notes:
- The bulk of the driver adding logic is in editors/animation/drivers.c, where most of
the Driver UI operators and tools are defined
- The property eyedropper code is in interface_eyedropper.c along with all the other
eyedroppers (even though they don't share much actual code in common). However, this
turns out to be necessary, as we can't get access to many of the low-level buttons API's
otherwise.
Todo:
- It may be necessary to restore a way to access the old behaviour (i.e. "manual setup")
in case it is not practical to immediately pick a property.
- Other things to investigate here include extra hotkeys (e.g. Ctrl-Shift-D for Add Single?),
and to expose the N-N mode.
- Other things we could try include interactively applying scaling factors, picking
multiple targets (e.g. for location difference and rotation difference drivers),
and/or other ways of using these property picking methods.
2016-03-26 17:55:42 +13:00
|
|
|
for (i = 0; i < len; i++) {
|
2016-03-27 17:57:27 +13:00
|
|
|
done_tot += add_driver_with_target(reports, dst_id, dst_path, i, src_id, src_path, src_index, &ptr, prop, &ptr2, prop2, flag, driver_type);
|
Driver Setup Workflow Improvement: Property Eyedropper
This commit brings some long requested improvements to the workflow for setting up
drivers, which should make it easier and faster to set up new drivers in a more
interactive fashion.
The new workflow is as follows:
1) Hover over the property (e.g. "Lamp Energy" or "Y Location") or properties ("Rotation")
you wish to add drivers to. We'll refer to this as the "destination"
2) Ctrl-D to active the new "Add Drivers" eyedropper
3) Click on the property you want to use as the source/target. The property under the
mouse will be used to drive the property you invoked Ctrl-D on.
For example, to drive the X, Y, and Z location of the Cube using the Y Location of the Lamp,
hover over any of the X/Y/Z location buttons, hit Ctrl-D, then click on the Y-Location
button of the Lamp object. Drivers will be added to the X, Y, and Z Location properties
of the Cube; each driver will have a single variable, which uses the Y-Location Transform
Channel of the Lamp.
Tips:
- Transform properties will automatically create "Transform Channel" driver variables.
Everything else will use "Single Property" ones
- Due to the way that Blender's UI Context works, you'll need two Properties Panel instances
open (and to have pinned one of the two to show the properties for the unselected
object). It's slightly clunky, but necessary for implementing a workflow like this,
as the UI cannot be manipulated while using eyedroppers to pick data.
- The eyedropper operator implemented here actually has three modes of operation.
1) The "1-N" (one to many) mode is the default used for Ctrl-D, and "Add Driver to All"
in the RMB Menu. This is the behaviour described above.
2) There's also a "1-1" (one to one) mode that is used for the "Add Single Driver" in the
RMB Menu.
3) Finally, there's the "N-N" mode (many to many), which isn't currently exposed.
The point of this is to allow mapping XYZ to XYZ elementwise (i.e. direct copying)
which is useful for things like locations, rotations, scaling, and colours.
Implementation Notes:
- The bulk of the driver adding logic is in editors/animation/drivers.c, where most of
the Driver UI operators and tools are defined
- The property eyedropper code is in interface_eyedropper.c along with all the other
eyedroppers (even though they don't share much actual code in common). However, this
turns out to be necessary, as we can't get access to many of the low-level buttons API's
otherwise.
Todo:
- It may be necessary to restore a way to access the old behaviour (i.e. "manual setup")
in case it is not practical to immediately pick a property.
- Other things to investigate here include extra hotkeys (e.g. Ctrl-Shift-D for Add Single?),
and to expose the N-N mode.
- Other things we could try include interactively applying scaling factors, picking
multiple targets (e.g. for location difference and rotation difference drivers),
and/or other ways of using these property picking methods.
2016-03-26 17:55:42 +13:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
Driver Setup Workflow Improvement: Property Eyedropper
This commit brings some long requested improvements to the workflow for setting up
drivers, which should make it easier and faster to set up new drivers in a more
interactive fashion.
The new workflow is as follows:
1) Hover over the property (e.g. "Lamp Energy" or "Y Location") or properties ("Rotation")
you wish to add drivers to. We'll refer to this as the "destination"
2) Ctrl-D to active the new "Add Drivers" eyedropper
3) Click on the property you want to use as the source/target. The property under the
mouse will be used to drive the property you invoked Ctrl-D on.
For example, to drive the X, Y, and Z location of the Cube using the Y Location of the Lamp,
hover over any of the X/Y/Z location buttons, hit Ctrl-D, then click on the Y-Location
button of the Lamp object. Drivers will be added to the X, Y, and Z Location properties
of the Cube; each driver will have a single variable, which uses the Y-Location Transform
Channel of the Lamp.
Tips:
- Transform properties will automatically create "Transform Channel" driver variables.
Everything else will use "Single Property" ones
- Due to the way that Blender's UI Context works, you'll need two Properties Panel instances
open (and to have pinned one of the two to show the properties for the unselected
object). It's slightly clunky, but necessary for implementing a workflow like this,
as the UI cannot be manipulated while using eyedroppers to pick data.
- The eyedropper operator implemented here actually has three modes of operation.
1) The "1-N" (one to many) mode is the default used for Ctrl-D, and "Add Driver to All"
in the RMB Menu. This is the behaviour described above.
2) There's also a "1-1" (one to one) mode that is used for the "Add Single Driver" in the
RMB Menu.
3) Finally, there's the "N-N" mode (many to many), which isn't currently exposed.
The point of this is to allow mapping XYZ to XYZ elementwise (i.e. direct copying)
which is useful for things like locations, rotations, scaling, and colours.
Implementation Notes:
- The bulk of the driver adding logic is in editors/animation/drivers.c, where most of
the Driver UI operators and tools are defined
- The property eyedropper code is in interface_eyedropper.c along with all the other
eyedroppers (even though they don't share much actual code in common). However, this
turns out to be necessary, as we can't get access to many of the low-level buttons API's
otherwise.
Todo:
- It may be necessary to restore a way to access the old behaviour (i.e. "manual setup")
in case it is not practical to immediately pick a property.
- Other things to investigate here include extra hotkeys (e.g. Ctrl-Shift-D for Add Single?),
and to expose the N-N mode.
- Other things we could try include interactively applying scaling factors, picking
multiple targets (e.g. for location difference and rotation difference drivers),
and/or other ways of using these property picking methods.
2016-03-26 17:55:42 +13:00
|
|
|
case CREATEDRIVER_MAPPING_1_1: /* 1-1 - Use the specified index (unless -1) */
|
|
|
|
|
{
|
2016-03-27 17:57:27 +13:00
|
|
|
done_tot = add_driver_with_target(reports, dst_id, dst_path, dst_index, src_id, src_path, src_index, &ptr, prop, &ptr2, prop2, flag, driver_type);
|
Driver Setup Workflow Improvement: Property Eyedropper
This commit brings some long requested improvements to the workflow for setting up
drivers, which should make it easier and faster to set up new drivers in a more
interactive fashion.
The new workflow is as follows:
1) Hover over the property (e.g. "Lamp Energy" or "Y Location") or properties ("Rotation")
you wish to add drivers to. We'll refer to this as the "destination"
2) Ctrl-D to active the new "Add Drivers" eyedropper
3) Click on the property you want to use as the source/target. The property under the
mouse will be used to drive the property you invoked Ctrl-D on.
For example, to drive the X, Y, and Z location of the Cube using the Y Location of the Lamp,
hover over any of the X/Y/Z location buttons, hit Ctrl-D, then click on the Y-Location
button of the Lamp object. Drivers will be added to the X, Y, and Z Location properties
of the Cube; each driver will have a single variable, which uses the Y-Location Transform
Channel of the Lamp.
Tips:
- Transform properties will automatically create "Transform Channel" driver variables.
Everything else will use "Single Property" ones
- Due to the way that Blender's UI Context works, you'll need two Properties Panel instances
open (and to have pinned one of the two to show the properties for the unselected
object). It's slightly clunky, but necessary for implementing a workflow like this,
as the UI cannot be manipulated while using eyedroppers to pick data.
- The eyedropper operator implemented here actually has three modes of operation.
1) The "1-N" (one to many) mode is the default used for Ctrl-D, and "Add Driver to All"
in the RMB Menu. This is the behaviour described above.
2) There's also a "1-1" (one to one) mode that is used for the "Add Single Driver" in the
RMB Menu.
3) Finally, there's the "N-N" mode (many to many), which isn't currently exposed.
The point of this is to allow mapping XYZ to XYZ elementwise (i.e. direct copying)
which is useful for things like locations, rotations, scaling, and colours.
Implementation Notes:
- The bulk of the driver adding logic is in editors/animation/drivers.c, where most of
the Driver UI operators and tools are defined
- The property eyedropper code is in interface_eyedropper.c along with all the other
eyedroppers (even though they don't share much actual code in common). However, this
turns out to be necessary, as we can't get access to many of the low-level buttons API's
otherwise.
Todo:
- It may be necessary to restore a way to access the old behaviour (i.e. "manual setup")
in case it is not practical to immediately pick a property.
- Other things to investigate here include extra hotkeys (e.g. Ctrl-Shift-D for Add Single?),
and to expose the N-N mode.
- Other things we could try include interactively applying scaling factors, picking
multiple targets (e.g. for location difference and rotation difference drivers),
and/or other ways of using these property picking methods.
2016-03-26 17:55:42 +13:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
Driver Setup Workflow Improvement: Property Eyedropper
This commit brings some long requested improvements to the workflow for setting up
drivers, which should make it easier and faster to set up new drivers in a more
interactive fashion.
The new workflow is as follows:
1) Hover over the property (e.g. "Lamp Energy" or "Y Location") or properties ("Rotation")
you wish to add drivers to. We'll refer to this as the "destination"
2) Ctrl-D to active the new "Add Drivers" eyedropper
3) Click on the property you want to use as the source/target. The property under the
mouse will be used to drive the property you invoked Ctrl-D on.
For example, to drive the X, Y, and Z location of the Cube using the Y Location of the Lamp,
hover over any of the X/Y/Z location buttons, hit Ctrl-D, then click on the Y-Location
button of the Lamp object. Drivers will be added to the X, Y, and Z Location properties
of the Cube; each driver will have a single variable, which uses the Y-Location Transform
Channel of the Lamp.
Tips:
- Transform properties will automatically create "Transform Channel" driver variables.
Everything else will use "Single Property" ones
- Due to the way that Blender's UI Context works, you'll need two Properties Panel instances
open (and to have pinned one of the two to show the properties for the unselected
object). It's slightly clunky, but necessary for implementing a workflow like this,
as the UI cannot be manipulated while using eyedroppers to pick data.
- The eyedropper operator implemented here actually has three modes of operation.
1) The "1-N" (one to many) mode is the default used for Ctrl-D, and "Add Driver to All"
in the RMB Menu. This is the behaviour described above.
2) There's also a "1-1" (one to one) mode that is used for the "Add Single Driver" in the
RMB Menu.
3) Finally, there's the "N-N" mode (many to many), which isn't currently exposed.
The point of this is to allow mapping XYZ to XYZ elementwise (i.e. direct copying)
which is useful for things like locations, rotations, scaling, and colours.
Implementation Notes:
- The bulk of the driver adding logic is in editors/animation/drivers.c, where most of
the Driver UI operators and tools are defined
- The property eyedropper code is in interface_eyedropper.c along with all the other
eyedroppers (even though they don't share much actual code in common). However, this
turns out to be necessary, as we can't get access to many of the low-level buttons API's
otherwise.
Todo:
- It may be necessary to restore a way to access the old behaviour (i.e. "manual setup")
in case it is not practical to immediately pick a property.
- Other things to investigate here include extra hotkeys (e.g. Ctrl-Shift-D for Add Single?),
and to expose the N-N mode.
- Other things we could try include interactively applying scaling factors, picking
multiple targets (e.g. for location difference and rotation difference drivers),
and/or other ways of using these property picking methods.
2016-03-26 17:55:42 +13:00
|
|
|
/* done */
|
|
|
|
|
return done_tot;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* --------------------------------- */
|
|
|
|
|
|
2009-04-10 13:08:12 +00:00
|
|
|
/* Main Driver Management API calls:
|
2018-09-02 18:28:27 +10: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)
|
2018-06-04 09:31:30 +02:00
|
|
|
{
|
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;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
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) {
|
2018-06-04 09:31:30 +02: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;
|
|
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
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;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
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;
|
2018-06-04 09:31:30 +02: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;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
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);
|
2018-06-04 09:31:30 +02: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;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
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;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
Driver Workflow (T55145): Tweak to default expression used for new drivers created from UI
Previously, newly created drivers were set to "Scripted Expression"
mode and had their 'expression' field set to the pre-driver value of the
property, so that adding a driver didn't cause the property to immediately
lose its old value (and potentially causing havok in the scene).
However, this had the unintended consequence of making the driver setup
workflow more cumbersome, as you first had to replace that value with
the name of the driver variable before your driver would work.
This commit works around this issue by trying to combine the best of both
worlds (quite literally): Now, the driver expression for drivers created
using Ctrl-D will be "var + <old value>".
Thus, in the simplest case, the driver will do something as soon as you fill
out the driver variable settings (e.g. just filling out the Target Object field
will do it), meaning you get your drivers working faster. Of course, it may now
be necessary to edit out the old-value, and/or it might be a bit more confusing
what/why it's there for newbies. However, the improved ease of setup, and/or
a more tangible example of how an expression may be constructed outweigh the
downsides IMO.
2018-06-11 17:44:08 +12:00
|
|
|
/* Creating drivers for buttons will create the driver(s) with type
|
2010-12-28 05:45:15 +00:00
|
|
|
* "scripted expression" so that their values won't be lost immediately,
|
|
|
|
|
* so here we copy those values over to the driver's expression
|
Driver Workflow (T55145): Tweak to default expression used for new drivers created from UI
Previously, newly created drivers were set to "Scripted Expression"
mode and had their 'expression' field set to the pre-driver value of the
property, so that adding a driver didn't cause the property to immediately
lose its old value (and potentially causing havok in the scene).
However, this had the unintended consequence of making the driver setup
workflow more cumbersome, as you first had to replace that value with
the name of the driver variable before your driver would work.
This commit works around this issue by trying to combine the best of both
worlds (quite literally): Now, the driver expression for drivers created
using Ctrl-D will be "var + <old value>".
Thus, in the simplest case, the driver will do something as soon as you fill
out the driver variable settings (e.g. just filling out the Target Object field
will do it), meaning you get your drivers working faster. Of course, it may now
be necessary to edit out the old-value, and/or it might be a bit more confusing
what/why it's there for newbies. However, the improved ease of setup, and/or
a more tangible example of how an expression may be constructed outweigh the
downsides IMO.
2018-06-11 17:44:08 +12:00
|
|
|
*
|
|
|
|
|
* If the "default dvar" option (for easier UI setup of drivers) is provided,
|
|
|
|
|
* include "var" in the expressions too, so that the user doesn't have to edit
|
|
|
|
|
* it to get something to happen. It should be fine to just add it to the default
|
|
|
|
|
* value, so that we get both in the expression, even if it's a bit more confusing
|
|
|
|
|
* that way...
|
2010-12-28 05:45:15 +00:00
|
|
|
*/
|
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);
|
2018-06-11 09:03:39 +02:00
|
|
|
const char *dvar_prefix = (flag & CREATEDRIVER_WITH_DEFAULT_DVAR) ? "var + " : "";
|
2012-05-08 15:30:00 +00:00
|
|
|
char *expression = driver->expression;
|
|
|
|
|
int val, maxlen = sizeof(driver->expression);
|
2009-11-04 15:16:41 +00:00
|
|
|
float fval;
|
2018-06-04 09:31:30 +02: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);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
Driver Workflow (T55145): Tweak to default expression used for new drivers created from UI
Previously, newly created drivers were set to "Scripted Expression"
mode and had their 'expression' field set to the pre-driver value of the
property, so that adding a driver didn't cause the property to immediately
lose its old value (and potentially causing havok in the scene).
However, this had the unintended consequence of making the driver setup
workflow more cumbersome, as you first had to replace that value with
the name of the driver variable before your driver would work.
This commit works around this issue by trying to combine the best of both
worlds (quite literally): Now, the driver expression for drivers created
using Ctrl-D will be "var + <old value>".
Thus, in the simplest case, the driver will do something as soon as you fill
out the driver variable settings (e.g. just filling out the Target Object field
will do it), meaning you get your drivers working faster. Of course, it may now
be necessary to edit out the old-value, and/or it might be a bit more confusing
what/why it's there for newbies. However, the improved ease of setup, and/or
a more tangible example of how an expression may be constructed outweigh the
downsides IMO.
2018-06-11 17:44:08 +12:00
|
|
|
BLI_snprintf(expression, maxlen, "%s%s", dvar_prefix, (val) ? "True" : "False");
|
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);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
Driver Workflow (T55145): Tweak to default expression used for new drivers created from UI
Previously, newly created drivers were set to "Scripted Expression"
mode and had their 'expression' field set to the pre-driver value of the
property, so that adding a driver didn't cause the property to immediately
lose its old value (and potentially causing havok in the scene).
However, this had the unintended consequence of making the driver setup
workflow more cumbersome, as you first had to replace that value with
the name of the driver variable before your driver would work.
This commit works around this issue by trying to combine the best of both
worlds (quite literally): Now, the driver expression for drivers created
using Ctrl-D will be "var + <old value>".
Thus, in the simplest case, the driver will do something as soon as you fill
out the driver variable settings (e.g. just filling out the Target Object field
will do it), meaning you get your drivers working faster. Of course, it may now
be necessary to edit out the old-value, and/or it might be a bit more confusing
what/why it's there for newbies. However, the improved ease of setup, and/or
a more tangible example of how an expression may be constructed outweigh the
downsides IMO.
2018-06-11 17:44:08 +12:00
|
|
|
BLI_snprintf(expression, maxlen, "%s%d", dvar_prefix, val);
|
2009-11-04 15:16:41 +00:00
|
|
|
}
|
|
|
|
|
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);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
Driver Workflow (T55145): Tweak to default expression used for new drivers created from UI
Previously, newly created drivers were set to "Scripted Expression"
mode and had their 'expression' field set to the pre-driver value of the
property, so that adding a driver didn't cause the property to immediately
lose its old value (and potentially causing havok in the scene).
However, this had the unintended consequence of making the driver setup
workflow more cumbersome, as you first had to replace that value with
the name of the driver variable before your driver would work.
This commit works around this issue by trying to combine the best of both
worlds (quite literally): Now, the driver expression for drivers created
using Ctrl-D will be "var + <old value>".
Thus, in the simplest case, the driver will do something as soon as you fill
out the driver variable settings (e.g. just filling out the Target Object field
will do it), meaning you get your drivers working faster. Of course, it may now
be necessary to edit out the old-value, and/or it might be a bit more confusing
what/why it's there for newbies. However, the improved ease of setup, and/or
a more tangible example of how an expression may be constructed outweigh the
downsides IMO.
2018-06-11 17:44:08 +12:00
|
|
|
BLI_snprintf(expression, maxlen, "%s%.3f", dvar_prefix, fval);
|
2018-06-17 14:50:42 +02:00
|
|
|
BLI_str_rstrip_float_zero(expression, '\0');
|
Driver Workflow (T55145): Tweak to default expression used for new drivers created from UI
Previously, newly created drivers were set to "Scripted Expression"
mode and had their 'expression' field set to the pre-driver value of the
property, so that adding a driver didn't cause the property to immediately
lose its old value (and potentially causing havok in the scene).
However, this had the unintended consequence of making the driver setup
workflow more cumbersome, as you first had to replace that value with
the name of the driver variable before your driver would work.
This commit works around this issue by trying to combine the best of both
worlds (quite literally): Now, the driver expression for drivers created
using Ctrl-D will be "var + <old value>".
Thus, in the simplest case, the driver will do something as soon as you fill
out the driver variable settings (e.g. just filling out the Target Object field
will do it), meaning you get your drivers working faster. Of course, it may now
be necessary to edit out the old-value, and/or it might be a bit more confusing
what/why it's there for newbies. However, the improved ease of setup, and/or
a more tangible example of how an expression may be constructed outweigh the
downsides IMO.
2018-06-11 17:44:08 +12:00
|
|
|
}
|
|
|
|
|
else if (flag & CREATEDRIVER_WITH_DEFAULT_DVAR) {
|
|
|
|
|
BLI_strncpy(expression, "var", maxlen);
|
2009-11-04 15:16:41 +00:00
|
|
|
}
|
2009-07-12 02:06:15 +00:00
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
|
|
|
|
/* for easier setup of drivers from UI, a driver variable should be
|
2010-12-28 05:45:15 +00:00
|
|
|
* 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
|
|
|
}
|
2018-06-04 09:31:30 +02: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
|
|
|
}
|
2018-06-04 09:31:30 +02: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:
|
2018-09-02 18:28:27 +10: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;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
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);
|
2018-06-04 09:31:30 +02: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;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
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;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
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);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2010-04-11 09:13:37 +00:00
|
|
|
/* done successfully */
|
2014-04-01 11:34:00 +11:00
|
|
|
success = true;
|
2010-04-11 09:13:37 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
2018-06-04 09:31:30 +02:00
|
|
|
/* find the matching driver and remove it only
|
2010-12-28 05:45:15 +00:00
|
|
|
* 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);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
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 */
|
2016-04-03 01:18:23 +13:00
|
|
|
void ANIM_drivers_copybuf_free(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;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-09-25 04:51:04 +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 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;
|
|
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-09-25 04:51:04 +00:00
|
|
|
/* 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);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-09-25 04:51:04 +00:00
|
|
|
/* clear copy/paste buffer first (for consistency with other copy/paste buffers) */
|
2016-04-03 01:18:23 +13:00
|
|
|
ANIM_drivers_copybuf_free();
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-09-25 04:51:04 +00:00
|
|
|
/* 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;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
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);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-09-25 04:51:04 +00:00
|
|
|
/* restore the path */
|
2012-05-08 15:30:00 +00:00
|
|
|
fcu->rna_path = tmp_path;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-09-25 04:51:04 +00:00
|
|
|
/* copied... */
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-09-25 04:51:04 +00:00
|
|
|
/* done */
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Main Driver Management API calls:
|
2018-11-14 12:53:15 +11:00
|
|
|
* Add a new driver for the specified property on the given ID block or replace an existing one
|
|
|
|
|
* with the driver + driver-curve data from the buffer
|
2009-09-25 04:51:04 +00:00
|
|
|
*/
|
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))
|
2018-06-04 09:31:30 +02:00
|
|
|
{
|
2009-09-25 04:51:04 +00:00
|
|
|
PointerRNA id_ptr, ptr;
|
|
|
|
|
PropertyRNA *prop;
|
|
|
|
|
FCurve *fcu;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-09-25 04:51:04 +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 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;
|
|
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-09-25 04:51:04 +00:00
|
|
|
/* 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;
|
|
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-09-25 04:51:04 +00:00
|
|
|
/* 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);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-09-25 04:51:04 +00:00
|
|
|
if (fcu) {
|
2018-06-04 09:31:30 +02:00
|
|
|
/* copy across the curve data from the buffer curve
|
2009-09-25 04:51:04 +00:00
|
|
|
* 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;
|
2018-06-04 09:31:30 +02: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);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2012-05-08 15:30:00 +00:00
|
|
|
/* extrapolation mode */
|
|
|
|
|
fcu->extend = channeldriver_copypaste_buf->extend;
|
2018-06-04 09:31:30 +02: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
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-09-25 04:51:04 +00:00
|
|
|
/* done */
|
|
|
|
|
return (fcu != NULL);
|
|
|
|
|
}
|
2009-04-10 13:08:12 +00:00
|
|
|
|
2016-04-15 20:04:07 +12:00
|
|
|
/* ************************************************** */
|
|
|
|
|
/* 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) {
|
|
|
|
|
DriverVar *dvar, *dvarn;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2016-04-15 22:05:18 +12:00
|
|
|
/* Free variables (and any data they use) */
|
2016-04-15 20:04:07 +12:00
|
|
|
for (dvar = driver_vars_copybuf.first; dvar; dvar = dvarn) {
|
|
|
|
|
dvarn = dvar->next;
|
|
|
|
|
driver_free_variable(&driver_vars_copybuf, dvar);
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2016-04-15 20:04:07 +12:00
|
|
|
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;
|
|
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2016-04-15 20:04:07 +12:00
|
|
|
if (BLI_listbase_is_empty(&fcu->driver->variables)) {
|
|
|
|
|
BKE_report(reports, RPT_ERROR, "Driver has no variables to copy");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2016-04-15 20:04:07 +12:00
|
|
|
/* clear buffer */
|
|
|
|
|
ANIM_driver_vars_copybuf_free();
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2016-04-15 20:04:07 +12:00
|
|
|
/* copy over the variables */
|
|
|
|
|
driver_variables_copy(&driver_vars_copybuf, &fcu->driver->variables);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2016-04-15 20:04:07 +12:00
|
|
|
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};
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2016-04-15 20:04:07 +12:00
|
|
|
/* sanity checks */
|
|
|
|
|
if (BLI_listbase_is_empty(&driver_vars_copybuf)) {
|
|
|
|
|
BKE_report(reports, RPT_ERROR, "No driver variables in clipboard to paste");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2016-04-15 20:04:07 +12:00
|
|
|
if (ELEM(NULL, fcu, fcu->driver)) {
|
|
|
|
|
BKE_report(reports, RPT_ERROR, "Cannot paste driver variables without a driver");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2016-04-15 20:04:07 +12:00
|
|
|
/* 1) Make a new copy of the variables in the buffer - these will get pasted later... */
|
|
|
|
|
driver_variables_copy(&tmp_list, &driver_vars_copybuf);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2016-04-15 20:04:07 +12:00
|
|
|
/* 2) Prepare destination array */
|
|
|
|
|
if (replace) {
|
|
|
|
|
DriverVar *dvar, *dvarn;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2016-04-15 20:04:07 +12:00
|
|
|
/* 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);
|
|
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2016-04-15 20:04:07 +12:00
|
|
|
BLI_listbase_clear(&driver->variables);
|
|
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2016-04-15 20:04:07 +12:00
|
|
|
/* 3) Add new vars */
|
|
|
|
|
if (driver->variables.last) {
|
|
|
|
|
DriverVar *last = driver->variables.last;
|
|
|
|
|
DriverVar *first = tmp_list.first;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2016-04-15 20:04:07 +12:00
|
|
|
last->next = first;
|
|
|
|
|
first->prev = last;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2016-04-15 20:04:07 +12:00
|
|
|
driver->variables.last = tmp_list.last;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
driver->variables.first = tmp_list.first;
|
|
|
|
|
driver->variables.last = tmp_list.last;
|
|
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2016-04-15 20:04:07 +12:00
|
|
|
/* since driver variables are cached, the expression needs re-compiling too */
|
Support evaluating simple driver expressions without Python interpreter.
Recently @sergey found that hard-coding evaluation of certain very
common driver expressions without calling the Python interpreter
produces a 30-40% performance improvement. Since hard-coding is
obviously not suitable for production, I implemented a proper
parser and interpreter for simple arithmetic expressions in C.
The evaluator supports +, -, *, /, (), ==, !=, <, <=, >, >=,
and, or, not, ternary if; driver variables, frame, pi, True, False,
and a subset of standard math functions that seem most useful.
Booleans are represented as numbers, since within the supported
operation set it seems to be impossible to distinguish True/False
from 1.0/0.0. Boolean operations properly implement lazy evaluation
with jumps, and comparisons support chaining like 'a < b < c...'.
Expressions are parsed into a very simple stack machine program
that can then be safely evaluated in multiple threads.
Reviewers: sergey, campbellbarton
Differential Revision: https://developer.blender.org/D3698
2018-09-15 15:32:40 +03:00
|
|
|
BKE_driver_invalidate_expression(driver, false, true);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2016-04-15 20:04:07 +12:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2009-04-10 13:08:12 +00:00
|
|
|
/* ************************************************** */
|
|
|
|
|
/* UI-Button Interface */
|
|
|
|
|
|
2016-03-30 03:01:27 +13:00
|
|
|
/* Add Driver - Enum Defines ------------------------- */
|
2009-04-10 13:08:12 +00:00
|
|
|
|
2016-03-30 03:01:27 +13:00
|
|
|
/* Mapping Types enum for operators */
|
|
|
|
|
/* NOTE: Used by ANIM_OT_driver_button_add and UI_OT_eyedropper_driver */
|
|
|
|
|
// XXX: These names need reviewing
|
|
|
|
|
EnumPropertyItem prop_driver_create_mapping_types[] = {
|
2018-10-28 17:51:40 +01:00
|
|
|
{CREATEDRIVER_MAPPING_1_N, "SINGLE_MANY", 0, "All from Target",
|
2016-03-30 03:01:27 +13:00
|
|
|
"Drive all components of this property using the target picked"},
|
|
|
|
|
{CREATEDRIVER_MAPPING_1_1, "DIRECT", 0, "Single from Target",
|
|
|
|
|
"Drive this component of this property using the target picked"},
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2016-04-17 03:28:45 +12:00
|
|
|
{CREATEDRIVER_MAPPING_N_N, "MATCH", ICON_COLOR, "Match Indices",
|
2016-03-30 03:01:27 +13:00
|
|
|
"Create drivers for each pair of corresponding elements"},
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2016-03-30 03:18:01 +13:00
|
|
|
{CREATEDRIVER_MAPPING_NONE_ALL, "NONE_ALL", ICON_HAND, "Manually Create Later",
|
2016-06-01 20:38:30 +02:00
|
|
|
"Create drivers for all properties without assigning any targets yet"},
|
2016-03-30 03:01:27 +13:00
|
|
|
{CREATEDRIVER_MAPPING_NONE, "NONE_SINGLE", 0, "Manually Create Later (Single)",
|
|
|
|
|
"Create driver for this property only and without assigning any targets yet"},
|
2019-02-03 14:01:45 +11:00
|
|
|
{0, NULL, 0, NULL, NULL},
|
2016-03-30 03:01:27 +13:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* Filtering callback for driver mapping types enum */
|
2017-10-18 15:07:26 +11:00
|
|
|
static const EnumPropertyItem *driver_mapping_type_itemsf(bContext *C, PointerRNA *UNUSED(owner_ptr), PropertyRNA *UNUSED(owner_prop), bool *r_free)
|
2009-04-10 13:08:12 +00:00
|
|
|
{
|
2016-03-30 03:01:27 +13:00
|
|
|
EnumPropertyItem *input = prop_driver_create_mapping_types;
|
|
|
|
|
EnumPropertyItem *item = NULL;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2012-05-08 15:30:00 +00:00
|
|
|
PointerRNA ptr = {{NULL}};
|
|
|
|
|
PropertyRNA *prop = NULL;
|
2014-02-03 18:55:59 +11:00
|
|
|
int index;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2016-03-30 03:01:27 +13:00
|
|
|
int totitem = 0;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2016-03-30 03:01:27 +13:00
|
|
|
if (!C) /* needed for docs */
|
|
|
|
|
return prop_driver_create_mapping_types;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_context_active_but_prop_get(C, &ptr, &prop, &index);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2010-09-23 20:26:03 +00:00
|
|
|
if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
|
2016-03-30 03:01:27 +13:00
|
|
|
const bool is_array = RNA_property_array_check(prop);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2016-03-30 03:01:27 +13:00
|
|
|
while (input->identifier) {
|
|
|
|
|
if (ELEM(input->value, CREATEDRIVER_MAPPING_1_1, CREATEDRIVER_MAPPING_NONE) || (is_array)) {
|
|
|
|
|
RNA_enum_item_add(&item, &totitem, input);
|
|
|
|
|
}
|
|
|
|
|
input++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* We need at least this one! */
|
|
|
|
|
RNA_enum_items_add_value(&item, &totitem, input, CREATEDRIVER_MAPPING_NONE);
|
|
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2016-03-30 03:01:27 +13:00
|
|
|
RNA_enum_item_end(&item, &totitem);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2016-03-30 03:01:27 +13:00
|
|
|
*r_free = true;
|
|
|
|
|
return item;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2018-06-11 17:35:13 +12:00
|
|
|
/* Add Driver (With Menu) Button Operator ------------------------ */
|
2016-03-30 03:01:27 +13:00
|
|
|
|
2018-07-02 11:47:00 +02:00
|
|
|
static bool add_driver_button_poll(bContext *C)
|
2016-03-30 03:01:27 +13:00
|
|
|
{
|
|
|
|
|
PointerRNA ptr = {{NULL}};
|
|
|
|
|
PropertyRNA *prop = NULL;
|
|
|
|
|
int index;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2016-03-30 03:01:27 +13:00
|
|
|
/* this operator can only run if there's a property button active, and it can be animated */
|
|
|
|
|
UI_context_active_but_prop_get(C, &ptr, &prop, &index);
|
|
|
|
|
return (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Wrapper for creating a driver without knowing what the targets will be yet (i.e. "manual/add later") */
|
|
|
|
|
static int add_driver_button_none(bContext *C, wmOperator *op, short mapping_type)
|
|
|
|
|
{
|
|
|
|
|
PointerRNA ptr = {{NULL}};
|
|
|
|
|
PropertyRNA *prop = NULL;
|
|
|
|
|
int index;
|
|
|
|
|
int success = 0;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2016-03-30 03:01:27 +13:00
|
|
|
UI_context_active_but_prop_get(C, &ptr, &prop, &index);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2016-03-30 03:01:27 +13:00
|
|
|
if (mapping_type == CREATEDRIVER_MAPPING_NONE_ALL)
|
|
|
|
|
index = -1;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2016-03-30 03:01:27 +13:00
|
|
|
if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
|
|
|
|
|
char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
|
|
|
|
|
short flags = CREATEDRIVER_WITH_DEFAULT_DVAR;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2016-03-30 03:01:27 +13:00
|
|
|
if (path) {
|
|
|
|
|
success += ANIM_add_driver(op->reports, ptr.id.data, path, index, flags, DRIVER_TYPE_PYTHON);
|
|
|
|
|
MEM_freeN(path);
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2016-03-30 03:01:27 +13:00
|
|
|
if (success) {
|
|
|
|
|
/* send updates */
|
|
|
|
|
UI_context_update_anim_flag(C);
|
2017-06-08 10:14:53 +02:00
|
|
|
DEG_relations_tag_update(CTX_data_main(C));
|
2016-03-30 03:01:27 +13:00
|
|
|
WM_event_add_notifier(C, NC_ANIMATION | ND_FCURVES_ORDER, NULL); // XXX
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2016-03-30 03:01:27 +13:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-11 17:35:13 +12:00
|
|
|
static int add_driver_button_menu_exec(bContext *C, wmOperator *op)
|
2016-03-30 03:01:27 +13:00
|
|
|
{
|
|
|
|
|
short mapping_type = RNA_enum_get(op->ptr, "mapping_type");
|
|
|
|
|
if (ELEM(mapping_type, CREATEDRIVER_MAPPING_NONE, CREATEDRIVER_MAPPING_NONE_ALL)) {
|
|
|
|
|
/* Just create driver with no targets */
|
|
|
|
|
return add_driver_button_none(C, op, mapping_type);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* Create Driver using Eyedropper */
|
|
|
|
|
wmOperatorType *ot = WM_operatortype_find("UI_OT_eyedropper_driver", true);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2016-03-30 03:01:27 +13:00
|
|
|
/* XXX: We assume that it's fine to use the same set of properties, since they're actually the same... */
|
2016-03-31 16:18:04 +02:00
|
|
|
WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, op->ptr);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2016-03-31 16:18:04 +02:00
|
|
|
return OPERATOR_FINISHED;
|
2009-04-10 13:08:12 +00:00
|
|
|
}
|
2016-03-30 03:01:27 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Show menu or create drivers */
|
2018-06-11 17:35:13 +12:00
|
|
|
static int add_driver_button_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
2016-03-30 03:01:27 +13:00
|
|
|
{
|
|
|
|
|
PropertyRNA *prop;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2016-03-30 03:01:27 +13:00
|
|
|
if ((prop = RNA_struct_find_property(op->ptr, "mapping_type")) && RNA_property_is_set(op->ptr, prop)) {
|
|
|
|
|
/* Mapping Type is Set - Directly go into creating drivers */
|
2018-06-11 17:35:13 +12:00
|
|
|
return add_driver_button_menu_exec(C, op);
|
2016-03-30 03:01:27 +13:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* Show menu */
|
|
|
|
|
// TODO: This should get filtered by the enum filter
|
2016-05-31 16:30:44 +10:00
|
|
|
/* important to execute in the region we're currently in */
|
|
|
|
|
return WM_menu_invoke_ex(C, op, WM_OP_INVOKE_DEFAULT);
|
2016-03-30 03:01:27 +13:00
|
|
|
}
|
2009-04-10 13:08:12 +00:00
|
|
|
}
|
|
|
|
|
|
2018-06-11 09:03:39 +02:00
|
|
|
static void UNUSED_FUNCTION(ANIM_OT_driver_button_add_menu)(wmOperatorType *ot)
|
2009-04-10 13:08:12 +00:00
|
|
|
{
|
|
|
|
|
/* identifiers */
|
2018-06-11 17:35:13 +12:00
|
|
|
ot->name = "Add Driver Menu";
|
|
|
|
|
ot->idname = "ANIM_OT_driver_button_add_menu";
|
2016-04-23 14:49:30 +02:00
|
|
|
ot->description = "Add driver(s) for the property(s) represented by the highlighted button";
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-04-10 13:08:12 +00:00
|
|
|
/* callbacks */
|
2018-06-11 17:35:13 +12:00
|
|
|
ot->invoke = add_driver_button_menu_invoke;
|
|
|
|
|
ot->exec = add_driver_button_menu_exec;
|
2016-03-30 03:01:27 +13:00
|
|
|
ot->poll = add_driver_button_poll;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-04-10 13:08:12 +00:00
|
|
|
/* flags */
|
2014-02-26 18:54:40 +01:00
|
|
|
ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-04-10 13:08:12 +00:00
|
|
|
/* properties */
|
2016-03-30 03:01:27 +13:00
|
|
|
ot->prop = RNA_def_enum(ot->srna, "mapping_type", prop_driver_create_mapping_types, 0,
|
|
|
|
|
"Mapping Type", "Method used to match target and driven properties");
|
|
|
|
|
RNA_def_enum_funcs(ot->prop, driver_mapping_type_itemsf);
|
2009-04-10 13:08:12 +00:00
|
|
|
}
|
|
|
|
|
|
2018-06-11 17:35:13 +12:00
|
|
|
/* Add Driver Button Operator ------------------------ */
|
|
|
|
|
|
|
|
|
|
static int add_driver_button_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
|
|
|
|
{
|
|
|
|
|
PointerRNA ptr = {{NULL}};
|
|
|
|
|
PropertyRNA *prop = NULL;
|
|
|
|
|
int index;
|
|
|
|
|
|
|
|
|
|
/* try to find driver using property retrieved from UI */
|
|
|
|
|
UI_context_active_but_prop_get(C, &ptr, &prop, &index);
|
|
|
|
|
|
|
|
|
|
if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
|
|
|
|
|
/* 1) Create a new "empty" driver for this property */
|
|
|
|
|
char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
|
|
|
|
|
short flags = CREATEDRIVER_WITH_DEFAULT_DVAR;
|
|
|
|
|
short success = 0;
|
|
|
|
|
|
|
|
|
|
if (path) {
|
|
|
|
|
success += ANIM_add_driver(op->reports, ptr.id.data, path, index, flags, DRIVER_TYPE_PYTHON);
|
|
|
|
|
MEM_freeN(path);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (success) {
|
|
|
|
|
/* send updates */
|
|
|
|
|
UI_context_update_anim_flag(C);
|
2018-12-06 17:52:37 +01:00
|
|
|
DEG_id_tag_update(ptr.id.data, ID_RECALC_COPY_ON_WRITE);
|
2018-06-11 17:35:13 +12:00
|
|
|
DEG_relations_tag_update(CTX_data_main(C));
|
|
|
|
|
WM_event_add_notifier(C, NC_ANIMATION | ND_FCURVES_ORDER, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 2) Show editing panel for setting up this driver */
|
|
|
|
|
/* TODO: Use a different one from the editing popever, so we can have the single/all toggle? */
|
2018-07-13 19:13:44 +02:00
|
|
|
UI_popover_panel_invoke(C, "GRAPH_PT_drivers_popover", true, op->reports);
|
2018-06-11 17:35:13 +12:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return OPERATOR_INTERFACE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ANIM_OT_driver_button_add(wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
/* identifiers */
|
|
|
|
|
ot->name = "Add Driver";
|
|
|
|
|
ot->idname = "ANIM_OT_driver_button_add";
|
|
|
|
|
ot->description = "Add driver for the property under the cursor";
|
|
|
|
|
|
|
|
|
|
/* callbacks */
|
|
|
|
|
/* NOTE: No exec, as we need all these to use the current context info */
|
|
|
|
|
ot->invoke = add_driver_button_invoke;
|
|
|
|
|
ot->poll = add_driver_button_poll;
|
|
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
|
ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
|
|
|
|
|
}
|
|
|
|
|
|
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");
|
2018-06-04 09:31:30 +02: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);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2010-04-11 09:13:37 +00:00
|
|
|
if (all)
|
2012-05-08 15:30:00 +00:00
|
|
|
index = -1;
|
2018-06-04 09:31:30 +02: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);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2015-03-05 09:10:16 +11:00
|
|
|
if (path) {
|
|
|
|
|
success = ANIM_remove_driver(op->reports, ptr.id.data, path, index, 0);
|
|
|
|
|
|
|
|
|
|
MEM_freeN(path);
|
|
|
|
|
}
|
2009-04-10 13:08:12 +00:00
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
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);
|
2017-06-08 10:14:53 +02:00
|
|
|
DEG_relations_tag_update(CTX_data_main(C));
|
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
|
|
|
}
|
2018-06-04 09:31:30 +02: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";
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-04-10 13:08:12 +00:00
|
|
|
/* callbacks */
|
2018-06-04 09:31:30 +02: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...
|
2018-06-04 09:31:30 +02:00
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
2018-05-24 18:08:32 +02:00
|
|
|
/* Edit Driver Button Operator ------------------------ */
|
|
|
|
|
|
|
|
|
|
static int edit_driver_button_exec(bContext *C, wmOperator *op)
|
|
|
|
|
{
|
|
|
|
|
PointerRNA ptr = {{NULL}};
|
|
|
|
|
PropertyRNA *prop = NULL;
|
|
|
|
|
int index;
|
2018-05-25 12:54:24 +02:00
|
|
|
|
2018-05-24 18:08:32 +02:00
|
|
|
/* try to find driver using property retrieved from UI */
|
|
|
|
|
UI_context_active_but_prop_get(C, &ptr, &prop, &index);
|
2018-05-25 12:54:24 +02:00
|
|
|
|
2018-05-24 18:08:32 +02:00
|
|
|
if (ptr.id.data && ptr.data && prop) {
|
2018-07-13 19:13:44 +02:00
|
|
|
UI_popover_panel_invoke(C, "GRAPH_PT_drivers_popover", true, op->reports);
|
2018-05-24 18:08:32 +02:00
|
|
|
}
|
2018-05-25 12:54:24 +02:00
|
|
|
|
2018-05-24 18:08:32 +02:00
|
|
|
return OPERATOR_INTERFACE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ANIM_OT_driver_button_edit(wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
/* identifiers */
|
|
|
|
|
ot->name = "Edit Driver";
|
|
|
|
|
ot->idname = "ANIM_OT_driver_button_edit";
|
|
|
|
|
ot->description = "Edit the drivers for the property connected represented by the highlighted button";
|
2018-06-04 09:39:04 +02:00
|
|
|
|
2018-05-24 18:08:32 +02:00
|
|
|
/* callbacks */
|
|
|
|
|
ot->exec = edit_driver_button_exec;
|
|
|
|
|
//op->poll = ??? // TODO: need to have some driver to be able to do this...
|
2018-06-04 09:39:04 +02:00
|
|
|
|
2018-05-24 18:08:32 +02:00
|
|
|
/* flags */
|
|
|
|
|
ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
|
|
|
|
|
}
|
|
|
|
|
|
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;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-09-25 04:51:04 +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);
|
2018-06-04 09:31:30 +02: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);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
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);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_context_update_anim_flag(C);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-09-25 04:51:04 +00:00
|
|
|
MEM_freeN(path);
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-09-25 04:51:04 +00:00
|
|
|
/* 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";
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-09-25 04:51:04 +00:00
|
|
|
/* callbacks */
|
2018-06-04 09:31:30 +02: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...
|
2018-06-04 09:31:30 +02:00
|
|
|
|
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;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-09-25 04:51:04 +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);
|
2018-06-04 09:31:30 +02: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);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
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);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2014-11-09 21:20:40 +01:00
|
|
|
UI_context_update_anim_flag(C);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2017-09-26 14:57:14 +10:00
|
|
|
DEG_relations_tag_update(CTX_data_main(C));
|
2018-12-06 17:52:37 +01:00
|
|
|
DEG_id_tag_update(ptr.id.data, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2017-09-26 13:29:48 +13:00
|
|
|
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, NULL); // XXX
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-09-25 04:51:04 +00:00
|
|
|
MEM_freeN(path);
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-09-25 04:51:04 +00:00
|
|
|
/* 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";
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-09-25 04:51:04 +00:00
|
|
|
/* callbacks */
|
2018-06-04 09:31:30 +02: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...
|
2018-06-04 09:31:30 +02:00
|
|
|
|
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
|
|
|
/* ************************************************** */
|