Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2019-04-17 07:17:24 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-04-17 07:21:24 +0300
commite12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 (patch)
tree8cf3453d12edb177a218ef8009357518ec6cab6a /source/blender/editors/space_graph
parentb3dabc200a4b0399ec6b81f2ff2730d07b44fcaa (diff)
ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat
Diffstat (limited to 'source/blender/editors/space_graph')
-rw-r--r--source/blender/editors/space_graph/CMakeLists.txt60
-rw-r--r--source/blender/editors/space_graph/graph_buttons.c2121
-rw-r--r--source/blender/editors/space_graph/graph_draw.c2040
-rw-r--r--source/blender/editors/space_graph/graph_edit.c4155
-rw-r--r--source/blender/editors/space_graph/graph_intern.h52
-rw-r--r--source/blender/editors/space_graph/graph_ops.c712
-rw-r--r--source/blender/editors/space_graph/graph_select.c2395
-rw-r--r--source/blender/editors/space_graph/graph_utils.c402
-rw-r--r--source/blender/editors/space_graph/space_graph.c1424
9 files changed, 6942 insertions, 6419 deletions
diff --git a/source/blender/editors/space_graph/CMakeLists.txt b/source/blender/editors/space_graph/CMakeLists.txt
index e0fc7500f94..cf5ffdb2be5 100644
--- a/source/blender/editors/space_graph/CMakeLists.txt
+++ b/source/blender/editors/space_graph/CMakeLists.txt
@@ -16,52 +16,52 @@
# ***** END GPL LICENSE BLOCK *****
set(INC
- ../include
- ../../blenkernel
- ../../blenlib
- ../../blentranslation
- ../../depsgraph
- ../../gpu
- ../../makesdna
- ../../makesrna
- ../../windowmanager
- ../../../../intern/guardedalloc
- ../../../../intern/glew-mx
+ ../include
+ ../../blenkernel
+ ../../blenlib
+ ../../blentranslation
+ ../../depsgraph
+ ../../gpu
+ ../../makesdna
+ ../../makesrna
+ ../../windowmanager
+ ../../../../intern/guardedalloc
+ ../../../../intern/glew-mx
)
set(INC_SYS
- ${GLEW_INCLUDE_PATH}
+ ${GLEW_INCLUDE_PATH}
)
set(SRC
- graph_buttons.c
- graph_draw.c
- graph_edit.c
- graph_ops.c
- graph_select.c
- graph_utils.c
- space_graph.c
+ graph_buttons.c
+ graph_draw.c
+ graph_edit.c
+ graph_ops.c
+ graph_select.c
+ graph_utils.c
+ space_graph.c
- graph_intern.h
+ graph_intern.h
)
set(LIB
- bf_blenkernel
- bf_blenlib
+ bf_blenkernel
+ bf_blenlib
)
if(WITH_AUDASPACE)
- list(APPEND INC_SYS
- ${AUDASPACE_C_INCLUDE_DIRS}
- )
- list(APPEND LIB
- bf_intern_audaspace
- )
- add_definitions(-DWITH_AUDASPACE)
+ list(APPEND INC_SYS
+ ${AUDASPACE_C_INCLUDE_DIRS}
+ )
+ list(APPEND LIB
+ bf_intern_audaspace
+ )
+ add_definitions(-DWITH_AUDASPACE)
endif()
if(WITH_INTERNATIONAL)
- add_definitions(-DWITH_INTERNATIONAL)
+ add_definitions(-DWITH_INTERNATIONAL)
endif()
add_definitions(${GL_DEFINITIONS})
diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c
index a4d7b5e9fc9..ac77095cbe2 100644
--- a/source/blender/editors/space_graph/graph_buttons.c
+++ b/source/blender/editors/space_graph/graph_buttons.c
@@ -21,7 +21,6 @@
* \ingroup spgraph
*/
-
#include <string.h>
#include <stdio.h>
#include <math.h>
@@ -64,7 +63,7 @@
#include "UI_interface.h"
#include "UI_resources.h"
-#include "graph_intern.h" // own include
+#include "graph_intern.h" // own include
/* ******************* graph editor space & buttons ************** */
@@ -74,33 +73,33 @@
static int graph_panel_context(const bContext *C, bAnimListElem **ale, FCurve **fcu)
{
- bAnimContext ac;
- bAnimListElem *elem = NULL;
-
- /* for now, only draw if we could init the anim-context info (necessary for all animation-related tools)
- * to work correctly is able to be correctly retrieved. There's no point showing empty panels?
- */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return 0;
-
- /* try to find 'active' F-Curve */
- elem = get_active_fcurve_channel(&ac);
- if (elem == NULL)
- return 0;
-
- if (fcu)
- *fcu = (FCurve *)elem->data;
- if (ale)
- *ale = elem;
- else
- MEM_freeN(elem);
-
- return 1;
+ bAnimContext ac;
+ bAnimListElem *elem = NULL;
+
+ /* for now, only draw if we could init the anim-context info (necessary for all animation-related tools)
+ * to work correctly is able to be correctly retrieved. There's no point showing empty panels?
+ */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return 0;
+
+ /* try to find 'active' F-Curve */
+ elem = get_active_fcurve_channel(&ac);
+ if (elem == NULL)
+ return 0;
+
+ if (fcu)
+ *fcu = (FCurve *)elem->data;
+ if (ale)
+ *ale = elem;
+ else
+ MEM_freeN(elem);
+
+ return 1;
}
static bool graph_panel_poll(const bContext *C, PanelType *UNUSED(pt))
{
- return graph_panel_context(C, NULL, NULL);
+ return graph_panel_context(C, NULL, NULL);
}
/* -------------- */
@@ -108,104 +107,104 @@ static bool graph_panel_poll(const bContext *C, PanelType *UNUSED(pt))
/* Graph Editor View Settings */
static void graph_panel_view(const bContext *C, Panel *pa)
{
- bScreen *sc = CTX_wm_screen(C);
- SpaceGraph *sipo = CTX_wm_space_graph(C);
- Scene *scene = CTX_data_scene(C);
- PointerRNA spaceptr, sceneptr;
- uiLayout *col, *sub, *row;
-
- /* get RNA pointers for use when creating the UI elements */
- RNA_id_pointer_create(&scene->id, &sceneptr);
- RNA_pointer_create(&sc->id, &RNA_SpaceGraphEditor, sipo, &spaceptr);
-
- /* 2D-Cursor */
- col = uiLayoutColumn(pa->layout, false);
- uiItemR(col, &spaceptr, "show_cursor", 0, NULL, ICON_NONE);
-
- sub = uiLayoutColumn(col, true);
- uiLayoutSetActive(sub, RNA_boolean_get(&spaceptr, "show_cursor"));
- uiItemO(sub, IFACE_("Cursor from Selection"), ICON_NONE, "GRAPH_OT_frame_jump");
-
- sub = uiLayoutColumn(col, true);
- uiLayoutSetActive(sub, RNA_boolean_get(&spaceptr, "show_cursor"));
- row = uiLayoutSplit(sub, 0.7f, true);
- if (sipo->mode == SIPO_MODE_DRIVERS)
- uiItemR(row, &spaceptr, "cursor_position_x", 0, IFACE_("Cursor X"), ICON_NONE);
- else
- uiItemR(row, &sceneptr, "frame_current", 0, IFACE_("Cursor X"), ICON_NONE);
- uiItemEnumO(row, "GRAPH_OT_snap", IFACE_("To Keys"), 0, "type", GRAPHKEYS_SNAP_CFRA);
-
- row = uiLayoutSplit(sub, 0.7f, true);
- uiItemR(row, &spaceptr, "cursor_position_y", 0, IFACE_("Cursor Y"), ICON_NONE);
- uiItemEnumO(row, "GRAPH_OT_snap", IFACE_("To Keys"), 0, "type", GRAPHKEYS_SNAP_VALUE);
+ bScreen *sc = CTX_wm_screen(C);
+ SpaceGraph *sipo = CTX_wm_space_graph(C);
+ Scene *scene = CTX_data_scene(C);
+ PointerRNA spaceptr, sceneptr;
+ uiLayout *col, *sub, *row;
+
+ /* get RNA pointers for use when creating the UI elements */
+ RNA_id_pointer_create(&scene->id, &sceneptr);
+ RNA_pointer_create(&sc->id, &RNA_SpaceGraphEditor, sipo, &spaceptr);
+
+ /* 2D-Cursor */
+ col = uiLayoutColumn(pa->layout, false);
+ uiItemR(col, &spaceptr, "show_cursor", 0, NULL, ICON_NONE);
+
+ sub = uiLayoutColumn(col, true);
+ uiLayoutSetActive(sub, RNA_boolean_get(&spaceptr, "show_cursor"));
+ uiItemO(sub, IFACE_("Cursor from Selection"), ICON_NONE, "GRAPH_OT_frame_jump");
+
+ sub = uiLayoutColumn(col, true);
+ uiLayoutSetActive(sub, RNA_boolean_get(&spaceptr, "show_cursor"));
+ row = uiLayoutSplit(sub, 0.7f, true);
+ if (sipo->mode == SIPO_MODE_DRIVERS)
+ uiItemR(row, &spaceptr, "cursor_position_x", 0, IFACE_("Cursor X"), ICON_NONE);
+ else
+ uiItemR(row, &sceneptr, "frame_current", 0, IFACE_("Cursor X"), ICON_NONE);
+ uiItemEnumO(row, "GRAPH_OT_snap", IFACE_("To Keys"), 0, "type", GRAPHKEYS_SNAP_CFRA);
+
+ row = uiLayoutSplit(sub, 0.7f, true);
+ uiItemR(row, &spaceptr, "cursor_position_y", 0, IFACE_("Cursor Y"), ICON_NONE);
+ uiItemEnumO(row, "GRAPH_OT_snap", IFACE_("To Keys"), 0, "type", GRAPHKEYS_SNAP_VALUE);
}
/* ******************* active F-Curve ************** */
static void graph_panel_properties(const bContext *C, Panel *pa)
{
- bAnimListElem *ale;
- FCurve *fcu;
- PointerRNA fcu_ptr;
- uiLayout *layout = pa->layout;
- uiLayout *col, *row, *sub;
- char name[256];
- int icon = 0;
-
- if (!graph_panel_context(C, &ale, &fcu))
- return;
-
- /* F-Curve pointer */
- RNA_pointer_create(ale->id, &RNA_FCurve, fcu, &fcu_ptr);
-
- /* user-friendly 'name' for F-Curve */
- col = uiLayoutColumn(layout, false);
- if (ale->type == ANIMTYPE_FCURVE) {
- /* get user-friendly name for F-Curve */
- icon = getname_anim_fcurve(name, ale->id, fcu);
- }
- else {
- /* NLA Control Curve, etc. */
- const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
-
- /* get name */
- if (acf && acf->name) {
- acf->name(ale, name);
- }
- else {
- strcpy(name, IFACE_("<invalid>"));
- icon = ICON_ERROR;
- }
-
- /* icon */
- if (ale->type == ANIMTYPE_NLACURVE)
- icon = ICON_NLA;
- }
- uiItemL(col, name, icon);
-
- /* RNA-Path Editing - only really should be enabled when things aren't working */
- col = uiLayoutColumn(layout, true);
- uiLayoutSetEnabled(col, (fcu->flag & FCURVE_DISABLED) != 0);
- uiItemR(col, &fcu_ptr, "data_path", 0, "", ICON_RNA);
- uiItemR(col, &fcu_ptr, "array_index", 0, NULL, ICON_NONE);
-
- /* color settings */
- col = uiLayoutColumn(layout, true);
- uiItemL(col, IFACE_("Display Color:"), ICON_NONE);
-
- row = uiLayoutRow(col, true);
- uiItemR(row, &fcu_ptr, "color_mode", 0, "", ICON_NONE);
-
- sub = uiLayoutRow(row, true);
- uiLayoutSetEnabled(sub, (fcu->color_mode == FCURVE_COLOR_CUSTOM));
- uiItemR(sub, &fcu_ptr, "color", 0, "", ICON_NONE);
-
- /* smoothing setting */
- col = uiLayoutColumn(layout, true);
- uiItemL(col, IFACE_("Auto Handle Smoothing:"), ICON_NONE);
- uiItemR(col, &fcu_ptr, "auto_smoothing", 0, "", ICON_NONE);
-
- MEM_freeN(ale);
+ bAnimListElem *ale;
+ FCurve *fcu;
+ PointerRNA fcu_ptr;
+ uiLayout *layout = pa->layout;
+ uiLayout *col, *row, *sub;
+ char name[256];
+ int icon = 0;
+
+ if (!graph_panel_context(C, &ale, &fcu))
+ return;
+
+ /* F-Curve pointer */
+ RNA_pointer_create(ale->id, &RNA_FCurve, fcu, &fcu_ptr);
+
+ /* user-friendly 'name' for F-Curve */
+ col = uiLayoutColumn(layout, false);
+ if (ale->type == ANIMTYPE_FCURVE) {
+ /* get user-friendly name for F-Curve */
+ icon = getname_anim_fcurve(name, ale->id, fcu);
+ }
+ else {
+ /* NLA Control Curve, etc. */
+ const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
+
+ /* get name */
+ if (acf && acf->name) {
+ acf->name(ale, name);
+ }
+ else {
+ strcpy(name, IFACE_("<invalid>"));
+ icon = ICON_ERROR;
+ }
+
+ /* icon */
+ if (ale->type == ANIMTYPE_NLACURVE)
+ icon = ICON_NLA;
+ }
+ uiItemL(col, name, icon);
+
+ /* RNA-Path Editing - only really should be enabled when things aren't working */
+ col = uiLayoutColumn(layout, true);
+ uiLayoutSetEnabled(col, (fcu->flag & FCURVE_DISABLED) != 0);
+ uiItemR(col, &fcu_ptr, "data_path", 0, "", ICON_RNA);
+ uiItemR(col, &fcu_ptr, "array_index", 0, NULL, ICON_NONE);
+
+ /* color settings */
+ col = uiLayoutColumn(layout, true);
+ uiItemL(col, IFACE_("Display Color:"), ICON_NONE);
+
+ row = uiLayoutRow(col, true);
+ uiItemR(row, &fcu_ptr, "color_mode", 0, "", ICON_NONE);
+
+ sub = uiLayoutRow(row, true);
+ uiLayoutSetEnabled(sub, (fcu->color_mode == FCURVE_COLOR_CUSTOM));
+ uiItemR(sub, &fcu_ptr, "color", 0, "", ICON_NONE);
+
+ /* smoothing setting */
+ col = uiLayoutColumn(layout, true);
+ uiItemL(col, IFACE_("Auto Handle Smoothing:"), ICON_NONE);
+ uiItemR(col, &fcu_ptr, "auto_smoothing", 0, "", ICON_NONE);
+
+ MEM_freeN(ale);
}
/* ******************* active Keyframe ************** */
@@ -213,66 +212,68 @@ static void graph_panel_properties(const bContext *C, Panel *pa)
/* get 'active' keyframe for panel editing */
static short get_active_fcurve_keyframe_edit(FCurve *fcu, BezTriple **bezt, BezTriple **prevbezt)
{
- BezTriple *b;
- int i;
-
- /* zero the pointers */
- *bezt = *prevbezt = NULL;
-
- /* sanity checks */
- if ((fcu->bezt == NULL) || (fcu->totvert == 0))
- return 0;
-
- /* find first selected keyframe for now, and call it the active one
- * - this is a reasonable assumption, given that whenever anyone
- * wants to edit numerically, there is likely to only be 1 vert selected
- */
- for (i = 0, b = fcu->bezt; i < fcu->totvert; i++, b++) {
- if (BEZT_ISSEL_ANY(b)) {
- /* found
- * - 'previous' is either the one before, of the keyframe itself (which is still fine)
- * XXX: we can just make this null instead if needed
- */
- *prevbezt = (i > 0) ? b - 1 : b;
- *bezt = b;
-
- return 1;
- }
- }
-
- /* not found */
- return 0;
+ BezTriple *b;
+ int i;
+
+ /* zero the pointers */
+ *bezt = *prevbezt = NULL;
+
+ /* sanity checks */
+ if ((fcu->bezt == NULL) || (fcu->totvert == 0))
+ return 0;
+
+ /* find first selected keyframe for now, and call it the active one
+ * - this is a reasonable assumption, given that whenever anyone
+ * wants to edit numerically, there is likely to only be 1 vert selected
+ */
+ for (i = 0, b = fcu->bezt; i < fcu->totvert; i++, b++) {
+ if (BEZT_ISSEL_ANY(b)) {
+ /* found
+ * - 'previous' is either the one before, of the keyframe itself (which is still fine)
+ * XXX: we can just make this null instead if needed
+ */
+ *prevbezt = (i > 0) ? b - 1 : b;
+ *bezt = b;
+
+ return 1;
+ }
+ }
+
+ /* not found */
+ return 0;
}
/* update callback for active keyframe properties - base updates stuff */
-static void graphedit_activekey_update_cb(bContext *UNUSED(C), void *fcu_ptr, void *UNUSED(bezt_ptr))
+static void graphedit_activekey_update_cb(bContext *UNUSED(C),
+ void *fcu_ptr,
+ void *UNUSED(bezt_ptr))
{
- FCurve *fcu = (FCurve *)fcu_ptr;
+ FCurve *fcu = (FCurve *)fcu_ptr;
- /* make sure F-Curve and its handles are still valid after this editing */
- sort_time_fcurve(fcu);
- calchandles_fcurve(fcu);
+ /* make sure F-Curve and its handles are still valid after this editing */
+ sort_time_fcurve(fcu);
+ calchandles_fcurve(fcu);
}
/* update callback for active keyframe properties - handle-editing wrapper */
static void graphedit_activekey_handles_cb(bContext *C, void *fcu_ptr, void *bezt_ptr)
{
- BezTriple *bezt = (BezTriple *)bezt_ptr;
-
- /* since editing the handles, make sure they're set to types which are receptive to editing
- * see transform_conversions.c :: createTransGraphEditData(), last step in second loop
- */
- if (ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM) && ELEM(bezt->h2, HD_AUTO, HD_AUTO_ANIM)) {
- /* by changing to aligned handles, these can now be moved... */
- bezt->h1 = HD_ALIGN;
- bezt->h2 = HD_ALIGN;
- }
- else {
- BKE_nurb_bezt_handle_test(bezt, true);
- }
-
- /* now call standard updates */
- graphedit_activekey_update_cb(C, fcu_ptr, bezt_ptr);
+ BezTriple *bezt = (BezTriple *)bezt_ptr;
+
+ /* since editing the handles, make sure they're set to types which are receptive to editing
+ * see transform_conversions.c :: createTransGraphEditData(), last step in second loop
+ */
+ if (ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM) && ELEM(bezt->h2, HD_AUTO, HD_AUTO_ANIM)) {
+ /* by changing to aligned handles, these can now be moved... */
+ bezt->h1 = HD_ALIGN;
+ bezt->h2 = HD_ALIGN;
+ }
+ else {
+ BKE_nurb_bezt_handle_test(bezt, true);
+ }
+
+ /* now call standard updates */
+ graphedit_activekey_update_cb(C, fcu_ptr, bezt_ptr);
}
/* update callback for editing coordinates of right handle in active keyframe properties
@@ -281,766 +282,943 @@ static void graphedit_activekey_handles_cb(bContext *C, void *fcu_ptr, void *bez
*/
static void graphedit_activekey_left_handle_coord_cb(bContext *C, void *fcu_ptr, void *bezt_ptr)
{
- BezTriple *bezt = (BezTriple *)bezt_ptr;
+ BezTriple *bezt = (BezTriple *)bezt_ptr;
- const char f1 = bezt->f1;
- const char f3 = bezt->f3;
+ const char f1 = bezt->f1;
+ const char f3 = bezt->f3;
- bezt->f1 |= SELECT;
- bezt->f3 &= ~SELECT;
+ bezt->f1 |= SELECT;
+ bezt->f3 &= ~SELECT;
- /* perform normal updates NOW */
- graphedit_activekey_handles_cb(C, fcu_ptr, bezt_ptr);
+ /* perform normal updates NOW */
+ graphedit_activekey_handles_cb(C, fcu_ptr, bezt_ptr);
- /* restore selection state so that no-one notices this hack */
- bezt->f1 = f1;
- bezt->f3 = f3;
+ /* restore selection state so that no-one notices this hack */
+ bezt->f1 = f1;
+ bezt->f3 = f3;
}
static void graphedit_activekey_right_handle_coord_cb(bContext *C, void *fcu_ptr, void *bezt_ptr)
{
- BezTriple *bezt = (BezTriple *)bezt_ptr;
+ BezTriple *bezt = (BezTriple *)bezt_ptr;
- /* original state of handle selection - to be restored after performing the recalculation */
- const char f1 = bezt->f1;
- const char f3 = bezt->f3;
+ /* original state of handle selection - to be restored after performing the recalculation */
+ const char f1 = bezt->f1;
+ const char f3 = bezt->f3;
- /* temporarily make it so that only the right handle is selected, so that updates go correctly
- * (i.e. it now acts as if we've just transforming the vert when it is selected by itself)
- */
- bezt->f1 &= ~SELECT;
- bezt->f3 |= SELECT;
+ /* temporarily make it so that only the right handle is selected, so that updates go correctly
+ * (i.e. it now acts as if we've just transforming the vert when it is selected by itself)
+ */
+ bezt->f1 &= ~SELECT;
+ bezt->f3 |= SELECT;
- /* perform normal updates NOW */
- graphedit_activekey_handles_cb(C, fcu_ptr, bezt_ptr);
+ /* perform normal updates NOW */
+ graphedit_activekey_handles_cb(C, fcu_ptr, bezt_ptr);
- /* restore selection state so that no-one notices this hack */
- bezt->f1 = f1;
- bezt->f3 = f3;
+ /* restore selection state so that no-one notices this hack */
+ bezt->f1 = f1;
+ bezt->f3 = f3;
}
static void graph_panel_key_properties(const bContext *C, Panel *pa)
{
- bAnimListElem *ale;
- FCurve *fcu;
- BezTriple *bezt, *prevbezt;
-
- uiLayout *layout = pa->layout;
- uiLayout *col;
- uiBlock *block;
-
- if (!graph_panel_context(C, &ale, &fcu))
- return;
-
- block = uiLayoutGetBlock(layout);
- /* UI_block_func_handle_set(block, do_graph_region_buttons, NULL); */
-
- /* only show this info if there are keyframes to edit */
- if (get_active_fcurve_keyframe_edit(fcu, &bezt, &prevbezt)) {
- PointerRNA bezt_ptr, id_ptr, fcu_prop_ptr;
- PropertyRNA *fcu_prop = NULL;
- uiBut *but;
- int unit = B_UNIT_NONE;
-
- /* RNA pointer to keyframe, to allow editing */
- RNA_pointer_create(ale->id, &RNA_Keyframe, bezt, &bezt_ptr);
-
- /* get property that F-Curve affects, for some unit-conversion magic */
- RNA_id_pointer_create(ale->id, &id_ptr);
- if (RNA_path_resolve_property(&id_ptr, fcu->rna_path, &fcu_prop_ptr, &fcu_prop)) {
- /* determine the unit for this property */
- unit = RNA_SUBTYPE_UNIT(RNA_property_subtype(fcu_prop));
- }
-
- /* interpolation */
- col = uiLayoutColumn(layout, false);
- if (fcu->flag & FCURVE_DISCRETE_VALUES) {
- uiLayout *split = uiLayoutSplit(col, 0.33f, true);
- uiItemL(split, IFACE_("Interpolation:"), ICON_NONE);
- uiItemL(split, IFACE_("None for Enum/Boolean"), ICON_IPO_CONSTANT);
- }
- else {
- uiItemR(col, &bezt_ptr, "interpolation", 0, NULL, ICON_NONE);
- }
-
- /* easing type */
- if (bezt->ipo > BEZT_IPO_BEZ)
- uiItemR(col, &bezt_ptr, "easing", 0, NULL, 0);
-
- /* easing extra */
- switch (bezt->ipo) {
- case BEZT_IPO_BACK:
- col = uiLayoutColumn(layout, 1);
- uiItemR(col, &bezt_ptr, "back", 0, NULL, 0);
- break;
- case BEZT_IPO_ELASTIC:
- col = uiLayoutColumn(layout, 1);
- uiItemR(col, &bezt_ptr, "amplitude", 0, NULL, 0);
- uiItemR(col, &bezt_ptr, "period", 0, NULL, 0);
- break;
- default:
- break;
- }
-
- /* numerical coordinate editing
- * - we use the button-versions of the calls so that we can attach special update handlers
- * and unit conversion magic that cannot be achieved using a purely RNA-approach
- */
- col = uiLayoutColumn(layout, true);
- /* keyframe itself */
- {
- uiItemL(col, IFACE_("Key:"), ICON_NONE);
-
- but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, IFACE_("Frame:"), 0, 0, UI_UNIT_X, UI_UNIT_Y,
- &bezt_ptr, "co", 0, 0, 0, -1, -1, NULL);
- UI_but_func_set(but, graphedit_activekey_update_cb, fcu, bezt);
-
- but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, IFACE_("Value:"), 0, 0, UI_UNIT_X, UI_UNIT_Y,
- &bezt_ptr, "co", 1, 0, 0, -1, -1, NULL);
- UI_but_func_set(but, graphedit_activekey_update_cb, fcu, bezt);
- UI_but_unit_type_set(but, unit);
- }
-
- /* previous handle - only if previous was Bezier interpolation */
- if ((prevbezt) && (prevbezt->ipo == BEZT_IPO_BEZ)) {
- uiItemL(col, IFACE_("Left Handle:"), ICON_NONE);
-
- but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, "X:", 0, 0, UI_UNIT_X, UI_UNIT_Y,
- &bezt_ptr, "handle_left", 0, 0, 0, -1, -1, NULL);
- UI_but_func_set(but, graphedit_activekey_left_handle_coord_cb, fcu, bezt);
-
- but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, "Y:", 0, 0, UI_UNIT_X, UI_UNIT_Y,
- &bezt_ptr, "handle_left", 1, 0, 0, -1, -1, NULL);
- UI_but_func_set(but, graphedit_activekey_left_handle_coord_cb, fcu, bezt);
- UI_but_unit_type_set(but, unit);
-
- /* XXX: with label? */
- but = uiDefButR(block, UI_BTYPE_MENU, B_REDR, NULL, 0, 0, UI_UNIT_X, UI_UNIT_Y,
- &bezt_ptr, "handle_left_type", 0, 0, 0, -1, -1, "Type of left handle");
- UI_but_func_set(but, graphedit_activekey_handles_cb, fcu, bezt);
- }
-
- /* next handle - only if current is Bezier interpolation */
- if (bezt->ipo == BEZT_IPO_BEZ) {
- /* NOTE: special update callbacks are needed on the coords here due to T39911 */
- uiItemL(col, IFACE_("Right Handle:"), ICON_NONE);
-
- but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, "X:", 0, 0, UI_UNIT_X, UI_UNIT_Y,
- &bezt_ptr, "handle_right", 0, 0, 0, -1, -1, NULL);
- UI_but_func_set(but, graphedit_activekey_right_handle_coord_cb, fcu, bezt);
-
- but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, "Y:", 0, 0, UI_UNIT_X, UI_UNIT_Y,
- &bezt_ptr, "handle_right", 1, 0, 0, -1, -1, NULL);
- UI_but_func_set(but, graphedit_activekey_right_handle_coord_cb, fcu, bezt);
- UI_but_unit_type_set(but, unit);
-
- /* XXX: with label? */
- but = uiDefButR(block, UI_BTYPE_MENU, B_REDR, NULL, 0, 0, UI_UNIT_X, UI_UNIT_Y,
- &bezt_ptr, "handle_right_type", 0, 0, 0, -1, -1, "Type of right handle");
- UI_but_func_set(but, graphedit_activekey_handles_cb, fcu, bezt);
- }
- }
- else {
- if ((fcu->bezt == NULL) && (fcu->modifiers.first)) {
- /* modifiers only - so no keyframes to be active */
- uiItemL(layout, IFACE_("F-Curve only has F-Modifiers"), ICON_NONE);
- uiItemL(layout, IFACE_("See Modifiers panel below"), ICON_INFO);
- }
- else if (fcu->fpt) {
- /* samples only */
- uiItemL(layout, IFACE_("F-Curve doesn't have any keyframes as it only contains sampled points"),
- ICON_NONE);
- }
- else
- uiItemL(layout, IFACE_("No active keyframe on F-Curve"), ICON_NONE);
- }
-
- MEM_freeN(ale);
+ bAnimListElem *ale;
+ FCurve *fcu;
+ BezTriple *bezt, *prevbezt;
+
+ uiLayout *layout = pa->layout;
+ uiLayout *col;
+ uiBlock *block;
+
+ if (!graph_panel_context(C, &ale, &fcu))
+ return;
+
+ block = uiLayoutGetBlock(layout);
+ /* UI_block_func_handle_set(block, do_graph_region_buttons, NULL); */
+
+ /* only show this info if there are keyframes to edit */
+ if (get_active_fcurve_keyframe_edit(fcu, &bezt, &prevbezt)) {
+ PointerRNA bezt_ptr, id_ptr, fcu_prop_ptr;
+ PropertyRNA *fcu_prop = NULL;
+ uiBut *but;
+ int unit = B_UNIT_NONE;
+
+ /* RNA pointer to keyframe, to allow editing */
+ RNA_pointer_create(ale->id, &RNA_Keyframe, bezt, &bezt_ptr);
+
+ /* get property that F-Curve affects, for some unit-conversion magic */
+ RNA_id_pointer_create(ale->id, &id_ptr);
+ if (RNA_path_resolve_property(&id_ptr, fcu->rna_path, &fcu_prop_ptr, &fcu_prop)) {
+ /* determine the unit for this property */
+ unit = RNA_SUBTYPE_UNIT(RNA_property_subtype(fcu_prop));
+ }
+
+ /* interpolation */
+ col = uiLayoutColumn(layout, false);
+ if (fcu->flag & FCURVE_DISCRETE_VALUES) {
+ uiLayout *split = uiLayoutSplit(col, 0.33f, true);
+ uiItemL(split, IFACE_("Interpolation:"), ICON_NONE);
+ uiItemL(split, IFACE_("None for Enum/Boolean"), ICON_IPO_CONSTANT);
+ }
+ else {
+ uiItemR(col, &bezt_ptr, "interpolation", 0, NULL, ICON_NONE);
+ }
+
+ /* easing type */
+ if (bezt->ipo > BEZT_IPO_BEZ)
+ uiItemR(col, &bezt_ptr, "easing", 0, NULL, 0);
+
+ /* easing extra */
+ switch (bezt->ipo) {
+ case BEZT_IPO_BACK:
+ col = uiLayoutColumn(layout, 1);
+ uiItemR(col, &bezt_ptr, "back", 0, NULL, 0);
+ break;
+ case BEZT_IPO_ELASTIC:
+ col = uiLayoutColumn(layout, 1);
+ uiItemR(col, &bezt_ptr, "amplitude", 0, NULL, 0);
+ uiItemR(col, &bezt_ptr, "period", 0, NULL, 0);
+ break;
+ default:
+ break;
+ }
+
+ /* numerical coordinate editing
+ * - we use the button-versions of the calls so that we can attach special update handlers
+ * and unit conversion magic that cannot be achieved using a purely RNA-approach
+ */
+ col = uiLayoutColumn(layout, true);
+ /* keyframe itself */
+ {
+ uiItemL(col, IFACE_("Key:"), ICON_NONE);
+
+ but = uiDefButR(block,
+ UI_BTYPE_NUM,
+ B_REDR,
+ IFACE_("Frame:"),
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &bezt_ptr,
+ "co",
+ 0,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+ UI_but_func_set(but, graphedit_activekey_update_cb, fcu, bezt);
+
+ but = uiDefButR(block,
+ UI_BTYPE_NUM,
+ B_REDR,
+ IFACE_("Value:"),
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &bezt_ptr,
+ "co",
+ 1,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+ UI_but_func_set(but, graphedit_activekey_update_cb, fcu, bezt);
+ UI_but_unit_type_set(but, unit);
+ }
+
+ /* previous handle - only if previous was Bezier interpolation */
+ if ((prevbezt) && (prevbezt->ipo == BEZT_IPO_BEZ)) {
+ uiItemL(col, IFACE_("Left Handle:"), ICON_NONE);
+
+ but = uiDefButR(block,
+ UI_BTYPE_NUM,
+ B_REDR,
+ "X:",
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &bezt_ptr,
+ "handle_left",
+ 0,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+ UI_but_func_set(but, graphedit_activekey_left_handle_coord_cb, fcu, bezt);
+
+ but = uiDefButR(block,
+ UI_BTYPE_NUM,
+ B_REDR,
+ "Y:",
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &bezt_ptr,
+ "handle_left",
+ 1,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+ UI_but_func_set(but, graphedit_activekey_left_handle_coord_cb, fcu, bezt);
+ UI_but_unit_type_set(but, unit);
+
+ /* XXX: with label? */
+ but = uiDefButR(block,
+ UI_BTYPE_MENU,
+ B_REDR,
+ NULL,
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &bezt_ptr,
+ "handle_left_type",
+ 0,
+ 0,
+ 0,
+ -1,
+ -1,
+ "Type of left handle");
+ UI_but_func_set(but, graphedit_activekey_handles_cb, fcu, bezt);
+ }
+
+ /* next handle - only if current is Bezier interpolation */
+ if (bezt->ipo == BEZT_IPO_BEZ) {
+ /* NOTE: special update callbacks are needed on the coords here due to T39911 */
+ uiItemL(col, IFACE_("Right Handle:"), ICON_NONE);
+
+ but = uiDefButR(block,
+ UI_BTYPE_NUM,
+ B_REDR,
+ "X:",
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &bezt_ptr,
+ "handle_right",
+ 0,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+ UI_but_func_set(but, graphedit_activekey_right_handle_coord_cb, fcu, bezt);
+
+ but = uiDefButR(block,
+ UI_BTYPE_NUM,
+ B_REDR,
+ "Y:",
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &bezt_ptr,
+ "handle_right",
+ 1,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+ UI_but_func_set(but, graphedit_activekey_right_handle_coord_cb, fcu, bezt);
+ UI_but_unit_type_set(but, unit);
+
+ /* XXX: with label? */
+ but = uiDefButR(block,
+ UI_BTYPE_MENU,
+ B_REDR,
+ NULL,
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &bezt_ptr,
+ "handle_right_type",
+ 0,
+ 0,
+ 0,
+ -1,
+ -1,
+ "Type of right handle");
+ UI_but_func_set(but, graphedit_activekey_handles_cb, fcu, bezt);
+ }
+ }
+ else {
+ if ((fcu->bezt == NULL) && (fcu->modifiers.first)) {
+ /* modifiers only - so no keyframes to be active */
+ uiItemL(layout, IFACE_("F-Curve only has F-Modifiers"), ICON_NONE);
+ uiItemL(layout, IFACE_("See Modifiers panel below"), ICON_INFO);
+ }
+ else if (fcu->fpt) {
+ /* samples only */
+ uiItemL(layout,
+ IFACE_("F-Curve doesn't have any keyframes as it only contains sampled points"),
+ ICON_NONE);
+ }
+ else
+ uiItemL(layout, IFACE_("No active keyframe on F-Curve"), ICON_NONE);
+ }
+
+ MEM_freeN(ale);
}
/* ******************* drivers ******************************** */
-#define B_IPO_DEPCHANGE 10
+#define B_IPO_DEPCHANGE 10
static void do_graph_region_driver_buttons(bContext *C, void *id_v, int event)
{
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
-
- switch (event) {
- case B_IPO_DEPCHANGE:
- {
- /* Was not actually run ever (NULL always passed as arg to this callback).
- * If needed again, will need to check how to pass both fcurve and ID... :/ */
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+
+ switch (event) {
+ case B_IPO_DEPCHANGE: {
+ /* Was not actually run ever (NULL always passed as arg to this callback).
+ * If needed again, will need to check how to pass both fcurve and ID... :/ */
#if 0
- /* force F-Curve & Driver to get re-evaluated (same as the old Update Dependencies) */
- FCurve *fcu = (FCurve *)fcu_v;
- ChannelDriver *driver = (fcu) ? fcu->driver : NULL;
-
- /* clear invalid flags */
- if (fcu) {
- fcu->flag &= ~FCURVE_DISABLED;
- driver->flag &= ~DRIVER_FLAG_INVALID;
- }
+ /* force F-Curve & Driver to get re-evaluated (same as the old Update Dependencies) */
+ FCurve *fcu = (FCurve *)fcu_v;
+ ChannelDriver *driver = (fcu) ? fcu->driver : NULL;
+
+ /* clear invalid flags */
+ if (fcu) {
+ fcu->flag &= ~FCURVE_DISABLED;
+ driver->flag &= ~DRIVER_FLAG_INVALID;
+ }
#endif
- ID *id = id_v;
- AnimData *adt = BKE_animdata_from_id(id);
-
- /* rebuild depsgraph for the new deps, and ensure COW copies get flushed. */
- DEG_relations_tag_update(bmain);
- DEG_id_tag_update_ex(bmain, id, ID_RECALC_COPY_ON_WRITE);
- if (adt != NULL) {
- if (adt->action != NULL) {
- DEG_id_tag_update_ex(bmain, &adt->action->id, ID_RECALC_COPY_ON_WRITE);
- }
- if (adt->tmpact != NULL) {
- DEG_id_tag_update_ex(bmain, &adt->tmpact->id, ID_RECALC_COPY_ON_WRITE);
- }
- }
-
- break;
- }
- }
-
- /* default for now */
- WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); // XXX could use better notifier
+ ID *id = id_v;
+ AnimData *adt = BKE_animdata_from_id(id);
+
+ /* rebuild depsgraph for the new deps, and ensure COW copies get flushed. */
+ DEG_relations_tag_update(bmain);
+ DEG_id_tag_update_ex(bmain, id, ID_RECALC_COPY_ON_WRITE);
+ if (adt != NULL) {
+ if (adt->action != NULL) {
+ DEG_id_tag_update_ex(bmain, &adt->action->id, ID_RECALC_COPY_ON_WRITE);
+ }
+ if (adt->tmpact != NULL) {
+ DEG_id_tag_update_ex(bmain, &adt->tmpact->id, ID_RECALC_COPY_ON_WRITE);
+ }
+ }
+
+ break;
+ }
+ }
+
+ /* default for now */
+ WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); // XXX could use better notifier
}
/* callback to add a target variable to the active driver */
static void driver_add_var_cb(bContext *C, void *driver_v, void *UNUSED(arg))
{
- ChannelDriver *driver = (ChannelDriver *)driver_v;
+ ChannelDriver *driver = (ChannelDriver *)driver_v;
- /* add a new variable */
- driver_add_new_variable(driver);
- ED_undo_push(C, "Add Driver Variable");
+ /* add a new variable */
+ driver_add_new_variable(driver);
+ ED_undo_push(C, "Add Driver Variable");
}
/* callback to remove target variable from active driver */
static void driver_delete_var_cb(bContext *C, void *driver_v, void *dvar_v)
{
- ChannelDriver *driver = (ChannelDriver *)driver_v;
- DriverVar *dvar = (DriverVar *)dvar_v;
+ ChannelDriver *driver = (ChannelDriver *)driver_v;
+ DriverVar *dvar = (DriverVar *)dvar_v;
- /* remove the active variable */
- driver_free_variable_ex(driver, dvar);
- ED_undo_push(C, "Delete Driver Variable");
+ /* remove the active variable */
+ driver_free_variable_ex(driver, dvar);
+ ED_undo_push(C, "Delete Driver Variable");
}
/* callback to report why a driver variable is invalid */
static void driver_dvar_invalid_name_query_cb(bContext *C, void *dvar_v, void *UNUSED(arg))
{
- uiPopupMenu *pup = UI_popup_menu_begin(C, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Invalid Variable Name"), ICON_NONE);
- uiLayout *layout = UI_popup_menu_layout(pup);
-
- DriverVar *dvar = (DriverVar *)dvar_v;
-
- if (dvar->flag & DVAR_FLAG_INVALID_EMPTY) {
- uiItemL(layout, "It cannot be left blank", ICON_ERROR);
- }
- if (dvar->flag & DVAR_FLAG_INVALID_START_NUM) {
- uiItemL(layout, "It cannot start with a number", ICON_ERROR);
- }
- if (dvar->flag & DVAR_FLAG_INVALID_START_CHAR) {
- uiItemL(layout,
- "It cannot start with a special character,"
- " including '$', '@', '!', '~', '+', '-', '_', '.', or ' '",
- ICON_NONE);
- }
- if (dvar->flag & DVAR_FLAG_INVALID_HAS_SPACE) {
- uiItemL(layout, "It cannot contain spaces (e.g. 'a space')", ICON_ERROR);
- }
- if (dvar->flag & DVAR_FLAG_INVALID_HAS_DOT) {
- uiItemL(layout, "It cannot contain dots (e.g. 'a.dot')", ICON_ERROR);
- }
- if (dvar->flag & DVAR_FLAG_INVALID_HAS_SPECIAL) {
- uiItemL(layout, "It cannot contain special (non-alphabetical/numeric) characters", ICON_ERROR);
- }
- if (dvar->flag & DVAR_FLAG_INVALID_PY_KEYWORD) {
- uiItemL(layout, "It cannot be a reserved keyword in Python", ICON_INFO);
- }
-
- UI_popup_menu_end(C, pup);
+ uiPopupMenu *pup = UI_popup_menu_begin(
+ C, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Invalid Variable Name"), ICON_NONE);
+ uiLayout *layout = UI_popup_menu_layout(pup);
+
+ DriverVar *dvar = (DriverVar *)dvar_v;
+
+ if (dvar->flag & DVAR_FLAG_INVALID_EMPTY) {
+ uiItemL(layout, "It cannot be left blank", ICON_ERROR);
+ }
+ if (dvar->flag & DVAR_FLAG_INVALID_START_NUM) {
+ uiItemL(layout, "It cannot start with a number", ICON_ERROR);
+ }
+ if (dvar->flag & DVAR_FLAG_INVALID_START_CHAR) {
+ uiItemL(layout,
+ "It cannot start with a special character,"
+ " including '$', '@', '!', '~', '+', '-', '_', '.', or ' '",
+ ICON_NONE);
+ }
+ if (dvar->flag & DVAR_FLAG_INVALID_HAS_SPACE) {
+ uiItemL(layout, "It cannot contain spaces (e.g. 'a space')", ICON_ERROR);
+ }
+ if (dvar->flag & DVAR_FLAG_INVALID_HAS_DOT) {
+ uiItemL(layout, "It cannot contain dots (e.g. 'a.dot')", ICON_ERROR);
+ }
+ if (dvar->flag & DVAR_FLAG_INVALID_HAS_SPECIAL) {
+ uiItemL(layout, "It cannot contain special (non-alphabetical/numeric) characters", ICON_ERROR);
+ }
+ if (dvar->flag & DVAR_FLAG_INVALID_PY_KEYWORD) {
+ uiItemL(layout, "It cannot be a reserved keyword in Python", ICON_INFO);
+ }
+
+ UI_popup_menu_end(C, pup);
}
/* callback to reset the driver's flags */
static void driver_update_flags_cb(bContext *UNUSED(C), void *fcu_v, void *UNUSED(arg))
{
- FCurve *fcu = (FCurve *)fcu_v;
- ChannelDriver *driver = fcu->driver;
+ FCurve *fcu = (FCurve *)fcu_v;
+ ChannelDriver *driver = fcu->driver;
- /* clear invalid flags */
- fcu->flag &= ~FCURVE_DISABLED;
- driver->flag &= ~DRIVER_FLAG_INVALID;
+ /* clear invalid flags */
+ fcu->flag &= ~FCURVE_DISABLED;
+ driver->flag &= ~DRIVER_FLAG_INVALID;
}
/* drivers panel poll */
static bool graph_panel_drivers_poll(const bContext *C, PanelType *UNUSED(pt))
{
- SpaceGraph *sipo = CTX_wm_space_graph(C);
+ SpaceGraph *sipo = CTX_wm_space_graph(C);
- if (sipo->mode != SIPO_MODE_DRIVERS)
- return 0;
+ if (sipo->mode != SIPO_MODE_DRIVERS)
+ return 0;
- return graph_panel_context(C, NULL, NULL);
+ return graph_panel_context(C, NULL, NULL);
}
/* settings for 'single property' driver variable type */
static void graph_panel_driverVar__singleProp(uiLayout *layout, ID *id, DriverVar *dvar)
{
- DriverTarget *dtar = &dvar->targets[0];
- PointerRNA dtar_ptr;
- uiLayout *row, *col;
-
- /* initialize RNA pointer to the target */
- RNA_pointer_create(id, &RNA_DriverTarget, dtar, &dtar_ptr);
-
- /* Target ID */
- row = uiLayoutRow(layout, false);
- uiLayoutSetRedAlert(row, ((dtar->flag & DTAR_FLAG_INVALID) && !dtar->id));
- uiTemplateAnyID(row, &dtar_ptr, "id", "id_type", IFACE_("Prop:"));
-
- /* Target Property */
- if (dtar->id) {
- PointerRNA root_ptr;
-
- /* get pointer for resolving the property selected */
- RNA_id_pointer_create(dtar->id, &root_ptr);
-
- /* rna path */
- col = uiLayoutColumn(layout, true);
- uiLayoutSetRedAlert(col, (dtar->flag & DTAR_FLAG_INVALID));
- uiTemplatePathBuilder(col, &dtar_ptr, "data_path", &root_ptr, IFACE_("Path"));
- }
+ DriverTarget *dtar = &dvar->targets[0];
+ PointerRNA dtar_ptr;
+ uiLayout *row, *col;
+
+ /* initialize RNA pointer to the target */
+ RNA_pointer_create(id, &RNA_DriverTarget, dtar, &dtar_ptr);
+
+ /* Target ID */
+ row = uiLayoutRow(layout, false);
+ uiLayoutSetRedAlert(row, ((dtar->flag & DTAR_FLAG_INVALID) && !dtar->id));
+ uiTemplateAnyID(row, &dtar_ptr, "id", "id_type", IFACE_("Prop:"));
+
+ /* Target Property */
+ if (dtar->id) {
+ PointerRNA root_ptr;
+
+ /* get pointer for resolving the property selected */
+ RNA_id_pointer_create(dtar->id, &root_ptr);
+
+ /* rna path */
+ col = uiLayoutColumn(layout, true);
+ uiLayoutSetRedAlert(col, (dtar->flag & DTAR_FLAG_INVALID));
+ uiTemplatePathBuilder(col, &dtar_ptr, "data_path", &root_ptr, IFACE_("Path"));
+ }
}
/* settings for 'rotation difference' driver variable type */
/* FIXME: 1) Must be same armature for both dtars, 2) Alignment issues... */
static void graph_panel_driverVar__rotDiff(uiLayout *layout, ID *id, DriverVar *dvar)
{
- DriverTarget *dtar = &dvar->targets[0];
- DriverTarget *dtar2 = &dvar->targets[1];
- Object *ob1 = (Object *)dtar->id;
- Object *ob2 = (Object *)dtar2->id;
- PointerRNA dtar_ptr, dtar2_ptr;
- uiLayout *col;
-
- /* initialize RNA pointer to the target */
- RNA_pointer_create(id, &RNA_DriverTarget, dtar, &dtar_ptr);
- RNA_pointer_create(id, &RNA_DriverTarget, dtar2, &dtar2_ptr);
-
- /* Object 1 */
- col = uiLayoutColumn(layout, true);
- uiLayoutSetRedAlert(col, (dtar->flag & DTAR_FLAG_INVALID)); /* XXX: per field... */
- uiItemR(col, &dtar_ptr, "id", 0, IFACE_("Object 1"), ICON_NONE);
-
- if (dtar->id && GS(dtar->id->name) == ID_OB && ob1->pose) {
- PointerRNA tar_ptr;
-
- RNA_pointer_create(dtar->id, &RNA_Pose, ob1->pose, &tar_ptr);
- uiItemPointerR(col, &dtar_ptr, "bone_target", &tar_ptr, "bones", "", ICON_BONE_DATA);
- }
-
- /* Object 2 */
- col = uiLayoutColumn(layout, true);
- uiLayoutSetRedAlert(col, (dtar2->flag & DTAR_FLAG_INVALID)); /* XXX: per field... */
- uiItemR(col, &dtar2_ptr, "id", 0, IFACE_("Object 2"), ICON_NONE);
-
- if (dtar2->id && GS(dtar2->id->name) == ID_OB && ob2->pose) {
- PointerRNA tar_ptr;
-
- RNA_pointer_create(dtar2->id, &RNA_Pose, ob2->pose, &tar_ptr);
- uiItemPointerR(col, &dtar2_ptr, "bone_target", &tar_ptr, "bones", "", ICON_BONE_DATA);
- }
+ DriverTarget *dtar = &dvar->targets[0];
+ DriverTarget *dtar2 = &dvar->targets[1];
+ Object *ob1 = (Object *)dtar->id;
+ Object *ob2 = (Object *)dtar2->id;
+ PointerRNA dtar_ptr, dtar2_ptr;
+ uiLayout *col;
+
+ /* initialize RNA pointer to the target */
+ RNA_pointer_create(id, &RNA_DriverTarget, dtar, &dtar_ptr);
+ RNA_pointer_create(id, &RNA_DriverTarget, dtar2, &dtar2_ptr);
+
+ /* Object 1 */
+ col = uiLayoutColumn(layout, true);
+ uiLayoutSetRedAlert(col, (dtar->flag & DTAR_FLAG_INVALID)); /* XXX: per field... */
+ uiItemR(col, &dtar_ptr, "id", 0, IFACE_("Object 1"), ICON_NONE);
+
+ if (dtar->id && GS(dtar->id->name) == ID_OB && ob1->pose) {
+ PointerRNA tar_ptr;
+
+ RNA_pointer_create(dtar->id, &RNA_Pose, ob1->pose, &tar_ptr);
+ uiItemPointerR(col, &dtar_ptr, "bone_target", &tar_ptr, "bones", "", ICON_BONE_DATA);
+ }
+
+ /* Object 2 */
+ col = uiLayoutColumn(layout, true);
+ uiLayoutSetRedAlert(col, (dtar2->flag & DTAR_FLAG_INVALID)); /* XXX: per field... */
+ uiItemR(col, &dtar2_ptr, "id", 0, IFACE_("Object 2"), ICON_NONE);
+
+ if (dtar2->id && GS(dtar2->id->name) == ID_OB && ob2->pose) {
+ PointerRNA tar_ptr;
+
+ RNA_pointer_create(dtar2->id, &RNA_Pose, ob2->pose, &tar_ptr);
+ uiItemPointerR(col, &dtar2_ptr, "bone_target", &tar_ptr, "bones", "", ICON_BONE_DATA);
+ }
}
/* settings for 'location difference' driver variable type */
static void graph_panel_driverVar__locDiff(uiLayout *layout, ID *id, DriverVar *dvar)
{
- DriverTarget *dtar = &dvar->targets[0];
- DriverTarget *dtar2 = &dvar->targets[1];
- Object *ob1 = (Object *)dtar->id;
- Object *ob2 = (Object *)dtar2->id;
- PointerRNA dtar_ptr, dtar2_ptr;
- uiLayout *col;
+ DriverTarget *dtar = &dvar->targets[0];
+ DriverTarget *dtar2 = &dvar->targets[1];
+ Object *ob1 = (Object *)dtar->id;
+ Object *ob2 = (Object *)dtar2->id;
+ PointerRNA dtar_ptr, dtar2_ptr;
+ uiLayout *col;
- /* initialize RNA pointer to the target */
- RNA_pointer_create(id, &RNA_DriverTarget, dtar, &dtar_ptr);
- RNA_pointer_create(id, &RNA_DriverTarget, dtar2, &dtar2_ptr);
+ /* initialize RNA pointer to the target */
+ RNA_pointer_create(id, &RNA_DriverTarget, dtar, &dtar_ptr);
+ RNA_pointer_create(id, &RNA_DriverTarget, dtar2, &dtar2_ptr);
- /* Object 1 */
- col = uiLayoutColumn(layout, true);
- uiLayoutSetRedAlert(col, (dtar->flag & DTAR_FLAG_INVALID)); /* XXX: per field... */
- uiItemR(col, &dtar_ptr, "id", 0, IFACE_("Object 1"), ICON_NONE);
+ /* Object 1 */
+ col = uiLayoutColumn(layout, true);
+ uiLayoutSetRedAlert(col, (dtar->flag & DTAR_FLAG_INVALID)); /* XXX: per field... */
+ uiItemR(col, &dtar_ptr, "id", 0, IFACE_("Object 1"), ICON_NONE);
- if (dtar->id && GS(dtar->id->name) == ID_OB && ob1->pose) {
- PointerRNA tar_ptr;
+ if (dtar->id && GS(dtar->id->name) == ID_OB && ob1->pose) {
+ PointerRNA tar_ptr;
- RNA_pointer_create(dtar->id, &RNA_Pose, ob1->pose, &tar_ptr);
- uiItemPointerR(col, &dtar_ptr, "bone_target", &tar_ptr, "bones", IFACE_("Bone"), ICON_BONE_DATA);
- }
+ RNA_pointer_create(dtar->id, &RNA_Pose, ob1->pose, &tar_ptr);
+ uiItemPointerR(
+ col, &dtar_ptr, "bone_target", &tar_ptr, "bones", IFACE_("Bone"), ICON_BONE_DATA);
+ }
- /* we can clear it again now - it's only needed when creating the ID/Bone fields */
- uiLayoutSetRedAlert(col, false);
+ /* we can clear it again now - it's only needed when creating the ID/Bone fields */
+ uiLayoutSetRedAlert(col, false);
- uiItemR(col, &dtar_ptr, "transform_space", 0, NULL, ICON_NONE);
+ uiItemR(col, &dtar_ptr, "transform_space", 0, NULL, ICON_NONE);
- /* Object 2 */
- col = uiLayoutColumn(layout, true);
- uiLayoutSetRedAlert(col, (dtar2->flag & DTAR_FLAG_INVALID)); /* XXX: per field... */
- uiItemR(col, &dtar2_ptr, "id", 0, IFACE_("Object 2"), ICON_NONE);
+ /* Object 2 */
+ col = uiLayoutColumn(layout, true);
+ uiLayoutSetRedAlert(col, (dtar2->flag & DTAR_FLAG_INVALID)); /* XXX: per field... */
+ uiItemR(col, &dtar2_ptr, "id", 0, IFACE_("Object 2"), ICON_NONE);
- if (dtar2->id && GS(dtar2->id->name) == ID_OB && ob2->pose) {
- PointerRNA tar_ptr;
+ if (dtar2->id && GS(dtar2->id->name) == ID_OB && ob2->pose) {
+ PointerRNA tar_ptr;
- RNA_pointer_create(dtar2->id, &RNA_Pose, ob2->pose, &tar_ptr);
- uiItemPointerR(col, &dtar2_ptr, "bone_target", &tar_ptr, "bones", IFACE_("Bone"), ICON_BONE_DATA);
- }
+ RNA_pointer_create(dtar2->id, &RNA_Pose, ob2->pose, &tar_ptr);
+ uiItemPointerR(
+ col, &dtar2_ptr, "bone_target", &tar_ptr, "bones", IFACE_("Bone"), ICON_BONE_DATA);
+ }
- /* we can clear it again now - it's only needed when creating the ID/Bone fields */
- uiLayoutSetRedAlert(col, false);
+ /* we can clear it again now - it's only needed when creating the ID/Bone fields */
+ uiLayoutSetRedAlert(col, false);
- uiItemR(col, &dtar2_ptr, "transform_space", 0, NULL, ICON_NONE);
+ uiItemR(col, &dtar2_ptr, "transform_space", 0, NULL, ICON_NONE);
}
/* settings for 'transform channel' driver variable type */
static void graph_panel_driverVar__transChan(uiLayout *layout, ID *id, DriverVar *dvar)
{
- DriverTarget *dtar = &dvar->targets[0];
- Object *ob = (Object *)dtar->id;
- PointerRNA dtar_ptr;
- uiLayout *col, *sub;
-
- /* initialize RNA pointer to the target */
- RNA_pointer_create(id, &RNA_DriverTarget, dtar, &dtar_ptr);
-
- /* properties */
- col = uiLayoutColumn(layout, true);
- uiLayoutSetRedAlert(col, (dtar->flag & DTAR_FLAG_INVALID)); /* XXX: per field... */
- uiItemR(col, &dtar_ptr, "id", 0, IFACE_("Object"), ICON_NONE);
-
- if (dtar->id && GS(dtar->id->name) == ID_OB && ob->pose) {
- PointerRNA tar_ptr;
-
- RNA_pointer_create(dtar->id, &RNA_Pose, ob->pose, &tar_ptr);
- uiItemPointerR(col, &dtar_ptr, "bone_target", &tar_ptr, "bones", IFACE_("Bone"), ICON_BONE_DATA);
- }
-
- sub = uiLayoutColumn(layout, true);
- uiItemR(sub, &dtar_ptr, "transform_type", 0, NULL, ICON_NONE);
- uiItemR(sub, &dtar_ptr, "transform_space", 0, IFACE_("Space"), ICON_NONE);
+ DriverTarget *dtar = &dvar->targets[0];
+ Object *ob = (Object *)dtar->id;
+ PointerRNA dtar_ptr;
+ uiLayout *col, *sub;
+
+ /* initialize RNA pointer to the target */
+ RNA_pointer_create(id, &RNA_DriverTarget, dtar, &dtar_ptr);
+
+ /* properties */
+ col = uiLayoutColumn(layout, true);
+ uiLayoutSetRedAlert(col, (dtar->flag & DTAR_FLAG_INVALID)); /* XXX: per field... */
+ uiItemR(col, &dtar_ptr, "id", 0, IFACE_("Object"), ICON_NONE);
+
+ if (dtar->id && GS(dtar->id->name) == ID_OB && ob->pose) {
+ PointerRNA tar_ptr;
+
+ RNA_pointer_create(dtar->id, &RNA_Pose, ob->pose, &tar_ptr);
+ uiItemPointerR(
+ col, &dtar_ptr, "bone_target", &tar_ptr, "bones", IFACE_("Bone"), ICON_BONE_DATA);
+ }
+
+ sub = uiLayoutColumn(layout, true);
+ uiItemR(sub, &dtar_ptr, "transform_type", 0, NULL, ICON_NONE);
+ uiItemR(sub, &dtar_ptr, "transform_space", 0, IFACE_("Space"), ICON_NONE);
}
/* ----------------------------------------------------------------- */
-
/* property driven by the driver - duplicates Active FCurve, but useful for clarity */
static void graph_draw_driven_property_panel(uiLayout *layout, ID *id, FCurve *fcu)
{
- PointerRNA fcu_ptr;
- uiLayout *row;
- char name[256];
- int icon = 0;
+ PointerRNA fcu_ptr;
+ uiLayout *row;
+ char name[256];
+ int icon = 0;
- /* F-Curve pointer */
- RNA_pointer_create(id, &RNA_FCurve, fcu, &fcu_ptr);
+ /* F-Curve pointer */
+ RNA_pointer_create(id, &RNA_FCurve, fcu, &fcu_ptr);
- /* get user-friendly 'name' for F-Curve */
- icon = getname_anim_fcurve(name, id, fcu);
+ /* get user-friendly 'name' for F-Curve */
+ icon = getname_anim_fcurve(name, id, fcu);
- /* panel layout... */
- row = uiLayoutRow(layout, true);
- uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_LEFT);
+ /* panel layout... */
+ row = uiLayoutRow(layout, true);
+ uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_LEFT);
- /* -> user friendly 'name' for datablock that owns F-Curve */
- /* XXX: Actually, we may need the datablock icons only... (e.g. right now will show bone for bone props) */
- uiItemL(row, id->name + 2, icon);
+ /* -> user friendly 'name' for datablock that owns F-Curve */
+ /* XXX: Actually, we may need the datablock icons only... (e.g. right now will show bone for bone props) */
+ uiItemL(row, id->name + 2, icon);
- /* -> user friendly 'name' for F-Curve/driver target */
- uiItemL(row, "", ICON_SMALL_TRI_RIGHT_VEC);
- uiItemL(row, name, ICON_RNA);
+ /* -> user friendly 'name' for F-Curve/driver target */
+ uiItemL(row, "", ICON_SMALL_TRI_RIGHT_VEC);
+ uiItemL(row, name, ICON_RNA);
}
/* UI properties panel layout for driver settings - shared for Drivers Editor and for */
-static void graph_draw_driver_settings_panel(uiLayout *layout, ID *id, FCurve *fcu, const bool is_popover)
+static void graph_draw_driver_settings_panel(uiLayout *layout,
+ ID *id,
+ FCurve *fcu,
+ const bool is_popover)
{
- ChannelDriver *driver = fcu->driver;
- DriverVar *dvar;
-
- PointerRNA driver_ptr;
- uiLayout *col, *row;
- uiBlock *block;
- uiBut *but;
-
- /* set event handler for panel */
- block = uiLayoutGetBlock(layout);
- UI_block_func_handle_set(block, do_graph_region_driver_buttons, id);
-
- /* driver-level settings - type, expressions, and errors */
- RNA_pointer_create(id, &RNA_Driver, driver, &driver_ptr);
-
- col = uiLayoutColumn(layout, true);
- block = uiLayoutGetBlock(col);
- uiItemR(col, &driver_ptr, "type", 0, NULL, ICON_NONE);
-
- {
- char valBuf[32];
-
- /* value of driver */
- row = uiLayoutRow(col, true);
- uiItemL(row, IFACE_("Driver Value:"), ICON_NONE);
- BLI_snprintf(valBuf, sizeof(valBuf), "%.3f", driver->curval);
- uiItemL(row, valBuf, ICON_NONE);
- }
-
- uiItemS(layout);
- uiItemS(layout);
-
- /* show expression box if doing scripted drivers, and/or error messages when invalid drivers exist */
- if (driver->type == DRIVER_TYPE_PYTHON) {
- bool bpy_data_expr_error = (strstr(driver->expression, "bpy.data.") != NULL);
- bool bpy_ctx_expr_error = (strstr(driver->expression, "bpy.context.") != NULL);
-
- /* expression */
- /* TODO: "Show syntax hints" button */
- col = uiLayoutColumn(layout, true);
- block = uiLayoutGetBlock(col);
-
- uiItemL(col, IFACE_("Expression:"), ICON_NONE);
- uiItemR(col, &driver_ptr, "expression", 0, "", ICON_NONE);
- uiItemR(col, &driver_ptr, "use_self", 0, NULL, ICON_NONE);
-
- /* errors? */
- col = uiLayoutColumn(layout, true);
- block = uiLayoutGetBlock(col);
-
- if (driver->flag & DRIVER_FLAG_INVALID) {
- uiItemL(col, IFACE_("ERROR: Invalid Python expression"), ICON_CANCEL);
- }
- else if (!BKE_driver_has_simple_expression(driver)) {
- if ((G.f & G_FLAG_SCRIPT_AUTOEXEC) == 0) {
- /* TODO: Add button to enable? */
- uiItemL(col, IFACE_("WARNING: Python expressions limited for security"), ICON_ERROR);
- }
- else {
- uiItemL(col, IFACE_("Slow Python expression"), ICON_INFO);
- }
- }
-
- /* Explicit bpy-references are evil. Warn about these to prevent errors */
- /* TODO: put these in a box? */
- if (bpy_data_expr_error || bpy_ctx_expr_error) {
- uiItemL(col, IFACE_("WARNING: Driver expression may not work correctly"), ICON_HELP);
-
- if (bpy_data_expr_error) {
- uiItemL(col, IFACE_("TIP: Use variables instead of bpy.data paths (see below)"), ICON_ERROR);
- }
- if (bpy_ctx_expr_error) {
- uiItemL(col, IFACE_("TIP: bpy.context is not safe for renderfarm usage"), ICON_ERROR);
- }
- }
- }
- else {
- /* errors? */
- col = uiLayoutColumn(layout, true);
- block = uiLayoutGetBlock(col);
-
- if (driver->flag & DRIVER_FLAG_INVALID)
- uiItemL(col, IFACE_("ERROR: Invalid target channel(s)"), ICON_ERROR);
-
- /* Warnings about a lack of variables
- * NOTE: The lack of variables is generally a bad thing, since it indicates
- * that the driver doesn't work at all. This particular scenario arises
- * primarily when users mistakenly try to use drivers for procedural
- * property animation
- */
- if (BLI_listbase_is_empty(&driver->variables)) {
- uiItemL(col, IFACE_("ERROR: Driver is useless without any inputs"), ICON_ERROR);
-
- if (!BLI_listbase_is_empty(&fcu->modifiers)) {
- uiItemL(col, IFACE_("TIP: Use F-Curves for procedural animation instead"), ICON_INFO);
- uiItemL(col, IFACE_("F-Modifiers can generate curves for those too"), ICON_INFO);
- }
- }
- }
-
- uiItemS(layout);
-
- /* add/copy/paste driver variables */
- if (is_popover) {
- /* add driver variable - add blank */
- row = uiLayoutRow(layout, true);
- block = uiLayoutGetBlock(row);
- but = uiDefIconTextBut(block, UI_BTYPE_BUT, B_IPO_DEPCHANGE, ICON_ADD, IFACE_("Add Input Variable"),
- 0, 0, 10 * UI_UNIT_X, UI_UNIT_Y,
- NULL, 0.0, 0.0, 0, 0,
- TIP_("Add a Driver Variable to keep track an input used by the driver"));
- UI_but_func_set(but, driver_add_var_cb, driver, NULL);
-
- /* add driver variable - add using eyedropper */
- /* XXX: will this operator work like this? */
- uiItemO(row, "", ICON_EYEDROPPER, "UI_OT_eyedropper_driver");
- }
- else {
- /* add driver variable */
- row = uiLayoutRow(layout, false);
- block = uiLayoutGetBlock(row);
- but = uiDefIconTextBut(block, UI_BTYPE_BUT, B_IPO_DEPCHANGE, ICON_ADD, IFACE_("Add Input Variable"),
- 0, 0, 10 * UI_UNIT_X, UI_UNIT_Y,
- NULL, 0.0, 0.0, 0, 0,
- TIP_("Driver variables ensure that all dependencies will be accounted for, ensuring that drivers will update correctly"));
- UI_but_func_set(but, driver_add_var_cb, driver, NULL);
-
- /* copy/paste (as sub-row) */
- row = uiLayoutRow(row, true);
- block = uiLayoutGetBlock(row);
-
- uiItemO(row, "", ICON_COPYDOWN, "GRAPH_OT_driver_variables_copy");
- uiItemO(row, "", ICON_PASTEDOWN, "GRAPH_OT_driver_variables_paste");
- }
-
- /* loop over targets, drawing them */
- for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
- PointerRNA dvar_ptr;
- uiLayout *box;
- uiLayout *subrow, *sub;
-
- /* sub-layout column for this variable's settings */
- col = uiLayoutColumn(layout, true);
-
- /* 1) header panel */
- box = uiLayoutBox(col);
- RNA_pointer_create(id, &RNA_DriverVariable, dvar, &dvar_ptr);
-
- row = uiLayoutRow(box, false);
- block = uiLayoutGetBlock(row);
-
- /* 1.1) variable type and name */
- subrow = uiLayoutRow(row, true);
-
- /* 1.1.1) variable type */
-
- /* HACK: special group just for the enum,
- * otherwise we get ugly layout with text included too... */
- sub = uiLayoutRow(subrow, true);
-
- uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_LEFT);
-
- uiItemR(sub, &dvar_ptr, "type", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
-
- /* 1.1.2) variable name */
-
- /* HACK: special group to counteract the effects of the previous enum,
- * which now pushes everything too far right */
- sub = uiLayoutRow(subrow, true);
-
- uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_EXPAND);
-
- uiItemR(sub, &dvar_ptr, "name", 0, "", ICON_NONE);
-
- /* 1.2) invalid name? */
- UI_block_emboss_set(block, UI_EMBOSS_NONE);
-
- if (dvar->flag & DVAR_FLAG_INVALID_NAME) {
- but = uiDefIconBut(block, UI_BTYPE_BUT, B_IPO_DEPCHANGE, ICON_ERROR, 290, 0, UI_UNIT_X, UI_UNIT_Y,
- NULL, 0.0, 0.0, 0.0, 0.0, IFACE_("Invalid variable name, click here for details"));
- UI_but_func_set(but, driver_dvar_invalid_name_query_cb, dvar, NULL); // XXX: reports?
- }
-
- /* 1.3) remove button */
- but = uiDefIconBut(block, UI_BTYPE_BUT, B_IPO_DEPCHANGE, ICON_X, 290, 0, UI_UNIT_X, UI_UNIT_Y,
- NULL, 0.0, 0.0, 0.0, 0.0, IFACE_("Delete target variable"));
- UI_but_func_set(but, driver_delete_var_cb, driver, dvar);
- UI_block_emboss_set(block, UI_EMBOSS);
-
-
- /* 2) variable type settings */
- box = uiLayoutBox(col);
- /* controls to draw depends on the type of variable */
- switch (dvar->type) {
- case DVAR_TYPE_SINGLE_PROP: /* single property */
- graph_panel_driverVar__singleProp(box, id, dvar);
- break;
- case DVAR_TYPE_ROT_DIFF: /* rotational difference */
- graph_panel_driverVar__rotDiff(box, id, dvar);
- break;
- case DVAR_TYPE_LOC_DIFF: /* location difference */
- graph_panel_driverVar__locDiff(box, id, dvar);
- break;
- case DVAR_TYPE_TRANSFORM_CHAN: /* transform channel */
- graph_panel_driverVar__transChan(box, id, dvar);
- break;
- }
-
- /* 3) value of variable */
- {
- char valBuf[32];
-
- box = uiLayoutBox(col);
- row = uiLayoutRow(box, true);
- uiItemL(row, IFACE_("Value:"), ICON_NONE);
-
- if ((dvar->type == DVAR_TYPE_ROT_DIFF) ||
- (dvar->type == DVAR_TYPE_TRANSFORM_CHAN &&
- dvar->targets[0].transChan >= DTAR_TRANSCHAN_ROTX &&
- dvar->targets[0].transChan < DTAR_TRANSCHAN_SCALEX))
- {
- BLI_snprintf(valBuf, sizeof(valBuf), "%.3f (%4.1f°)", dvar->curval, RAD2DEGF(dvar->curval));
- }
- else {
- BLI_snprintf(valBuf, sizeof(valBuf), "%.3f", dvar->curval);
- }
-
- uiItemL(row, valBuf, ICON_NONE);
- }
- }
-
- uiItemS(layout);
- uiItemS(layout);
-
- /* XXX: This should become redundant. But sometimes the flushing fails,
- * so keep this around for a while longer as a "last resort" */
- row = uiLayoutRow(layout, true);
- block = uiLayoutGetBlock(row);
- but = uiDefIconTextBut(block, UI_BTYPE_BUT, B_IPO_DEPCHANGE, ICON_FILE_REFRESH, IFACE_("Update Dependencies"),
- 0, 0, 10 * UI_UNIT_X, UI_UNIT_Y,
- NULL, 0.0, 0.0, 0, 0,
- TIP_("Force updates of dependencies - Only use this if drivers are not updating correctly"));
- UI_but_func_set(but, driver_update_flags_cb, fcu, NULL);
+ ChannelDriver *driver = fcu->driver;
+ DriverVar *dvar;
+
+ PointerRNA driver_ptr;
+ uiLayout *col, *row;
+ uiBlock *block;
+ uiBut *but;
+
+ /* set event handler for panel */
+ block = uiLayoutGetBlock(layout);
+ UI_block_func_handle_set(block, do_graph_region_driver_buttons, id);
+
+ /* driver-level settings - type, expressions, and errors */
+ RNA_pointer_create(id, &RNA_Driver, driver, &driver_ptr);
+
+ col = uiLayoutColumn(layout, true);
+ block = uiLayoutGetBlock(col);
+ uiItemR(col, &driver_ptr, "type", 0, NULL, ICON_NONE);
+
+ {
+ char valBuf[32];
+
+ /* value of driver */
+ row = uiLayoutRow(col, true);
+ uiItemL(row, IFACE_("Driver Value:"), ICON_NONE);
+ BLI_snprintf(valBuf, sizeof(valBuf), "%.3f", driver->curval);
+ uiItemL(row, valBuf, ICON_NONE);
+ }
+
+ uiItemS(layout);
+ uiItemS(layout);
+
+ /* show expression box if doing scripted drivers, and/or error messages when invalid drivers exist */
+ if (driver->type == DRIVER_TYPE_PYTHON) {
+ bool bpy_data_expr_error = (strstr(driver->expression, "bpy.data.") != NULL);
+ bool bpy_ctx_expr_error = (strstr(driver->expression, "bpy.context.") != NULL);
+
+ /* expression */
+ /* TODO: "Show syntax hints" button */
+ col = uiLayoutColumn(layout, true);
+ block = uiLayoutGetBlock(col);
+
+ uiItemL(col, IFACE_("Expression:"), ICON_NONE);
+ uiItemR(col, &driver_ptr, "expression", 0, "", ICON_NONE);
+ uiItemR(col, &driver_ptr, "use_self", 0, NULL, ICON_NONE);
+
+ /* errors? */
+ col = uiLayoutColumn(layout, true);
+ block = uiLayoutGetBlock(col);
+
+ if (driver->flag & DRIVER_FLAG_INVALID) {
+ uiItemL(col, IFACE_("ERROR: Invalid Python expression"), ICON_CANCEL);
+ }
+ else if (!BKE_driver_has_simple_expression(driver)) {
+ if ((G.f & G_FLAG_SCRIPT_AUTOEXEC) == 0) {
+ /* TODO: Add button to enable? */
+ uiItemL(col, IFACE_("WARNING: Python expressions limited for security"), ICON_ERROR);
+ }
+ else {
+ uiItemL(col, IFACE_("Slow Python expression"), ICON_INFO);
+ }
+ }
+
+ /* Explicit bpy-references are evil. Warn about these to prevent errors */
+ /* TODO: put these in a box? */
+ if (bpy_data_expr_error || bpy_ctx_expr_error) {
+ uiItemL(col, IFACE_("WARNING: Driver expression may not work correctly"), ICON_HELP);
+
+ if (bpy_data_expr_error) {
+ uiItemL(
+ col, IFACE_("TIP: Use variables instead of bpy.data paths (see below)"), ICON_ERROR);
+ }
+ if (bpy_ctx_expr_error) {
+ uiItemL(col, IFACE_("TIP: bpy.context is not safe for renderfarm usage"), ICON_ERROR);
+ }
+ }
+ }
+ else {
+ /* errors? */
+ col = uiLayoutColumn(layout, true);
+ block = uiLayoutGetBlock(col);
+
+ if (driver->flag & DRIVER_FLAG_INVALID)
+ uiItemL(col, IFACE_("ERROR: Invalid target channel(s)"), ICON_ERROR);
+
+ /* Warnings about a lack of variables
+ * NOTE: The lack of variables is generally a bad thing, since it indicates
+ * that the driver doesn't work at all. This particular scenario arises
+ * primarily when users mistakenly try to use drivers for procedural
+ * property animation
+ */
+ if (BLI_listbase_is_empty(&driver->variables)) {
+ uiItemL(col, IFACE_("ERROR: Driver is useless without any inputs"), ICON_ERROR);
+
+ if (!BLI_listbase_is_empty(&fcu->modifiers)) {
+ uiItemL(col, IFACE_("TIP: Use F-Curves for procedural animation instead"), ICON_INFO);
+ uiItemL(col, IFACE_("F-Modifiers can generate curves for those too"), ICON_INFO);
+ }
+ }
+ }
+
+ uiItemS(layout);
+
+ /* add/copy/paste driver variables */
+ if (is_popover) {
+ /* add driver variable - add blank */
+ row = uiLayoutRow(layout, true);
+ block = uiLayoutGetBlock(row);
+ but = uiDefIconTextBut(
+ block,
+ UI_BTYPE_BUT,
+ B_IPO_DEPCHANGE,
+ ICON_ADD,
+ IFACE_("Add Input Variable"),
+ 0,
+ 0,
+ 10 * UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0,
+ 0,
+ TIP_("Add a Driver Variable to keep track an input used by the driver"));
+ UI_but_func_set(but, driver_add_var_cb, driver, NULL);
+
+ /* add driver variable - add using eyedropper */
+ /* XXX: will this operator work like this? */
+ uiItemO(row, "", ICON_EYEDROPPER, "UI_OT_eyedropper_driver");
+ }
+ else {
+ /* add driver variable */
+ row = uiLayoutRow(layout, false);
+ block = uiLayoutGetBlock(row);
+ but = uiDefIconTextBut(block,
+ UI_BTYPE_BUT,
+ B_IPO_DEPCHANGE,
+ ICON_ADD,
+ IFACE_("Add Input Variable"),
+ 0,
+ 0,
+ 10 * UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0,
+ 0,
+ TIP_("Driver variables ensure that all dependencies will be accounted "
+ "for, ensuring that drivers will update correctly"));
+ UI_but_func_set(but, driver_add_var_cb, driver, NULL);
+
+ /* copy/paste (as sub-row) */
+ row = uiLayoutRow(row, true);
+ block = uiLayoutGetBlock(row);
+
+ uiItemO(row, "", ICON_COPYDOWN, "GRAPH_OT_driver_variables_copy");
+ uiItemO(row, "", ICON_PASTEDOWN, "GRAPH_OT_driver_variables_paste");
+ }
+
+ /* loop over targets, drawing them */
+ for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
+ PointerRNA dvar_ptr;
+ uiLayout *box;
+ uiLayout *subrow, *sub;
+
+ /* sub-layout column for this variable's settings */
+ col = uiLayoutColumn(layout, true);
+
+ /* 1) header panel */
+ box = uiLayoutBox(col);
+ RNA_pointer_create(id, &RNA_DriverVariable, dvar, &dvar_ptr);
+
+ row = uiLayoutRow(box, false);
+ block = uiLayoutGetBlock(row);
+
+ /* 1.1) variable type and name */
+ subrow = uiLayoutRow(row, true);
+
+ /* 1.1.1) variable type */
+
+ /* HACK: special group just for the enum,
+ * otherwise we get ugly layout with text included too... */
+ sub = uiLayoutRow(subrow, true);
+
+ uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_LEFT);
+
+ uiItemR(sub, &dvar_ptr, "type", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
+
+ /* 1.1.2) variable name */
+
+ /* HACK: special group to counteract the effects of the previous enum,
+ * which now pushes everything too far right */
+ sub = uiLayoutRow(subrow, true);
+
+ uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_EXPAND);
+
+ uiItemR(sub, &dvar_ptr, "name", 0, "", ICON_NONE);
+
+ /* 1.2) invalid name? */
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+
+ if (dvar->flag & DVAR_FLAG_INVALID_NAME) {
+ but = uiDefIconBut(block,
+ UI_BTYPE_BUT,
+ B_IPO_DEPCHANGE,
+ ICON_ERROR,
+ 290,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ IFACE_("Invalid variable name, click here for details"));
+ UI_but_func_set(but, driver_dvar_invalid_name_query_cb, dvar, NULL); // XXX: reports?
+ }
+
+ /* 1.3) remove button */
+ but = uiDefIconBut(block,
+ UI_BTYPE_BUT,
+ B_IPO_DEPCHANGE,
+ ICON_X,
+ 290,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ IFACE_("Delete target variable"));
+ UI_but_func_set(but, driver_delete_var_cb, driver, dvar);
+ UI_block_emboss_set(block, UI_EMBOSS);
+
+ /* 2) variable type settings */
+ box = uiLayoutBox(col);
+ /* controls to draw depends on the type of variable */
+ switch (dvar->type) {
+ case DVAR_TYPE_SINGLE_PROP: /* single property */
+ graph_panel_driverVar__singleProp(box, id, dvar);
+ break;
+ case DVAR_TYPE_ROT_DIFF: /* rotational difference */
+ graph_panel_driverVar__rotDiff(box, id, dvar);
+ break;
+ case DVAR_TYPE_LOC_DIFF: /* location difference */
+ graph_panel_driverVar__locDiff(box, id, dvar);
+ break;
+ case DVAR_TYPE_TRANSFORM_CHAN: /* transform channel */
+ graph_panel_driverVar__transChan(box, id, dvar);
+ break;
+ }
+
+ /* 3) value of variable */
+ {
+ char valBuf[32];
+
+ box = uiLayoutBox(col);
+ row = uiLayoutRow(box, true);
+ uiItemL(row, IFACE_("Value:"), ICON_NONE);
+
+ if ((dvar->type == DVAR_TYPE_ROT_DIFF) ||
+ (dvar->type == DVAR_TYPE_TRANSFORM_CHAN &&
+ dvar->targets[0].transChan >= DTAR_TRANSCHAN_ROTX &&
+ dvar->targets[0].transChan < DTAR_TRANSCHAN_SCALEX)) {
+ BLI_snprintf(
+ valBuf, sizeof(valBuf), "%.3f (%4.1f°)", dvar->curval, RAD2DEGF(dvar->curval));
+ }
+ else {
+ BLI_snprintf(valBuf, sizeof(valBuf), "%.3f", dvar->curval);
+ }
+
+ uiItemL(row, valBuf, ICON_NONE);
+ }
+ }
+
+ uiItemS(layout);
+ uiItemS(layout);
+
+ /* XXX: This should become redundant. But sometimes the flushing fails,
+ * so keep this around for a while longer as a "last resort" */
+ row = uiLayoutRow(layout, true);
+ block = uiLayoutGetBlock(row);
+ but = uiDefIconTextBut(
+ block,
+ UI_BTYPE_BUT,
+ B_IPO_DEPCHANGE,
+ ICON_FILE_REFRESH,
+ IFACE_("Update Dependencies"),
+ 0,
+ 0,
+ 10 * UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0,
+ 0,
+ TIP_("Force updates of dependencies - Only use this if drivers are not updating correctly"));
+ UI_but_func_set(but, driver_update_flags_cb, fcu, NULL);
}
/* ----------------------------------------------------------------- */
-
/* panel to show property driven by the driver (in Drivers Editor) - duplicates Active FCurve, but useful for clarity */
static void graph_panel_driven_property(const bContext *C, Panel *pa)
{
- bAnimListElem *ale;
- FCurve *fcu;
+ bAnimListElem *ale;
+ FCurve *fcu;
- if (!graph_panel_context(C, &ale, &fcu))
- return;
+ if (!graph_panel_context(C, &ale, &fcu))
+ return;
- graph_draw_driven_property_panel(pa->layout, ale->id, fcu);
+ graph_draw_driven_property_panel(pa->layout, ale->id, fcu);
- MEM_freeN(ale);
+ MEM_freeN(ale);
}
/* driver settings for active F-Curve
* (only for 'Drivers' mode in Graph Editor, i.e. the full "Drivers Editor") */
static void graph_panel_drivers(const bContext *C, Panel *pa)
{
- bAnimListElem *ale;
- FCurve *fcu;
+ bAnimListElem *ale;
+ FCurve *fcu;
- /* Get settings from context */
- if (!graph_panel_context(C, &ale, &fcu))
- return;
+ /* Get settings from context */
+ if (!graph_panel_context(C, &ale, &fcu))
+ return;
- graph_draw_driver_settings_panel(pa->layout, ale->id, fcu, false);
+ graph_draw_driver_settings_panel(pa->layout, ale->id, fcu, false);
- /* cleanup */
- MEM_freeN(ale);
+ /* cleanup */
+ MEM_freeN(ale);
}
/* ----------------------------------------------------------------- */
@@ -1048,205 +1226,206 @@ static void graph_panel_drivers(const bContext *C, Panel *pa)
/* poll to make this not show up in the graph editor, as this is only to be used as a popup elsewhere */
static bool graph_panel_drivers_popover_poll(const bContext *C, PanelType *UNUSED(pt))
{
- return ED_operator_graphedit_active((bContext *)C) == false;
+ return ED_operator_graphedit_active((bContext *)C) == false;
}
/* popover panel for driver editing anywhere in ui */
static void graph_panel_drivers_popover(const bContext *C, Panel *pa)
{
- uiLayout *layout = pa->layout;
-
- PointerRNA ptr = {{NULL}};
- PropertyRNA *prop = NULL;
- int index = -1;
- uiBut *but = NULL;
-
- /* Get active property to show driver properties for */
- but = UI_context_active_but_prop_get((bContext *)C, &ptr, &prop, &index);
- if (but) {
- FCurve *fcu;
- bool driven, special;
-
- fcu = rna_get_fcurve_context_ui((bContext *)C,
- &ptr, prop, index,
- NULL, NULL, &driven, &special);
-
- /* Hack: Force all buttons in this panel to be able to know the driver button
- * this panel is getting spawned from, so that things like the "Open Drivers Editor"
- * button will work.
- */
- uiLayoutSetContextFromBut(layout, but);
-
- /* Populate Panel - With a combination of the contents of the Driven and Driver panels */
- if (fcu) {
- ID *id = ptr.id.data;
-
- /* Driven Property Settings */
- uiItemL(layout, IFACE_("Driven Property:"), ICON_NONE);
- graph_draw_driven_property_panel(pa->layout, id, fcu);
- /* TODO: All vs Single */
-
- uiItemS(layout);
- uiItemS(layout);
-
- /* Drivers Settings */
- uiItemL(layout, IFACE_("Driver Settings:"), ICON_NONE);
- graph_draw_driver_settings_panel(pa->layout, id, fcu, true);
- }
- }
-
- /* Show drivers editor is always visible */
- uiItemO(layout, IFACE_("Show in Drivers Editor"), ICON_DRIVER, "SCREEN_OT_drivers_editor_show");
+ uiLayout *layout = pa->layout;
+
+ PointerRNA ptr = {{NULL}};
+ PropertyRNA *prop = NULL;
+ int index = -1;
+ uiBut *but = NULL;
+
+ /* Get active property to show driver properties for */
+ but = UI_context_active_but_prop_get((bContext *)C, &ptr, &prop, &index);
+ if (but) {
+ FCurve *fcu;
+ bool driven, special;
+
+ fcu = rna_get_fcurve_context_ui(
+ (bContext *)C, &ptr, prop, index, NULL, NULL, &driven, &special);
+
+ /* Hack: Force all buttons in this panel to be able to know the driver button
+ * this panel is getting spawned from, so that things like the "Open Drivers Editor"
+ * button will work.
+ */
+ uiLayoutSetContextFromBut(layout, but);
+
+ /* Populate Panel - With a combination of the contents of the Driven and Driver panels */
+ if (fcu) {
+ ID *id = ptr.id.data;
+
+ /* Driven Property Settings */
+ uiItemL(layout, IFACE_("Driven Property:"), ICON_NONE);
+ graph_draw_driven_property_panel(pa->layout, id, fcu);
+ /* TODO: All vs Single */
+
+ uiItemS(layout);
+ uiItemS(layout);
+
+ /* Drivers Settings */
+ uiItemL(layout, IFACE_("Driver Settings:"), ICON_NONE);
+ graph_draw_driver_settings_panel(pa->layout, id, fcu, true);
+ }
+ }
+
+ /* Show drivers editor is always visible */
+ uiItemO(layout, IFACE_("Show in Drivers Editor"), ICON_DRIVER, "SCREEN_OT_drivers_editor_show");
}
/* ******************* F-Modifiers ******************************** */
/* All the drawing code is in editors/animation/fmodifier_ui.c */
-#define B_FMODIFIER_REDRAW 20
+#define B_FMODIFIER_REDRAW 20
static void do_graph_region_modifier_buttons(bContext *C, void *UNUSED(arg), int event)
{
- switch (event) {
- case B_FMODIFIER_REDRAW: // XXX this should send depsgraph updates too
- WM_event_add_notifier(C, NC_ANIMATION, NULL); // XXX need a notifier specially for F-Modifiers
- break;
- }
+ switch (event) {
+ case B_FMODIFIER_REDRAW: // XXX this should send depsgraph updates too
+ WM_event_add_notifier(
+ C, NC_ANIMATION, NULL); // XXX need a notifier specially for F-Modifiers
+ break;
+ }
}
static void graph_panel_modifiers(const bContext *C, Panel *pa)
{
- bAnimListElem *ale;
- FCurve *fcu;
- FModifier *fcm;
- uiLayout *col, *row;
- uiBlock *block;
- bool active;
-
- if (!graph_panel_context(C, &ale, &fcu))
- return;
-
- block = uiLayoutGetBlock(pa->layout);
- UI_block_func_handle_set(block, do_graph_region_modifier_buttons, NULL);
-
- /* 'add modifier' button at top of panel */
- {
- row = uiLayoutRow(pa->layout, false);
-
- /* this is an operator button which calls a 'add modifier' operator...
- * a menu might be nicer but would be tricky as we need some custom filtering
- */
- uiItemMenuEnumO(row, (bContext *)C, "GRAPH_OT_fmodifier_add", "type", IFACE_("Add Modifier"), ICON_NONE);
-
- /* copy/paste (as sub-row) */
- row = uiLayoutRow(row, true);
- uiItemO(row, "", ICON_COPYDOWN, "GRAPH_OT_fmodifier_copy");
- uiItemO(row, "", ICON_PASTEDOWN, "GRAPH_OT_fmodifier_paste");
- }
-
- active = !(fcu->flag & FCURVE_MOD_OFF);
- /* draw each modifier */
- for (fcm = fcu->modifiers.first; fcm; fcm = fcm->next) {
- col = uiLayoutColumn(pa->layout, true);
- uiLayoutSetActive(col, active);
-
- ANIM_uiTemplate_fmodifier_draw(col, ale->fcurve_owner_id, &fcu->modifiers, fcm);
- }
-
- MEM_freeN(ale);
+ bAnimListElem *ale;
+ FCurve *fcu;
+ FModifier *fcm;
+ uiLayout *col, *row;
+ uiBlock *block;
+ bool active;
+
+ if (!graph_panel_context(C, &ale, &fcu))
+ return;
+
+ block = uiLayoutGetBlock(pa->layout);
+ UI_block_func_handle_set(block, do_graph_region_modifier_buttons, NULL);
+
+ /* 'add modifier' button at top of panel */
+ {
+ row = uiLayoutRow(pa->layout, false);
+
+ /* this is an operator button which calls a 'add modifier' operator...
+ * a menu might be nicer but would be tricky as we need some custom filtering
+ */
+ uiItemMenuEnumO(
+ row, (bContext *)C, "GRAPH_OT_fmodifier_add", "type", IFACE_("Add Modifier"), ICON_NONE);
+
+ /* copy/paste (as sub-row) */
+ row = uiLayoutRow(row, true);
+ uiItemO(row, "", ICON_COPYDOWN, "GRAPH_OT_fmodifier_copy");
+ uiItemO(row, "", ICON_PASTEDOWN, "GRAPH_OT_fmodifier_paste");
+ }
+
+ active = !(fcu->flag & FCURVE_MOD_OFF);
+ /* draw each modifier */
+ for (fcm = fcu->modifiers.first; fcm; fcm = fcm->next) {
+ col = uiLayoutColumn(pa->layout, true);
+ uiLayoutSetActive(col, active);
+
+ ANIM_uiTemplate_fmodifier_draw(col, ale->fcurve_owner_id, &fcu->modifiers, fcm);
+ }
+
+ MEM_freeN(ale);
}
/* ******************* general ******************************** */
void graph_buttons_register(ARegionType *art)
{
- PanelType *pt;
-
- pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel properties");
- strcpy(pt->idname, "GRAPH_PT_properties");
- strcpy(pt->label, N_("Active F-Curve"));
- strcpy(pt->category, "F-Curve");
- strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
- pt->draw = graph_panel_properties;
- pt->poll = graph_panel_poll;
- BLI_addtail(&art->paneltypes, pt);
-
- pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel properties");
- strcpy(pt->idname, "GRAPH_PT_key_properties");
- strcpy(pt->label, N_("Active Keyframe"));
- strcpy(pt->category, "F-Curve");
- strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
- pt->draw = graph_panel_key_properties;
- pt->poll = graph_panel_poll;
- BLI_addtail(&art->paneltypes, pt);
-
- pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel drivers driven");
- strcpy(pt->idname, "GRAPH_PT_driven_property");
- strcpy(pt->label, N_("Driven Property"));
- strcpy(pt->category, "Drivers");
- strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
- pt->draw = graph_panel_driven_property;
- pt->poll = graph_panel_drivers_poll;
- BLI_addtail(&art->paneltypes, pt);
-
- pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel drivers");
- strcpy(pt->idname, "GRAPH_PT_drivers");
- strcpy(pt->label, N_("Driver"));
- strcpy(pt->category, "Drivers");
- strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
- pt->draw = graph_panel_drivers;
- pt->poll = graph_panel_drivers_poll;
- BLI_addtail(&art->paneltypes, pt);
-
- pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel drivers pover");
- strcpy(pt->idname, "GRAPH_PT_drivers_popover");
- strcpy(pt->label, N_("Add/Edit Driver"));
- strcpy(pt->category, "Drivers");
- strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
- pt->draw = graph_panel_drivers_popover;
- pt->poll = graph_panel_drivers_popover_poll;
- BLI_addtail(&art->paneltypes, pt);
- /* This panel isn't used in this region.
- * Add explicitly to global list (so popovers work). */
- WM_paneltype_add(pt);
-
- pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel modifiers");
- strcpy(pt->idname, "GRAPH_PT_modifiers");
- strcpy(pt->label, N_("Modifiers"));
- strcpy(pt->category, "Modifiers");
- strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
- pt->draw = graph_panel_modifiers;
- pt->poll = graph_panel_poll;
- BLI_addtail(&art->paneltypes, pt);
-
- pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel view");
- strcpy(pt->idname, "GRAPH_PT_view");
- strcpy(pt->label, N_("View Properties"));
- strcpy(pt->category, "View");
- strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
- pt->draw = graph_panel_view;
- BLI_addtail(&art->paneltypes, pt);
+ PanelType *pt;
+
+ pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel properties");
+ strcpy(pt->idname, "GRAPH_PT_properties");
+ strcpy(pt->label, N_("Active F-Curve"));
+ strcpy(pt->category, "F-Curve");
+ strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+ pt->draw = graph_panel_properties;
+ pt->poll = graph_panel_poll;
+ BLI_addtail(&art->paneltypes, pt);
+
+ pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel properties");
+ strcpy(pt->idname, "GRAPH_PT_key_properties");
+ strcpy(pt->label, N_("Active Keyframe"));
+ strcpy(pt->category, "F-Curve");
+ strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+ pt->draw = graph_panel_key_properties;
+ pt->poll = graph_panel_poll;
+ BLI_addtail(&art->paneltypes, pt);
+
+ pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel drivers driven");
+ strcpy(pt->idname, "GRAPH_PT_driven_property");
+ strcpy(pt->label, N_("Driven Property"));
+ strcpy(pt->category, "Drivers");
+ strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+ pt->draw = graph_panel_driven_property;
+ pt->poll = graph_panel_drivers_poll;
+ BLI_addtail(&art->paneltypes, pt);
+
+ pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel drivers");
+ strcpy(pt->idname, "GRAPH_PT_drivers");
+ strcpy(pt->label, N_("Driver"));
+ strcpy(pt->category, "Drivers");
+ strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+ pt->draw = graph_panel_drivers;
+ pt->poll = graph_panel_drivers_poll;
+ BLI_addtail(&art->paneltypes, pt);
+
+ pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel drivers pover");
+ strcpy(pt->idname, "GRAPH_PT_drivers_popover");
+ strcpy(pt->label, N_("Add/Edit Driver"));
+ strcpy(pt->category, "Drivers");
+ strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+ pt->draw = graph_panel_drivers_popover;
+ pt->poll = graph_panel_drivers_popover_poll;
+ BLI_addtail(&art->paneltypes, pt);
+ /* This panel isn't used in this region.
+ * Add explicitly to global list (so popovers work). */
+ WM_paneltype_add(pt);
+
+ pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel modifiers");
+ strcpy(pt->idname, "GRAPH_PT_modifiers");
+ strcpy(pt->label, N_("Modifiers"));
+ strcpy(pt->category, "Modifiers");
+ strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+ pt->draw = graph_panel_modifiers;
+ pt->poll = graph_panel_poll;
+ BLI_addtail(&art->paneltypes, pt);
+
+ pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel view");
+ strcpy(pt->idname, "GRAPH_PT_view");
+ strcpy(pt->label, N_("View Properties"));
+ strcpy(pt->category, "View");
+ strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+ pt->draw = graph_panel_view;
+ BLI_addtail(&art->paneltypes, pt);
}
static int graph_properties_toggle_exec(bContext *C, wmOperator *UNUSED(op))
{
- ScrArea *sa = CTX_wm_area(C);
- ARegion *ar = graph_has_buttons_region(sa);
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar = graph_has_buttons_region(sa);
- if (ar)
- ED_region_toggle_hidden(C, ar);
+ if (ar)
+ ED_region_toggle_hidden(C, ar);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void GRAPH_OT_properties(wmOperatorType *ot)
{
- ot->name = "Toggle Sidebar";
- ot->idname = "GRAPH_OT_properties";
- ot->description = "Toggle the properties region visibility";
+ ot->name = "Toggle Sidebar";
+ ot->idname = "GRAPH_OT_properties";
+ ot->description = "Toggle the properties region visibility";
- ot->exec = graph_properties_toggle_exec;
- ot->poll = ED_operator_graphedit_active;
+ ot->exec = graph_properties_toggle_exec;
+ ot->poll = ED_operator_graphedit_active;
- /* flags */
- ot->flag = 0;
+ /* flags */
+ ot->flag = 0;
}
diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c
index 52f45a66c0d..5bfe1c1aadd 100644
--- a/source/blender/editors/space_graph/graph_draw.c
+++ b/source/blender/editors/space_graph/graph_draw.c
@@ -20,7 +20,6 @@
* \ingroup spgraph
*/
-
#include <stdio.h>
#include <math.h>
#include <string.h>
@@ -40,7 +39,6 @@
#include "BKE_curve.h"
#include "BKE_fcurve.h"
-
#include "GPU_draw.h"
#include "GPU_immediate.h"
#include "GPU_matrix.h"
@@ -63,7 +61,7 @@
*/
static float fcurve_display_alpha(FCurve *fcu)
{
- return (fcu->flag & FCURVE_SELECTED) ? 1.0f : U.fcu_inactive_alpha;
+ return (fcu->flag & FCURVE_SELECTED) ? 1.0f : U.fcu_inactive_alpha;
}
/* *************************** */
@@ -74,63 +72,64 @@ static float fcurve_display_alpha(FCurve *fcu)
/* TODO: draw a shaded poly showing the region of influence too!!! */
static void draw_fcurve_modifier_controls_envelope(FModifier *fcm, View2D *v2d)
{
- FMod_Envelope *env = (FMod_Envelope *)fcm->data;
- FCM_EnvelopeData *fed;
- const float fac = 0.05f * BLI_rctf_size_x(&v2d->cur);
- int i;
+ FMod_Envelope *env = (FMod_Envelope *)fcm->data;
+ FCM_EnvelopeData *fed;
+ const float fac = 0.05f * BLI_rctf_size_x(&v2d->cur);
+ int i;
- const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ const uint shdr_pos = GPU_vertformat_attr_add(
+ immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- GPU_line_width(1.0f);
+ GPU_line_width(1.0f);
- immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
- float viewport_size[4];
- GPU_viewport_size_get_f(viewport_size);
- immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
+ float viewport_size[4];
+ GPU_viewport_size_get_f(viewport_size);
+ immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
- immUniform1i("colors_len", 0); /* Simple dashes. */
- immUniformColor3f(0.0f, 0.0f, 0.0f);
- immUniform1f("dash_width", 10.0f);
- immUniform1f("dash_factor", 0.5f);
+ immUniform1i("colors_len", 0); /* Simple dashes. */
+ immUniformColor3f(0.0f, 0.0f, 0.0f);
+ immUniform1f("dash_width", 10.0f);
+ immUniform1f("dash_factor", 0.5f);
- /* draw two black lines showing the standard reference levels */
+ /* draw two black lines showing the standard reference levels */
- immBegin(GPU_PRIM_LINES, 4);
- immVertex2f(shdr_pos, v2d->cur.xmin, env->midval + env->min);
- immVertex2f(shdr_pos, v2d->cur.xmax, env->midval + env->min);
+ immBegin(GPU_PRIM_LINES, 4);
+ immVertex2f(shdr_pos, v2d->cur.xmin, env->midval + env->min);
+ immVertex2f(shdr_pos, v2d->cur.xmax, env->midval + env->min);
- immVertex2f(shdr_pos, v2d->cur.xmin, env->midval + env->max);
- immVertex2f(shdr_pos, v2d->cur.xmax, env->midval + env->max);
- immEnd();
+ immVertex2f(shdr_pos, v2d->cur.xmin, env->midval + env->max);
+ immVertex2f(shdr_pos, v2d->cur.xmax, env->midval + env->max);
+ immEnd();
- immUnbindProgram();
+ immUnbindProgram();
- if (env->totvert > 0) {
- /* set size of vertices (non-adjustable for now) */
- GPU_point_size(2.0f);
+ if (env->totvert > 0) {
+ /* set size of vertices (non-adjustable for now) */
+ GPU_point_size(2.0f);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- /* for now, point color is fixed, and is white */
- immUniformColor3f(1.0f, 1.0f, 1.0f);
+ /* for now, point color is fixed, and is white */
+ immUniformColor3f(1.0f, 1.0f, 1.0f);
- immBeginAtMost(GPU_PRIM_POINTS, env->totvert * 2);
+ immBeginAtMost(GPU_PRIM_POINTS, env->totvert * 2);
- for (i = 0, fed = env->data; i < env->totvert; i++, fed++) {
- /* only draw if visible
- * - min/max here are fixed, not relative
- */
- if (IN_RANGE(fed->time, (v2d->cur.xmin - fac), (v2d->cur.xmax + fac))) {
- immVertex2f(shdr_pos, fed->time, fed->min);
- immVertex2f(shdr_pos, fed->time, fed->max);
- }
- }
+ for (i = 0, fed = env->data; i < env->totvert; i++, fed++) {
+ /* only draw if visible
+ * - min/max here are fixed, not relative
+ */
+ if (IN_RANGE(fed->time, (v2d->cur.xmin - fac), (v2d->cur.xmax + fac))) {
+ immVertex2f(shdr_pos, fed->time, fed->min);
+ immVertex2f(shdr_pos, fed->time, fed->max);
+ }
+ }
- immEnd();
+ immEnd();
- immUnbindProgram();
- }
+ immUnbindProgram();
+ }
}
/* *************************** */
@@ -141,283 +140,282 @@ static void draw_fcurve_modifier_controls_envelope(FModifier *fcm, View2D *v2d)
/* helper func - set color to draw F-Curve data with */
static void set_fcurve_vertex_color(FCurve *fcu, bool sel)
{
- float color[4];
- float diff;
-
- /* Set color of curve vertex based on state of curve (i.e. 'Edit' Mode) */
- if ((fcu->flag & FCURVE_PROTECTED) == 0) {
- /* Curve's points ARE BEING edited */
- UI_GetThemeColor3fv(sel ? TH_VERTEX_SELECT : TH_VERTEX, color);
- }
- else {
- /* Curve's points CANNOT BE edited */
- UI_GetThemeColor3fv(sel ? TH_TEXT_HI : TH_TEXT, color);
- }
-
- /* Fade the 'intensity' of the vertices based on the selection of the curves too
- * - Only fade by 50% the amount the curves were faded by, so that the points
- * still stand out for easier selection
- */
- diff = 1.0f - fcurve_display_alpha(fcu);
- color[3] = 1.0f - (diff * 0.5f);
- CLAMP(color[3], 0.2f, 1.0f);
-
- immUniformColor4fv(color);
+ float color[4];
+ float diff;
+
+ /* Set color of curve vertex based on state of curve (i.e. 'Edit' Mode) */
+ if ((fcu->flag & FCURVE_PROTECTED) == 0) {
+ /* Curve's points ARE BEING edited */
+ UI_GetThemeColor3fv(sel ? TH_VERTEX_SELECT : TH_VERTEX, color);
+ }
+ else {
+ /* Curve's points CANNOT BE edited */
+ UI_GetThemeColor3fv(sel ? TH_TEXT_HI : TH_TEXT, color);
+ }
+
+ /* Fade the 'intensity' of the vertices based on the selection of the curves too
+ * - Only fade by 50% the amount the curves were faded by, so that the points
+ * still stand out for easier selection
+ */
+ diff = 1.0f - fcurve_display_alpha(fcu);
+ color[3] = 1.0f - (diff * 0.5f);
+ CLAMP(color[3], 0.2f, 1.0f);
+
+ immUniformColor4fv(color);
}
-static void draw_fcurve_selected_keyframe_vertices(FCurve *fcu, View2D *v2d, bool edit, bool sel, unsigned pos)
+static void draw_fcurve_selected_keyframe_vertices(
+ FCurve *fcu, View2D *v2d, bool edit, bool sel, unsigned pos)
{
- const float fac = 0.05f * BLI_rctf_size_x(&v2d->cur);
-
- set_fcurve_vertex_color(fcu, sel);
-
- immBeginAtMost(GPU_PRIM_POINTS, fcu->totvert);
-
- BezTriple *bezt = fcu->bezt;
- for (int i = 0; i < fcu->totvert; i++, bezt++) {
- /* as an optimization step, only draw those in view
- * - we apply a correction factor to ensure that points don't pop in/out due to slight twitches of view size
- */
- if (IN_RANGE(bezt->vec[1][0], (v2d->cur.xmin - fac), (v2d->cur.xmax + fac))) {
- if (edit) {
- /* 'Keyframe' vertex only, as handle lines and handles have already been drawn
- * - only draw those with correct selection state for the current drawing color
- * -
- */
- if ((bezt->f2 & SELECT) == sel)
- immVertex2fv(pos, bezt->vec[1]);
- }
- else {
- /* no check for selection here, as curve is not editable... */
- /* XXX perhaps we don't want to even draw points? maybe add an option for that later */
- immVertex2fv(pos, bezt->vec[1]);
- }
- }
- }
-
- immEnd();
+ const float fac = 0.05f * BLI_rctf_size_x(&v2d->cur);
+
+ set_fcurve_vertex_color(fcu, sel);
+
+ immBeginAtMost(GPU_PRIM_POINTS, fcu->totvert);
+
+ BezTriple *bezt = fcu->bezt;
+ for (int i = 0; i < fcu->totvert; i++, bezt++) {
+ /* as an optimization step, only draw those in view
+ * - we apply a correction factor to ensure that points don't pop in/out due to slight twitches of view size
+ */
+ if (IN_RANGE(bezt->vec[1][0], (v2d->cur.xmin - fac), (v2d->cur.xmax + fac))) {
+ if (edit) {
+ /* 'Keyframe' vertex only, as handle lines and handles have already been drawn
+ * - only draw those with correct selection state for the current drawing color
+ * -
+ */
+ if ((bezt->f2 & SELECT) == sel)
+ immVertex2fv(pos, bezt->vec[1]);
+ }
+ else {
+ /* no check for selection here, as curve is not editable... */
+ /* XXX perhaps we don't want to even draw points? maybe add an option for that later */
+ immVertex2fv(pos, bezt->vec[1]);
+ }
+ }
+ }
+
+ immEnd();
}
/* helper func - draw keyframe vertices only for an F-Curve */
static void draw_fcurve_keyframe_vertices(FCurve *fcu, View2D *v2d, bool edit, unsigned pos)
{
- immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA);
+ immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA);
- immUniform1f("size", UI_GetThemeValuef(TH_VERTEX_SIZE) * U.pixelsize);
+ immUniform1f("size", UI_GetThemeValuef(TH_VERTEX_SIZE) * U.pixelsize);
- draw_fcurve_selected_keyframe_vertices(fcu, v2d, edit, false, pos);
- draw_fcurve_selected_keyframe_vertices(fcu, v2d, edit, true, pos);
+ draw_fcurve_selected_keyframe_vertices(fcu, v2d, edit, false, pos);
+ draw_fcurve_selected_keyframe_vertices(fcu, v2d, edit, true, pos);
- immUnbindProgram();
+ immUnbindProgram();
}
-
/* helper func - draw handle vertices only for an F-Curve (if it is not protected) */
-static void draw_fcurve_selected_handle_vertices(FCurve *fcu, View2D *v2d, bool sel, bool sel_handle_only, unsigned pos)
+static void draw_fcurve_selected_handle_vertices(
+ FCurve *fcu, View2D *v2d, bool sel, bool sel_handle_only, unsigned pos)
{
- (void) v2d; /* TODO: use this to draw only points in view */
-
- /* set handle color */
- float hcolor[3];
- UI_GetThemeColor3fv(sel ? TH_HANDLE_VERTEX_SELECT : TH_HANDLE_VERTEX, hcolor);
- immUniform4f("outlineColor", hcolor[0], hcolor[1], hcolor[2], 1.0f);
- immUniformColor3fvAlpha(hcolor, 0.01f); /* almost invisible - only keep for smoothness */
-
- immBeginAtMost(GPU_PRIM_POINTS, fcu->totvert * 2);
-
- BezTriple *bezt = fcu->bezt;
- BezTriple *prevbezt = NULL;
- for (int i = 0; i < fcu->totvert; i++, prevbezt = bezt, bezt++) {
- /* Draw the editmode handles for a bezier curve (others don't have handles)
- * if their selection status matches the selection status we're drawing for
- * - first handle only if previous beztriple was bezier-mode
- * - second handle only if current beztriple is bezier-mode
- *
- * Also, need to take into account whether the keyframe was selected
- * if a Graph Editor option to only show handles of selected keys is on.
- */
- if (!sel_handle_only || BEZT_ISSEL_ANY(bezt)) {
- if ((!prevbezt && (bezt->ipo == BEZT_IPO_BEZ)) || (prevbezt && (prevbezt->ipo == BEZT_IPO_BEZ))) {
- if ((bezt->f1 & SELECT) == sel
- /* && v2d->cur.xmin < bezt->vec[0][0] < v2d->cur.xmax) */ )
- {
- immVertex2fv(pos, bezt->vec[0]);
- }
- }
-
- if (bezt->ipo == BEZT_IPO_BEZ) {
- if ((bezt->f3 & SELECT) == sel
- /* && v2d->cur.xmin < bezt->vec[2][0] < v2d->cur.xmax) */ )
- {
- immVertex2fv(pos, bezt->vec[2]);
- }
- }
- }
- }
-
- immEnd();
+ (void)v2d; /* TODO: use this to draw only points in view */
+
+ /* set handle color */
+ float hcolor[3];
+ UI_GetThemeColor3fv(sel ? TH_HANDLE_VERTEX_SELECT : TH_HANDLE_VERTEX, hcolor);
+ immUniform4f("outlineColor", hcolor[0], hcolor[1], hcolor[2], 1.0f);
+ immUniformColor3fvAlpha(hcolor, 0.01f); /* almost invisible - only keep for smoothness */
+
+ immBeginAtMost(GPU_PRIM_POINTS, fcu->totvert * 2);
+
+ BezTriple *bezt = fcu->bezt;
+ BezTriple *prevbezt = NULL;
+ for (int i = 0; i < fcu->totvert; i++, prevbezt = bezt, bezt++) {
+ /* Draw the editmode handles for a bezier curve (others don't have handles)
+ * if their selection status matches the selection status we're drawing for
+ * - first handle only if previous beztriple was bezier-mode
+ * - second handle only if current beztriple is bezier-mode
+ *
+ * Also, need to take into account whether the keyframe was selected
+ * if a Graph Editor option to only show handles of selected keys is on.
+ */
+ if (!sel_handle_only || BEZT_ISSEL_ANY(bezt)) {
+ if ((!prevbezt && (bezt->ipo == BEZT_IPO_BEZ)) ||
+ (prevbezt && (prevbezt->ipo == BEZT_IPO_BEZ))) {
+ if ((bezt->f1 & SELECT) == sel
+ /* && v2d->cur.xmin < bezt->vec[0][0] < v2d->cur.xmax) */) {
+ immVertex2fv(pos, bezt->vec[0]);
+ }
+ }
+
+ if (bezt->ipo == BEZT_IPO_BEZ) {
+ if ((bezt->f3 & SELECT) == sel
+ /* && v2d->cur.xmin < bezt->vec[2][0] < v2d->cur.xmax) */) {
+ immVertex2fv(pos, bezt->vec[2]);
+ }
+ }
+ }
+ }
+
+ immEnd();
}
/* helper func - draw handle vertices only for an F-Curve (if it is not protected) */
-static void draw_fcurve_handle_vertices(FCurve *fcu, View2D *v2d, bool sel_handle_only, unsigned pos)
+static void draw_fcurve_handle_vertices(FCurve *fcu,
+ View2D *v2d,
+ bool sel_handle_only,
+ unsigned pos)
{
- /* smooth outlines for more consistent appearance */
- immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA);
+ /* smooth outlines for more consistent appearance */
+ immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA);
- /* set handle size */
- immUniform1f("size", (1.4f * UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE)) * U.pixelsize);
- immUniform1f("outlineWidth", 1.5f * U.pixelsize);
+ /* set handle size */
+ immUniform1f("size", (1.4f * UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE)) * U.pixelsize);
+ immUniform1f("outlineWidth", 1.5f * U.pixelsize);
- draw_fcurve_selected_handle_vertices(fcu, v2d, false, sel_handle_only, pos);
- draw_fcurve_selected_handle_vertices(fcu, v2d, true, sel_handle_only, pos);
+ draw_fcurve_selected_handle_vertices(fcu, v2d, false, sel_handle_only, pos);
+ draw_fcurve_selected_handle_vertices(fcu, v2d, true, sel_handle_only, pos);
- immUnbindProgram();
+ immUnbindProgram();
}
-
static void draw_fcurve_vertices(ARegion *ar, FCurve *fcu, bool do_handles, bool sel_handle_only)
{
- View2D *v2d = &ar->v2d;
+ View2D *v2d = &ar->v2d;
- /* only draw points if curve is visible
- * - draw unselected points before selected points as separate passes
- * to make sure in the case of overlapping points that the selected is always visible
- * - draw handles before keyframes, so that keyframes will overlap handles (keyframes are more important for users)
- */
+ /* only draw points if curve is visible
+ * - draw unselected points before selected points as separate passes
+ * to make sure in the case of overlapping points that the selected is always visible
+ * - draw handles before keyframes, so that keyframes will overlap handles (keyframes are more important for users)
+ */
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- GPU_blend(true);
- GPU_enable_program_point_size();
+ GPU_blend(true);
+ GPU_enable_program_point_size();
- /* draw the two handles first (if they're shown, the curve doesn't
- * have just a single keyframe, and the curve is being edited) */
- if (do_handles) {
- draw_fcurve_handle_vertices(fcu, v2d, sel_handle_only, pos);
- }
+ /* draw the two handles first (if they're shown, the curve doesn't
+ * have just a single keyframe, and the curve is being edited) */
+ if (do_handles) {
+ draw_fcurve_handle_vertices(fcu, v2d, sel_handle_only, pos);
+ }
- /* draw keyframes over the handles */
- draw_fcurve_keyframe_vertices(fcu, v2d, !(fcu->flag & FCURVE_PROTECTED), pos);
+ /* draw keyframes over the handles */
+ draw_fcurve_keyframe_vertices(fcu, v2d, !(fcu->flag & FCURVE_PROTECTED), pos);
- GPU_disable_program_point_size();
- GPU_blend(false);
+ GPU_disable_program_point_size();
+ GPU_blend(false);
}
/* Handles ---------------- */
static bool draw_fcurve_handles_check(SpaceGraph *sipo, FCurve *fcu)
{
- /* don't draw handle lines if handles are not to be shown */
- if (
- /* handles shouldn't be shown anywhere */
- (sipo->flag & SIPO_NOHANDLES) ||
- /* keyframes aren't editable */
- (fcu->flag & FCURVE_PROTECTED) ||
-#if 0 /* handles can still be selected and handle types set, better draw - campbell */
- /* editing the handles here will cause weird/incorrect interpolation issues */
- (fcu->flag & FCURVE_INT_VALUES) ||
+ /* don't draw handle lines if handles are not to be shown */
+ if (
+ /* handles shouldn't be shown anywhere */
+ (sipo->flag & SIPO_NOHANDLES) ||
+ /* keyframes aren't editable */
+ (fcu->flag & FCURVE_PROTECTED) ||
+#if 0 /* handles can still be selected and handle types set, better draw - campbell */
+ /* editing the handles here will cause weird/incorrect interpolation issues */
+ (fcu->flag & FCURVE_INT_VALUES) ||
#endif
- /* group that curve belongs to is not editable */
- ((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED)) ||
- /* do not show handles if there is only 1 keyframe,
- * otherwise they all clump together in an ugly ball */
- (fcu->totvert <= 1)
- )
- {
- return false;
- }
- else {
- return true;
- }
+ /* group that curve belongs to is not editable */
+ ((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED)) ||
+ /* do not show handles if there is only 1 keyframe,
+ * otherwise they all clump together in an ugly ball */
+ (fcu->totvert <= 1)) {
+ return false;
+ }
+ else {
+ return true;
+ }
}
/* draw lines for F-Curve handles only (this is only done in EditMode)
* note: draw_fcurve_handles_check must be checked before running this. */
static void draw_fcurve_handles(SpaceGraph *sipo, FCurve *fcu)
{
- int sel, b;
-
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
- immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
-
- immBeginAtMost(GPU_PRIM_LINES, 4 * 2 * fcu->totvert);
-
- /* slightly hacky, but we want to draw unselected points before selected ones
- * so that selected points are clearly visible
- */
- for (sel = 0; sel < 2; sel++) {
- BezTriple *bezt = fcu->bezt, *prevbezt = NULL;
- int basecol = (sel) ? TH_HANDLE_SEL_FREE : TH_HANDLE_FREE;
- const float *fp;
- unsigned char col[4];
-
- for (b = 0; b < fcu->totvert; b++, prevbezt = bezt, bezt++) {
- /* if only selected keyframes can get their handles shown,
- * check that keyframe is selected
- */
- if (sipo->flag & SIPO_SELVHANDLESONLY) {
- if (BEZT_ISSEL_ANY(bezt) == 0)
- continue;
- }
-
- /* draw handle with appropriate set of colors if selection is ok */
- if ((bezt->f2 & SELECT) == sel) {
- fp = bezt->vec[0];
-
- /* only draw first handle if previous segment had handles */
- if ((!prevbezt && (bezt->ipo == BEZT_IPO_BEZ)) || (prevbezt && (prevbezt->ipo == BEZT_IPO_BEZ))) {
- UI_GetThemeColor3ubv(basecol + bezt->h1, col);
- col[3] = fcurve_display_alpha(fcu) * 255;
- immAttr4ubv(color, col);
- immVertex2fv(pos, fp);
- immAttr4ubv(color, col);
- immVertex2fv(pos, fp + 3);
- }
-
- /* only draw second handle if this segment is bezier */
- if (bezt->ipo == BEZT_IPO_BEZ) {
- UI_GetThemeColor3ubv(basecol + bezt->h2, col);
- col[3] = fcurve_display_alpha(fcu) * 255;
- immAttr4ubv(color, col);
- immVertex2fv(pos, fp + 3);
- immAttr4ubv(color, col);
- immVertex2fv(pos, fp + 6);
- }
- }
- else {
- /* only draw first handle if previous segment was had handles, and selection is ok */
- if (((bezt->f1 & SELECT) == sel) &&
- ((!prevbezt && (bezt->ipo == BEZT_IPO_BEZ)) || (prevbezt && (prevbezt->ipo == BEZT_IPO_BEZ))))
- {
- fp = bezt->vec[0];
- UI_GetThemeColor3ubv(basecol + bezt->h1, col);
- col[3] = fcurve_display_alpha(fcu) * 255;
- immAttr4ubv(color, col);
- immVertex2fv(pos, fp);
- immAttr4ubv(color, col);
- immVertex2fv(pos, fp + 3);
- }
-
- /* only draw second handle if this segment is bezier, and selection is ok */
- if (((bezt->f3 & SELECT) == sel) &&
- (bezt->ipo == BEZT_IPO_BEZ))
- {
- fp = bezt->vec[1];
- UI_GetThemeColor3ubv(basecol + bezt->h2, col);
- col[3] = fcurve_display_alpha(fcu) * 255;
- immAttr4ubv(color, col);
- immVertex2fv(pos, fp);
- immAttr4ubv(color, col);
- immVertex2fv(pos, fp + 3);
- }
- }
- }
- }
-
- immEnd();
- immUnbindProgram();
+ int sel, b;
+
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint color = GPU_vertformat_attr_add(
+ format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
+ immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
+
+ immBeginAtMost(GPU_PRIM_LINES, 4 * 2 * fcu->totvert);
+
+ /* slightly hacky, but we want to draw unselected points before selected ones
+ * so that selected points are clearly visible
+ */
+ for (sel = 0; sel < 2; sel++) {
+ BezTriple *bezt = fcu->bezt, *prevbezt = NULL;
+ int basecol = (sel) ? TH_HANDLE_SEL_FREE : TH_HANDLE_FREE;
+ const float *fp;
+ unsigned char col[4];
+
+ for (b = 0; b < fcu->totvert; b++, prevbezt = bezt, bezt++) {
+ /* if only selected keyframes can get their handles shown,
+ * check that keyframe is selected
+ */
+ if (sipo->flag & SIPO_SELVHANDLESONLY) {
+ if (BEZT_ISSEL_ANY(bezt) == 0)
+ continue;
+ }
+
+ /* draw handle with appropriate set of colors if selection is ok */
+ if ((bezt->f2 & SELECT) == sel) {
+ fp = bezt->vec[0];
+
+ /* only draw first handle if previous segment had handles */
+ if ((!prevbezt && (bezt->ipo == BEZT_IPO_BEZ)) ||
+ (prevbezt && (prevbezt->ipo == BEZT_IPO_BEZ))) {
+ UI_GetThemeColor3ubv(basecol + bezt->h1, col);
+ col[3] = fcurve_display_alpha(fcu) * 255;
+ immAttr4ubv(color, col);
+ immVertex2fv(pos, fp);
+ immAttr4ubv(color, col);
+ immVertex2fv(pos, fp + 3);
+ }
+
+ /* only draw second handle if this segment is bezier */
+ if (bezt->ipo == BEZT_IPO_BEZ) {
+ UI_GetThemeColor3ubv(basecol + bezt->h2, col);
+ col[3] = fcurve_display_alpha(fcu) * 255;
+ immAttr4ubv(color, col);
+ immVertex2fv(pos, fp + 3);
+ immAttr4ubv(color, col);
+ immVertex2fv(pos, fp + 6);
+ }
+ }
+ else {
+ /* only draw first handle if previous segment was had handles, and selection is ok */
+ if (((bezt->f1 & SELECT) == sel) && ((!prevbezt && (bezt->ipo == BEZT_IPO_BEZ)) ||
+ (prevbezt && (prevbezt->ipo == BEZT_IPO_BEZ)))) {
+ fp = bezt->vec[0];
+ UI_GetThemeColor3ubv(basecol + bezt->h1, col);
+ col[3] = fcurve_display_alpha(fcu) * 255;
+ immAttr4ubv(color, col);
+ immVertex2fv(pos, fp);
+ immAttr4ubv(color, col);
+ immVertex2fv(pos, fp + 3);
+ }
+
+ /* only draw second handle if this segment is bezier, and selection is ok */
+ if (((bezt->f3 & SELECT) == sel) && (bezt->ipo == BEZT_IPO_BEZ)) {
+ fp = bezt->vec[1];
+ UI_GetThemeColor3ubv(basecol + bezt->h2, col);
+ col[3] = fcurve_display_alpha(fcu) * 255;
+ immAttr4ubv(color, col);
+ immVertex2fv(pos, fp);
+ immAttr4ubv(color, col);
+ immVertex2fv(pos, fp + 3);
+ }
+ }
+ }
+ }
+
+ immEnd();
+ immUnbindProgram();
}
/* Samples ---------------- */
@@ -426,230 +424,236 @@ static void draw_fcurve_handles(SpaceGraph *sipo, FCurve *fcu)
* NOTE: the caller MUST HAVE GL_LINE_SMOOTH & GL_BLEND ENABLED, otherwise, the controls don't
* have a consistent appearance (due to off-pixel alignments)...
*/
-static void draw_fcurve_sample_control(float x, float y, float xscale, float yscale, float hsize, unsigned int pos)
+static void draw_fcurve_sample_control(
+ float x, float y, float xscale, float yscale, float hsize, unsigned int pos)
{
- /* adjust view transform before starting */
- GPU_matrix_push();
- GPU_matrix_translate_2f(x, y);
- GPU_matrix_scale_2f(1.0f / xscale * hsize, 1.0f / yscale * hsize);
-
- /* draw X shape */
- immBegin(GPU_PRIM_LINES, 4);
- immVertex2f(pos, -0.7f, -0.7f);
- immVertex2f(pos, +0.7f, +0.7f);
-
- immVertex2f(pos, -0.7f, +0.7f);
- immVertex2f(pos, +0.7f, -0.7f);
- immEnd();
-
- /* restore view transform */
- GPU_matrix_pop();
+ /* adjust view transform before starting */
+ GPU_matrix_push();
+ GPU_matrix_translate_2f(x, y);
+ GPU_matrix_scale_2f(1.0f / xscale * hsize, 1.0f / yscale * hsize);
+
+ /* draw X shape */
+ immBegin(GPU_PRIM_LINES, 4);
+ immVertex2f(pos, -0.7f, -0.7f);
+ immVertex2f(pos, +0.7f, +0.7f);
+
+ immVertex2f(pos, -0.7f, +0.7f);
+ immVertex2f(pos, +0.7f, -0.7f);
+ immEnd();
+
+ /* restore view transform */
+ GPU_matrix_pop();
}
/* helper func - draw keyframe vertices only for an F-Curve */
static void draw_fcurve_samples(SpaceGraph *sipo, ARegion *ar, FCurve *fcu)
{
- FPoint *first, *last;
- float hsize, xscale, yscale;
+ FPoint *first, *last;
+ float hsize, xscale, yscale;
- /* get view settings */
- hsize = UI_GetThemeValuef(TH_VERTEX_SIZE);
- UI_view2d_scale_get(&ar->v2d, &xscale, &yscale);
+ /* get view settings */
+ hsize = UI_GetThemeValuef(TH_VERTEX_SIZE);
+ UI_view2d_scale_get(&ar->v2d, &xscale, &yscale);
- /* get verts */
- first = fcu->fpt;
- last = (first) ? (first + (fcu->totvert - 1)) : (NULL);
+ /* get verts */
+ first = fcu->fpt;
+ last = (first) ? (first + (fcu->totvert - 1)) : (NULL);
- /* draw */
- if (first && last) {
- /* anti-aliased lines for more consistent appearance */
- if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) GPU_line_smooth(true);
- GPU_blend(true);
+ /* draw */
+ if (first && last) {
+ /* anti-aliased lines for more consistent appearance */
+ if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0)
+ GPU_line_smooth(true);
+ GPU_blend(true);
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- immUniformThemeColor((fcu->flag & FCURVE_SELECTED) ? TH_TEXT_HI : TH_TEXT);
+ immUniformThemeColor((fcu->flag & FCURVE_SELECTED) ? TH_TEXT_HI : TH_TEXT);
- draw_fcurve_sample_control(first->vec[0], first->vec[1], xscale, yscale, hsize, pos);
- draw_fcurve_sample_control(last->vec[0], last->vec[1], xscale, yscale, hsize, pos);
+ draw_fcurve_sample_control(first->vec[0], first->vec[1], xscale, yscale, hsize, pos);
+ draw_fcurve_sample_control(last->vec[0], last->vec[1], xscale, yscale, hsize, pos);
- immUnbindProgram();
+ immUnbindProgram();
- GPU_blend(false);
- if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) GPU_line_smooth(false);
- }
+ GPU_blend(false);
+ if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0)
+ GPU_line_smooth(false);
+ }
}
/* Curve ---------------- */
/* helper func - just draw the F-Curve by sampling the visible region (for drawing curves with modifiers) */
-static void draw_fcurve_curve(bAnimContext *ac, ID *id, FCurve *fcu_, View2D *v2d, View2DGrid *grid, unsigned int pos)
+static void draw_fcurve_curve(
+ bAnimContext *ac, ID *id, FCurve *fcu_, View2D *v2d, View2DGrid *grid, unsigned int pos)
{
- SpaceGraph *sipo = (SpaceGraph *)ac->sl;
- float samplefreq;
- float stime, etime;
- float unitFac, offset;
- float dx, dy;
- short mapping_flag = ANIM_get_normalization_flags(ac);
- int i, n;
-
- /* when opening a blend file on a different sized screen or while dragging the toolbar this can happen
- * best just bail out in this case */
- UI_view2d_grid_size(grid, &dx, &dy);
- if (dx <= 0.0f)
- return;
-
-
- /* disable any drivers */
- FCurve fcurve_for_draw = *fcu_;
- fcurve_for_draw.driver = NULL;
-
- /* compute unit correction factor */
- unitFac = ANIM_unit_mapping_get_factor(ac->scene, id, &fcurve_for_draw, mapping_flag, &offset);
-
- /* Note about sampling frequency:
- * Ideally, this is chosen such that we have 1-2 pixels = 1 segment
- * which means that our curves can be as smooth as possible. However,
- * this does mean that curves may not be fully accurate (i.e. if they have
- * sudden spikes which happen at the sampling point, we may have problems).
- * Also, this may introduce lower performance on less densely detailed curves,
- * though it is impossible to predict this from the modifiers!
- *
- * If the automatically determined sampling frequency is likely to cause an infinite
- * loop (i.e. too close to 0), then clamp it to a determined "safe" value. The value
- * chosen here is just the coarsest value which still looks reasonable...
- */
- /* grid->dx represents the number of 'frames' between gridlines,
- * but we divide by U.v2d_min_gridsize to get pixels-steps */
- /* TODO: perhaps we should have 1.0 frames as upper limit so that curves don't get too distorted? */
- samplefreq = dx / (U.v2d_min_gridsize * U.pixelsize);
-
- if (sipo->flag & SIPO_BEAUTYDRAW_OFF) {
- /* Low Precision = coarse lower-bound clamping
- *
- * Although the "Beauty Draw" flag was originally for AA'd
- * line drawing, the sampling rate here has a much greater
- * impact on performance (e.g. for T40372)!
- *
- * This one still amounts to 10 sample-frames for each 1-frame interval
- * which should be quite a decent approximation in many situations.
- */
- if (samplefreq < 0.1f)
- samplefreq = 0.1f;
- }
- else {
- /* "Higher Precision" but slower - especially on larger windows (e.g. T40372) */
- if (samplefreq < 0.00001f)
- samplefreq = 0.00001f;
- }
-
-
- /* the start/end times are simply the horizontal extents of the 'cur' rect */
- stime = v2d->cur.xmin;
- etime = v2d->cur.xmax + samplefreq; /* + samplefreq here so that last item gets included... */
-
-
- /* at each sampling interval, add a new vertex
- * - apply the unit correction factor to the calculated values so that
- * the displayed values appear correctly in the viewport
- */
-
- n = (etime - stime) / samplefreq + 0.5f;
-
- if (n > 0) {
- immBegin(GPU_PRIM_LINE_STRIP, (n + 1));
-
- for (i = 0; i <= n; i++) {
- float ctime = stime + i * samplefreq;
- immVertex2f(pos, ctime, (evaluate_fcurve(&fcurve_for_draw, ctime) + offset) * unitFac);
- }
-
- immEnd();
- }
+ SpaceGraph *sipo = (SpaceGraph *)ac->sl;
+ float samplefreq;
+ float stime, etime;
+ float unitFac, offset;
+ float dx, dy;
+ short mapping_flag = ANIM_get_normalization_flags(ac);
+ int i, n;
+
+ /* when opening a blend file on a different sized screen or while dragging the toolbar this can happen
+ * best just bail out in this case */
+ UI_view2d_grid_size(grid, &dx, &dy);
+ if (dx <= 0.0f)
+ return;
+
+ /* disable any drivers */
+ FCurve fcurve_for_draw = *fcu_;
+ fcurve_for_draw.driver = NULL;
+
+ /* compute unit correction factor */
+ unitFac = ANIM_unit_mapping_get_factor(ac->scene, id, &fcurve_for_draw, mapping_flag, &offset);
+
+ /* Note about sampling frequency:
+ * Ideally, this is chosen such that we have 1-2 pixels = 1 segment
+ * which means that our curves can be as smooth as possible. However,
+ * this does mean that curves may not be fully accurate (i.e. if they have
+ * sudden spikes which happen at the sampling point, we may have problems).
+ * Also, this may introduce lower performance on less densely detailed curves,
+ * though it is impossible to predict this from the modifiers!
+ *
+ * If the automatically determined sampling frequency is likely to cause an infinite
+ * loop (i.e. too close to 0), then clamp it to a determined "safe" value. The value
+ * chosen here is just the coarsest value which still looks reasonable...
+ */
+ /* grid->dx represents the number of 'frames' between gridlines,
+ * but we divide by U.v2d_min_gridsize to get pixels-steps */
+ /* TODO: perhaps we should have 1.0 frames as upper limit so that curves don't get too distorted? */
+ samplefreq = dx / (U.v2d_min_gridsize * U.pixelsize);
+
+ if (sipo->flag & SIPO_BEAUTYDRAW_OFF) {
+ /* Low Precision = coarse lower-bound clamping
+ *
+ * Although the "Beauty Draw" flag was originally for AA'd
+ * line drawing, the sampling rate here has a much greater
+ * impact on performance (e.g. for T40372)!
+ *
+ * This one still amounts to 10 sample-frames for each 1-frame interval
+ * which should be quite a decent approximation in many situations.
+ */
+ if (samplefreq < 0.1f)
+ samplefreq = 0.1f;
+ }
+ else {
+ /* "Higher Precision" but slower - especially on larger windows (e.g. T40372) */
+ if (samplefreq < 0.00001f)
+ samplefreq = 0.00001f;
+ }
+
+ /* the start/end times are simply the horizontal extents of the 'cur' rect */
+ stime = v2d->cur.xmin;
+ etime = v2d->cur.xmax + samplefreq; /* + samplefreq here so that last item gets included... */
+
+ /* at each sampling interval, add a new vertex
+ * - apply the unit correction factor to the calculated values so that
+ * the displayed values appear correctly in the viewport
+ */
+
+ n = (etime - stime) / samplefreq + 0.5f;
+
+ if (n > 0) {
+ immBegin(GPU_PRIM_LINE_STRIP, (n + 1));
+
+ for (i = 0; i <= n; i++) {
+ float ctime = stime + i * samplefreq;
+ immVertex2f(pos, ctime, (evaluate_fcurve(&fcurve_for_draw, ctime) + offset) * unitFac);
+ }
+
+ immEnd();
+ }
}
/* helper func - draw a samples-based F-Curve */
-static void draw_fcurve_curve_samples(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d, const uint shdr_pos)
+static void draw_fcurve_curve_samples(
+ bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d, const uint shdr_pos)
{
- FPoint *prevfpt = fcu->fpt;
- FPoint *fpt = prevfpt + 1;
- float fac, v[2];
- int b = fcu->totvert;
- float unit_scale, offset;
- short mapping_flag = ANIM_get_normalization_flags(ac);
- int count = fcu->totvert;
-
- if (prevfpt->vec[0] > v2d->cur.xmin) {
- count++;
- }
-
- if ((prevfpt + b - 1)->vec[0] < v2d->cur.xmax) {
- count++;
- }
-
- /* apply unit mapping */
- GPU_matrix_push();
- unit_scale = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag, &offset);
- GPU_matrix_scale_2f(1.0f, unit_scale);
- GPU_matrix_translate_2f(0.0f, offset);
-
- immBegin(GPU_PRIM_LINE_STRIP, count);
-
- /* extrapolate to left? - left-side of view comes before first keyframe? */
- if (prevfpt->vec[0] > v2d->cur.xmin) {
- v[0] = v2d->cur.xmin;
-
- /* y-value depends on the interpolation */
- if ((fcu->extend == FCURVE_EXTRAPOLATE_CONSTANT) || (fcu->flag & FCURVE_INT_VALUES) || (fcu->totvert == 1)) {
- /* just extend across the first keyframe's value */
- v[1] = prevfpt->vec[1];
- }
- else {
- /* extrapolate linear doesn't use the handle, use the next points center instead */
- fac = (prevfpt->vec[0] - fpt->vec[0]) / (prevfpt->vec[0] - v[0]);
- if (fac) fac = 1.0f / fac;
- v[1] = prevfpt->vec[1] - fac * (prevfpt->vec[1] - fpt->vec[1]);
- }
-
- immVertex2fv(shdr_pos, v);
- }
-
- /* loop over samples, drawing segments */
- /* draw curve between first and last keyframe (if there are enough to do so) */
- while (b--) {
- /* Linear interpolation: just add one point (which should add a new line segment) */
- immVertex2fv(shdr_pos, prevfpt->vec);
-
- /* get next pointers */
- if (b > 0) {
- prevfpt++;
- }
- }
-
- /* extrapolate to right? (see code for left-extrapolation above too) */
- if (prevfpt->vec[0] < v2d->cur.xmax) {
- v[0] = v2d->cur.xmax;
-
- /* y-value depends on the interpolation */
- if ((fcu->extend == FCURVE_EXTRAPOLATE_CONSTANT) || (fcu->flag & FCURVE_INT_VALUES) || (fcu->totvert == 1)) {
- /* based on last keyframe's value */
- v[1] = prevfpt->vec[1];
- }
- else {
- /* extrapolate linear doesn't use the handle, use the previous points center instead */
- fpt = prevfpt - 1;
- fac = (prevfpt->vec[0] - fpt->vec[0]) / (prevfpt->vec[0] - v[0]);
- if (fac) fac = 1.0f / fac;
- v[1] = prevfpt->vec[1] - fac * (prevfpt->vec[1] - fpt->vec[1]);
- }
-
- immVertex2fv(shdr_pos, v);
- }
-
- immEnd();
-
- GPU_matrix_pop();
+ FPoint *prevfpt = fcu->fpt;
+ FPoint *fpt = prevfpt + 1;
+ float fac, v[2];
+ int b = fcu->totvert;
+ float unit_scale, offset;
+ short mapping_flag = ANIM_get_normalization_flags(ac);
+ int count = fcu->totvert;
+
+ if (prevfpt->vec[0] > v2d->cur.xmin) {
+ count++;
+ }
+
+ if ((prevfpt + b - 1)->vec[0] < v2d->cur.xmax) {
+ count++;
+ }
+
+ /* apply unit mapping */
+ GPU_matrix_push();
+ unit_scale = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag, &offset);
+ GPU_matrix_scale_2f(1.0f, unit_scale);
+ GPU_matrix_translate_2f(0.0f, offset);
+
+ immBegin(GPU_PRIM_LINE_STRIP, count);
+
+ /* extrapolate to left? - left-side of view comes before first keyframe? */
+ if (prevfpt->vec[0] > v2d->cur.xmin) {
+ v[0] = v2d->cur.xmin;
+
+ /* y-value depends on the interpolation */
+ if ((fcu->extend == FCURVE_EXTRAPOLATE_CONSTANT) || (fcu->flag & FCURVE_INT_VALUES) ||
+ (fcu->totvert == 1)) {
+ /* just extend across the first keyframe's value */
+ v[1] = prevfpt->vec[1];
+ }
+ else {
+ /* extrapolate linear doesn't use the handle, use the next points center instead */
+ fac = (prevfpt->vec[0] - fpt->vec[0]) / (prevfpt->vec[0] - v[0]);
+ if (fac)
+ fac = 1.0f / fac;
+ v[1] = prevfpt->vec[1] - fac * (prevfpt->vec[1] - fpt->vec[1]);
+ }
+
+ immVertex2fv(shdr_pos, v);
+ }
+
+ /* loop over samples, drawing segments */
+ /* draw curve between first and last keyframe (if there are enough to do so) */
+ while (b--) {
+ /* Linear interpolation: just add one point (which should add a new line segment) */
+ immVertex2fv(shdr_pos, prevfpt->vec);
+
+ /* get next pointers */
+ if (b > 0) {
+ prevfpt++;
+ }
+ }
+
+ /* extrapolate to right? (see code for left-extrapolation above too) */
+ if (prevfpt->vec[0] < v2d->cur.xmax) {
+ v[0] = v2d->cur.xmax;
+
+ /* y-value depends on the interpolation */
+ if ((fcu->extend == FCURVE_EXTRAPOLATE_CONSTANT) || (fcu->flag & FCURVE_INT_VALUES) ||
+ (fcu->totvert == 1)) {
+ /* based on last keyframe's value */
+ v[1] = prevfpt->vec[1];
+ }
+ else {
+ /* extrapolate linear doesn't use the handle, use the previous points center instead */
+ fpt = prevfpt - 1;
+ fac = (prevfpt->vec[0] - fpt->vec[0]) / (prevfpt->vec[0] - v[0]);
+ if (fac)
+ fac = 1.0f / fac;
+ v[1] = prevfpt->vec[1] - fac * (prevfpt->vec[1] - fpt->vec[1]);
+ }
+
+ immVertex2fv(shdr_pos, v);
+ }
+
+ immEnd();
+
+ GPU_matrix_pop();
}
/* helper func - check if the F-Curve only contains easily drawable segments
@@ -657,183 +661,192 @@ static void draw_fcurve_curve_samples(bAnimContext *ac, ID *id, FCurve *fcu, Vie
*/
static bool fcurve_can_use_simple_bezt_drawing(FCurve *fcu)
{
- BezTriple *bezt;
- int i;
+ BezTriple *bezt;
+ int i;
- for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
- if (ELEM(bezt->ipo, BEZT_IPO_CONST, BEZT_IPO_LIN, BEZT_IPO_BEZ) == false) {
- return false;
- }
- }
+ for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
+ if (ELEM(bezt->ipo, BEZT_IPO_CONST, BEZT_IPO_LIN, BEZT_IPO_BEZ) == false) {
+ return false;
+ }
+ }
- return true;
+ return true;
}
/* helper func - draw one repeat of an F-Curve (using Bezier curve approximations) */
-static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d, unsigned int pos)
+static void draw_fcurve_curve_bezts(
+ bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d, unsigned int pos)
{
- BezTriple *prevbezt = fcu->bezt;
- BezTriple *bezt = prevbezt + 1;
- float v1[2], v2[2], v3[2], v4[2];
- float *fp, data[120];
- float fac = 0.0f;
- int b = fcu->totvert - 1;
- int resol;
- float unit_scale, offset;
- short mapping_flag = ANIM_get_normalization_flags(ac);
-
- /* apply unit mapping */
- GPU_matrix_push();
- unit_scale = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag, &offset);
- GPU_matrix_scale_2f(1.0f, unit_scale);
- GPU_matrix_translate_2f(0.0f, offset);
-
- /* For now, this assumes the worst case scenario, where all the keyframes have
- * bezier interpolation, and are drawn at full res.
- * This is tricky to optimize, but maybe can be improved at some point... */
- immBeginAtMost(GPU_PRIM_LINE_STRIP, (b * 32 + 3));
-
- /* extrapolate to left? */
- if (prevbezt->vec[1][0] > v2d->cur.xmin) {
- /* left-side of view comes before first keyframe, so need to extend as not cyclic */
- v1[0] = v2d->cur.xmin;
-
- /* y-value depends on the interpolation */
- if ((fcu->extend == FCURVE_EXTRAPOLATE_CONSTANT) || (prevbezt->ipo == BEZT_IPO_CONST) || (fcu->totvert == 1)) {
- /* just extend across the first keyframe's value */
- v1[1] = prevbezt->vec[1][1];
- }
- else if (prevbezt->ipo == BEZT_IPO_LIN) {
- /* extrapolate linear dosnt use the handle, use the next points center instead */
- fac = (prevbezt->vec[1][0] - bezt->vec[1][0]) / (prevbezt->vec[1][0] - v1[0]);
- if (fac) fac = 1.0f / fac;
- v1[1] = prevbezt->vec[1][1] - fac * (prevbezt->vec[1][1] - bezt->vec[1][1]);
- }
- else {
- /* based on angle of handle 1 (relative to keyframe) */
- fac = (prevbezt->vec[0][0] - prevbezt->vec[1][0]) / (prevbezt->vec[1][0] - v1[0]);
- if (fac) fac = 1.0f / fac;
- v1[1] = prevbezt->vec[1][1] - fac * (prevbezt->vec[0][1] - prevbezt->vec[1][1]);
- }
-
- immVertex2fv(pos, v1);
- }
-
- /* if only one keyframe, add it now */
- if (fcu->totvert == 1) {
- v1[0] = prevbezt->vec[1][0];
- v1[1] = prevbezt->vec[1][1];
- immVertex2fv(pos, v1);
- }
-
- /* draw curve between first and last keyframe (if there are enough to do so) */
- /* TODO: optimize this to not have to calc stuff out of view too? */
- while (b--) {
- if (prevbezt->ipo == BEZT_IPO_CONST) {
- /* Constant-Interpolation: draw segment between previous keyframe and next,
- * but holding same value */
- v1[0] = prevbezt->vec[1][0];
- v1[1] = prevbezt->vec[1][1];
- immVertex2fv(pos, v1);
-
- v1[0] = bezt->vec[1][0];
- v1[1] = prevbezt->vec[1][1];
- immVertex2fv(pos, v1);
- }
- else if (prevbezt->ipo == BEZT_IPO_LIN) {
- /* Linear interpolation: just add one point (which should add a new line segment) */
- v1[0] = prevbezt->vec[1][0];
- v1[1] = prevbezt->vec[1][1];
- immVertex2fv(pos, v1);
- }
- else if (prevbezt->ipo == BEZT_IPO_BEZ) {
- /* Bezier-Interpolation: draw curve as series of segments between keyframes
- * - resol determines number of points to sample in between keyframes
- */
-
- /* resol depends on distance between points
- * (not just horizontal) OR is a fixed high res */
- /* TODO: view scale should factor into this someday too... */
- if (fcu->driver) {
- resol = 32;
- }
- else {
- resol = (int)(5.0f * len_v2v2(bezt->vec[1], prevbezt->vec[1]));
- }
-
- if (resol < 2) {
- /* only draw one */
- v1[0] = prevbezt->vec[1][0];
- v1[1] = prevbezt->vec[1][1];
- immVertex2fv(pos, v1);
- }
- else {
- /* clamp resolution to max of 32 */
- /* NOTE: higher values will crash */
- if (resol > 32) resol = 32;
-
- v1[0] = prevbezt->vec[1][0];
- v1[1] = prevbezt->vec[1][1];
- v2[0] = prevbezt->vec[2][0];
- v2[1] = prevbezt->vec[2][1];
-
- v3[0] = bezt->vec[0][0];
- v3[1] = bezt->vec[0][1];
- v4[0] = bezt->vec[1][0];
- v4[1] = bezt->vec[1][1];
-
- correct_bezpart(v1, v2, v3, v4);
-
- BKE_curve_forward_diff_bezier(v1[0], v2[0], v3[0], v4[0], data, resol, sizeof(float) * 3);
- BKE_curve_forward_diff_bezier(v1[1], v2[1], v3[1], v4[1], data + 1, resol, sizeof(float) * 3);
-
- for (fp = data; resol; resol--, fp += 3) {
- immVertex2fv(pos, fp);
- }
- }
- }
-
- /* get next pointers */
- prevbezt = bezt;
- bezt++;
-
- /* last point? */
- if (b == 0) {
- v1[0] = prevbezt->vec[1][0];
- v1[1] = prevbezt->vec[1][1];
- immVertex2fv(pos, v1);
- }
- }
-
- /* extrapolate to right? (see code for left-extrapolation above too) */
- if (prevbezt->vec[1][0] < v2d->cur.xmax) {
- v1[0] = v2d->cur.xmax;
-
- /* y-value depends on the interpolation */
- if ((fcu->extend == FCURVE_EXTRAPOLATE_CONSTANT) || (fcu->flag & FCURVE_INT_VALUES) || (prevbezt->ipo == BEZT_IPO_CONST) || (fcu->totvert == 1)) {
- /* based on last keyframe's value */
- v1[1] = prevbezt->vec[1][1];
- }
- else if (prevbezt->ipo == BEZT_IPO_LIN) {
- /* extrapolate linear dosnt use the handle, use the previous points center instead */
- bezt = prevbezt - 1;
- fac = (prevbezt->vec[1][0] - bezt->vec[1][0]) / (prevbezt->vec[1][0] - v1[0]);
- if (fac) fac = 1.0f / fac;
- v1[1] = prevbezt->vec[1][1] - fac * (prevbezt->vec[1][1] - bezt->vec[1][1]);
- }
- else {
- /* based on angle of handle 1 (relative to keyframe) */
- fac = (prevbezt->vec[2][0] - prevbezt->vec[1][0]) / (prevbezt->vec[1][0] - v1[0]);
- if (fac) fac = 1.0f / fac;
- v1[1] = prevbezt->vec[1][1] - fac * (prevbezt->vec[2][1] - prevbezt->vec[1][1]);
- }
-
- immVertex2fv(pos, v1);
- }
-
- immEnd();
-
- GPU_matrix_pop();
+ BezTriple *prevbezt = fcu->bezt;
+ BezTriple *bezt = prevbezt + 1;
+ float v1[2], v2[2], v3[2], v4[2];
+ float *fp, data[120];
+ float fac = 0.0f;
+ int b = fcu->totvert - 1;
+ int resol;
+ float unit_scale, offset;
+ short mapping_flag = ANIM_get_normalization_flags(ac);
+
+ /* apply unit mapping */
+ GPU_matrix_push();
+ unit_scale = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag, &offset);
+ GPU_matrix_scale_2f(1.0f, unit_scale);
+ GPU_matrix_translate_2f(0.0f, offset);
+
+ /* For now, this assumes the worst case scenario, where all the keyframes have
+ * bezier interpolation, and are drawn at full res.
+ * This is tricky to optimize, but maybe can be improved at some point... */
+ immBeginAtMost(GPU_PRIM_LINE_STRIP, (b * 32 + 3));
+
+ /* extrapolate to left? */
+ if (prevbezt->vec[1][0] > v2d->cur.xmin) {
+ /* left-side of view comes before first keyframe, so need to extend as not cyclic */
+ v1[0] = v2d->cur.xmin;
+
+ /* y-value depends on the interpolation */
+ if ((fcu->extend == FCURVE_EXTRAPOLATE_CONSTANT) || (prevbezt->ipo == BEZT_IPO_CONST) ||
+ (fcu->totvert == 1)) {
+ /* just extend across the first keyframe's value */
+ v1[1] = prevbezt->vec[1][1];
+ }
+ else if (prevbezt->ipo == BEZT_IPO_LIN) {
+ /* extrapolate linear dosnt use the handle, use the next points center instead */
+ fac = (prevbezt->vec[1][0] - bezt->vec[1][0]) / (prevbezt->vec[1][0] - v1[0]);
+ if (fac)
+ fac = 1.0f / fac;
+ v1[1] = prevbezt->vec[1][1] - fac * (prevbezt->vec[1][1] - bezt->vec[1][1]);
+ }
+ else {
+ /* based on angle of handle 1 (relative to keyframe) */
+ fac = (prevbezt->vec[0][0] - prevbezt->vec[1][0]) / (prevbezt->vec[1][0] - v1[0]);
+ if (fac)
+ fac = 1.0f / fac;
+ v1[1] = prevbezt->vec[1][1] - fac * (prevbezt->vec[0][1] - prevbezt->vec[1][1]);
+ }
+
+ immVertex2fv(pos, v1);
+ }
+
+ /* if only one keyframe, add it now */
+ if (fcu->totvert == 1) {
+ v1[0] = prevbezt->vec[1][0];
+ v1[1] = prevbezt->vec[1][1];
+ immVertex2fv(pos, v1);
+ }
+
+ /* draw curve between first and last keyframe (if there are enough to do so) */
+ /* TODO: optimize this to not have to calc stuff out of view too? */
+ while (b--) {
+ if (prevbezt->ipo == BEZT_IPO_CONST) {
+ /* Constant-Interpolation: draw segment between previous keyframe and next,
+ * but holding same value */
+ v1[0] = prevbezt->vec[1][0];
+ v1[1] = prevbezt->vec[1][1];
+ immVertex2fv(pos, v1);
+
+ v1[0] = bezt->vec[1][0];
+ v1[1] = prevbezt->vec[1][1];
+ immVertex2fv(pos, v1);
+ }
+ else if (prevbezt->ipo == BEZT_IPO_LIN) {
+ /* Linear interpolation: just add one point (which should add a new line segment) */
+ v1[0] = prevbezt->vec[1][0];
+ v1[1] = prevbezt->vec[1][1];
+ immVertex2fv(pos, v1);
+ }
+ else if (prevbezt->ipo == BEZT_IPO_BEZ) {
+ /* Bezier-Interpolation: draw curve as series of segments between keyframes
+ * - resol determines number of points to sample in between keyframes
+ */
+
+ /* resol depends on distance between points
+ * (not just horizontal) OR is a fixed high res */
+ /* TODO: view scale should factor into this someday too... */
+ if (fcu->driver) {
+ resol = 32;
+ }
+ else {
+ resol = (int)(5.0f * len_v2v2(bezt->vec[1], prevbezt->vec[1]));
+ }
+
+ if (resol < 2) {
+ /* only draw one */
+ v1[0] = prevbezt->vec[1][0];
+ v1[1] = prevbezt->vec[1][1];
+ immVertex2fv(pos, v1);
+ }
+ else {
+ /* clamp resolution to max of 32 */
+ /* NOTE: higher values will crash */
+ if (resol > 32)
+ resol = 32;
+
+ v1[0] = prevbezt->vec[1][0];
+ v1[1] = prevbezt->vec[1][1];
+ v2[0] = prevbezt->vec[2][0];
+ v2[1] = prevbezt->vec[2][1];
+
+ v3[0] = bezt->vec[0][0];
+ v3[1] = bezt->vec[0][1];
+ v4[0] = bezt->vec[1][0];
+ v4[1] = bezt->vec[1][1];
+
+ correct_bezpart(v1, v2, v3, v4);
+
+ BKE_curve_forward_diff_bezier(v1[0], v2[0], v3[0], v4[0], data, resol, sizeof(float) * 3);
+ BKE_curve_forward_diff_bezier(
+ v1[1], v2[1], v3[1], v4[1], data + 1, resol, sizeof(float) * 3);
+
+ for (fp = data; resol; resol--, fp += 3) {
+ immVertex2fv(pos, fp);
+ }
+ }
+ }
+
+ /* get next pointers */
+ prevbezt = bezt;
+ bezt++;
+
+ /* last point? */
+ if (b == 0) {
+ v1[0] = prevbezt->vec[1][0];
+ v1[1] = prevbezt->vec[1][1];
+ immVertex2fv(pos, v1);
+ }
+ }
+
+ /* extrapolate to right? (see code for left-extrapolation above too) */
+ if (prevbezt->vec[1][0] < v2d->cur.xmax) {
+ v1[0] = v2d->cur.xmax;
+
+ /* y-value depends on the interpolation */
+ if ((fcu->extend == FCURVE_EXTRAPOLATE_CONSTANT) || (fcu->flag & FCURVE_INT_VALUES) ||
+ (prevbezt->ipo == BEZT_IPO_CONST) || (fcu->totvert == 1)) {
+ /* based on last keyframe's value */
+ v1[1] = prevbezt->vec[1][1];
+ }
+ else if (prevbezt->ipo == BEZT_IPO_LIN) {
+ /* extrapolate linear dosnt use the handle, use the previous points center instead */
+ bezt = prevbezt - 1;
+ fac = (prevbezt->vec[1][0] - bezt->vec[1][0]) / (prevbezt->vec[1][0] - v1[0]);
+ if (fac)
+ fac = 1.0f / fac;
+ v1[1] = prevbezt->vec[1][1] - fac * (prevbezt->vec[1][1] - bezt->vec[1][1]);
+ }
+ else {
+ /* based on angle of handle 1 (relative to keyframe) */
+ fac = (prevbezt->vec[2][0] - prevbezt->vec[1][0]) / (prevbezt->vec[1][0] - v1[0]);
+ if (fac)
+ fac = 1.0f / fac;
+ v1[1] = prevbezt->vec[1][1] - fac * (prevbezt->vec[2][1] - prevbezt->vec[1][1]);
+ }
+
+ immVertex2fv(pos, v1);
+ }
+
+ immEnd();
+
+ GPU_matrix_pop();
}
/* Debugging -------------------------------- */
@@ -845,116 +858,117 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2
*/
static void graph_draw_driver_debug(bAnimContext *ac, ID *id, FCurve *fcu)
{
- ChannelDriver *driver = fcu->driver;
- View2D *v2d = &ac->ar->v2d;
- short mapping_flag = ANIM_get_normalization_flags(ac);
- float offset;
- float unitfac = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag, &offset);
+ ChannelDriver *driver = fcu->driver;
+ View2D *v2d = &ac->ar->v2d;
+ short mapping_flag = ANIM_get_normalization_flags(ac);
+ float offset;
+ float unitfac = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag, &offset);
- /* for now, only show when debugging driver... */
- //if ((driver->flag & DRIVER_FLAG_SHOWDEBUG) == 0)
- // return;
+ /* for now, only show when debugging driver... */
+ //if ((driver->flag & DRIVER_FLAG_SHOWDEBUG) == 0)
+ // return;
- const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
+ const uint shdr_pos = GPU_vertformat_attr_add(
+ immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
- float viewport_size[4];
- GPU_viewport_size_get_f(viewport_size);
- immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
+ float viewport_size[4];
+ GPU_viewport_size_get_f(viewport_size);
+ immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
- immUniform1i("colors_len", 0); /* Simple dashes. */
+ immUniform1i("colors_len", 0); /* Simple dashes. */
- /* No curve to modify/visualize the result?
- * => We still want to show the 1-1 default...
- */
- if ((fcu->totvert == 0) && BLI_listbase_is_empty(&fcu->modifiers)) {
- float t;
+ /* No curve to modify/visualize the result?
+ * => We still want to show the 1-1 default...
+ */
+ if ((fcu->totvert == 0) && BLI_listbase_is_empty(&fcu->modifiers)) {
+ float t;
- /* draw with thin dotted lines in style of what curve would have been */
- immUniformColor3fv(fcu->color);
+ /* draw with thin dotted lines in style of what curve would have been */
+ immUniformColor3fv(fcu->color);
- immUniform1f("dash_width", 40.0f);
- immUniform1f("dash_factor", 0.5f);
- GPU_line_width(2.0f);
+ immUniform1f("dash_width", 40.0f);
+ immUniform1f("dash_factor", 0.5f);
+ GPU_line_width(2.0f);
- /* draw 1-1 line, stretching just past the screen limits
- * NOTE: we need to scale the y-values to be valid for the units
- */
- immBegin(GPU_PRIM_LINES, 2);
+ /* draw 1-1 line, stretching just past the screen limits
+ * NOTE: we need to scale the y-values to be valid for the units
+ */
+ immBegin(GPU_PRIM_LINES, 2);
- t = v2d->cur.xmin;
- immVertex2f(shdr_pos, t, (t + offset) * unitfac);
+ t = v2d->cur.xmin;
+ immVertex2f(shdr_pos, t, (t + offset) * unitfac);
- t = v2d->cur.xmax;
- immVertex2f(shdr_pos, t, (t + offset) * unitfac);
+ t = v2d->cur.xmax;
+ immVertex2f(shdr_pos, t, (t + offset) * unitfac);
- immEnd();
- }
+ immEnd();
+ }
- /* draw driver only if actually functional */
- if ((driver->flag & DRIVER_FLAG_INVALID) == 0) {
- /* grab "coordinates" for driver outputs */
- float x = driver->curval;
- float y = fcu->curval * unitfac;
+ /* draw driver only if actually functional */
+ if ((driver->flag & DRIVER_FLAG_INVALID) == 0) {
+ /* grab "coordinates" for driver outputs */
+ float x = driver->curval;
+ float y = fcu->curval * unitfac;
- /* only draw indicators if the point is in range*/
- if (x >= v2d->cur.xmin) {
- float co[2];
+ /* only draw indicators if the point is in range*/
+ if (x >= v2d->cur.xmin) {
+ float co[2];
- /* draw dotted lines leading towards this point from both axes ....... */
- immUniformColor3f(0.9f, 0.9f, 0.9f);
- immUniform1f("dash_width", 10.0f);
- immUniform1f("dash_factor", 0.5f);
+ /* draw dotted lines leading towards this point from both axes ....... */
+ immUniformColor3f(0.9f, 0.9f, 0.9f);
+ immUniform1f("dash_width", 10.0f);
+ immUniform1f("dash_factor", 0.5f);
- immBegin(GPU_PRIM_LINES, (y >= v2d->cur.ymin) ? 4 : 2);
+ immBegin(GPU_PRIM_LINES, (y >= v2d->cur.ymin) ? 4 : 2);
- /* x-axis lookup */
- co[0] = x;
+ /* x-axis lookup */
+ co[0] = x;
- if (y >= v2d->cur.ymin) {
- co[1] = v2d->cur.ymin - 1.0f;
- immVertex2fv(shdr_pos, co);
+ if (y >= v2d->cur.ymin) {
+ co[1] = v2d->cur.ymin - 1.0f;
+ immVertex2fv(shdr_pos, co);
- co[1] = y;
- immVertex2fv(shdr_pos, co);
- }
+ co[1] = y;
+ immVertex2fv(shdr_pos, co);
+ }
- /* y-axis lookup */
- co[1] = y;
+ /* y-axis lookup */
+ co[1] = y;
- co[0] = v2d->cur.xmin - 1.0f;
- immVertex2fv(shdr_pos, co);
+ co[0] = v2d->cur.xmin - 1.0f;
+ immVertex2fv(shdr_pos, co);
- co[0] = x;
- immVertex2fv(shdr_pos, co);
+ co[0] = x;
+ immVertex2fv(shdr_pos, co);
- immEnd();
+ immEnd();
- immUnbindProgram();
+ immUnbindProgram();
- /* GPU_PRIM_POINTS do not survive dashed line geometry shader... */
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ /* GPU_PRIM_POINTS do not survive dashed line geometry shader... */
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- /* x marks the spot .................................................... */
- /* -> outer frame */
- immUniformColor3f(0.9f, 0.9f, 0.9f);
- GPU_point_size(7.0);
+ /* x marks the spot .................................................... */
+ /* -> outer frame */
+ immUniformColor3f(0.9f, 0.9f, 0.9f);
+ GPU_point_size(7.0);
- immBegin(GPU_PRIM_POINTS, 1);
- immVertex2f(shdr_pos, x, y);
- immEnd();
+ immBegin(GPU_PRIM_POINTS, 1);
+ immVertex2f(shdr_pos, x, y);
+ immEnd();
- /* inner frame */
- immUniformColor3f(0.9f, 0.0f, 0.0f);
- GPU_point_size(3.0);
+ /* inner frame */
+ immUniformColor3f(0.9f, 0.0f, 0.0f);
+ GPU_point_size(3.0);
- immBegin(GPU_PRIM_POINTS, 1);
- immVertex2f(shdr_pos, x, y);
- immEnd();
- }
- }
+ immBegin(GPU_PRIM_POINTS, 1);
+ immVertex2f(shdr_pos, x, y);
+ immEnd();
+ }
+ }
- immUnbindProgram();
+ immUnbindProgram();
}
/* Public Curve-Drawing API ---------------- */
@@ -964,224 +978,227 @@ static void graph_draw_driver_debug(bAnimContext *ac, ID *id, FCurve *fcu)
*/
void graph_draw_ghost_curves(bAnimContext *ac, SpaceGraph *sipo, ARegion *ar)
{
- FCurve *fcu;
+ FCurve *fcu;
- /* draw with thick dotted lines */
- GPU_line_width(3.0f);
+ /* draw with thick dotted lines */
+ GPU_line_width(3.0f);
- /* anti-aliased lines for less jagged appearance */
- if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) {
- GPU_line_smooth(true);
- }
- GPU_blend(true);
+ /* anti-aliased lines for less jagged appearance */
+ if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) {
+ GPU_line_smooth(true);
+ }
+ GPU_blend(true);
- const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ const uint shdr_pos = GPU_vertformat_attr_add(
+ immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
- float viewport_size[4];
- GPU_viewport_size_get_f(viewport_size);
- immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
+ float viewport_size[4];
+ GPU_viewport_size_get_f(viewport_size);
+ immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
- immUniform1i("colors_len", 0); /* Simple dashes. */
- immUniform1f("dash_width", 20.0f);
- immUniform1f("dash_factor", 0.5f);
+ immUniform1i("colors_len", 0); /* Simple dashes. */
+ immUniform1f("dash_width", 20.0f);
+ immUniform1f("dash_factor", 0.5f);
- /* the ghost curves are simply sampled F-Curves stored in sipo->runtime.ghost_curves */
- for (fcu = sipo->runtime.ghost_curves.first; fcu; fcu = fcu->next) {
- /* set whatever color the curve has set
- * - this is set by the function which creates these
- * - draw with a fixed opacity of 2
- */
- immUniformColor3fvAlpha(fcu->color, 0.5f);
+ /* the ghost curves are simply sampled F-Curves stored in sipo->runtime.ghost_curves */
+ for (fcu = sipo->runtime.ghost_curves.first; fcu; fcu = fcu->next) {
+ /* set whatever color the curve has set
+ * - this is set by the function which creates these
+ * - draw with a fixed opacity of 2
+ */
+ immUniformColor3fvAlpha(fcu->color, 0.5f);
- /* simply draw the stored samples */
- draw_fcurve_curve_samples(ac, NULL, fcu, &ar->v2d, shdr_pos);
- }
+ /* simply draw the stored samples */
+ draw_fcurve_curve_samples(ac, NULL, fcu, &ar->v2d, shdr_pos);
+ }
- immUnbindProgram();
+ immUnbindProgram();
- if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) {
- GPU_line_smooth(false);
- }
- GPU_blend(false);
+ if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) {
+ GPU_line_smooth(false);
+ }
+ GPU_blend(false);
}
/* This is called twice from space_graph.c -> graph_main_region_draw()
* Unselected then selected F-Curves are drawn so that they do not occlude each other.
*/
-void graph_draw_curves(bAnimContext *ac, SpaceGraph *sipo, ARegion *ar, View2DGrid *grid, short sel)
+void graph_draw_curves(
+ bAnimContext *ac, SpaceGraph *sipo, ARegion *ar, View2DGrid *grid, short sel)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- /* build list of curves to draw */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE);
- filter |= ((sel) ? (ANIMFILTER_SEL) : (ANIMFILTER_UNSEL));
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* for each curve:
- * draw curve, then handle-lines, and finally vertices in this order so that
- * the data will be layered correctly
- */
- for (ale = anim_data.first; ale; ale = ale->next) {
- FCurve *fcu = (FCurve *)ale->key_data;
- FModifier *fcm = find_active_fmodifier(&fcu->modifiers);
- AnimData *adt = ANIM_nla_mapping_get(ac, ale);
-
- /* map keyframes for drawing if scaled F-Curve */
- if (adt) {
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0);
- }
-
- /* draw curve:
- * - curve line may be result of one or more destructive modifiers or just the raw data,
- * so we need to check which method should be used
- * - controls from active modifier take precedence over keyframes
- * (XXX! editing tools need to take this into account!)
- */
-
- /* 1) draw curve line */
- if (((fcu->modifiers.first) || (fcu->flag & FCURVE_INT_VALUES)) ||
- (((fcu->bezt) || (fcu->fpt)) && (fcu->totvert)))
- {
- /* set color/drawing style for curve itself */
- /* draw active F-Curve thicker than the rest to make it stand out */
- if (fcu->flag & FCURVE_ACTIVE) {
- GPU_line_width(2.5);
- }
- else {
- GPU_line_width(1.0);
- }
-
- /* anti-aliased lines for less jagged appearance */
- if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) {
- GPU_line_smooth(true);
- }
- GPU_blend(true);
-
- const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
-
- immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
-
- float viewport_size[4];
- GPU_viewport_size_get_f(viewport_size);
- immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
-
- immUniform1i("colors_len", 0); /* Simple dashes. */
-
- if (BKE_fcurve_is_protected(fcu)) {
- /* protected curves (non editable) are drawn with dotted lines */
- immUniform1f("dash_width", 4.0f);
- immUniform1f("dash_factor", 0.5f);
- }
- else {
- immUniform1f("dash_factor", 2.0f); /* solid line */
- }
-
- if (((fcu->grp) && (fcu->grp->flag & AGRP_MUTED)) || (fcu->flag & FCURVE_MUTED)) {
- /* muted curves are drawn in a grayish hue */
- /* XXX should we have some variations? */
- immUniformThemeColorShade(TH_HEADER, 50);
- }
- else {
- /* set whatever color the curve has set
- * - unselected curves draw less opaque to help distinguish the selected ones
- */
- immUniformColor3fvAlpha(fcu->color, fcurve_display_alpha(fcu));
- }
-
- /* draw F-Curve */
- if ((fcu->modifiers.first) || (fcu->flag & FCURVE_INT_VALUES)) {
- /* draw a curve affected by modifiers or only allowed to have integer values
- * by sampling it at various small-intervals over the visible region
- */
- draw_fcurve_curve(ac, ale->id, fcu, &ar->v2d, grid, shdr_pos);
- }
- else if (((fcu->bezt) || (fcu->fpt)) && (fcu->totvert)) {
- /* just draw curve based on defined data (i.e. no modifiers) */
- if (fcu->bezt) {
- if (fcurve_can_use_simple_bezt_drawing(fcu)) {
- draw_fcurve_curve_bezts(ac, ale->id, fcu, &ar->v2d, shdr_pos);
- }
- else {
- draw_fcurve_curve(ac, ale->id, fcu, &ar->v2d, grid, shdr_pos);
- }
- }
- else if (fcu->fpt) {
- draw_fcurve_curve_samples(ac, ale->id, fcu, &ar->v2d, shdr_pos);
- }
- }
-
- immUnbindProgram();
-
- if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) {
- GPU_line_smooth(false);
- }
- GPU_blend(false);
- }
-
- /* 2) draw handles and vertices as appropriate based on active
- * - if the option to only show controls if the F-Curve is selected is enabled, we must obey this
- */
- if (!(sipo->flag & SIPO_SELCUVERTSONLY) || (fcu->flag & FCURVE_SELECTED)) {
- if (!fcurve_are_keyframes_usable(fcu) && !(fcu->fpt && fcu->totvert)) {
- /* only draw controls if this is the active modifier */
- if ((fcu->flag & FCURVE_ACTIVE) && (fcm)) {
- switch (fcm->type) {
- case FMODIFIER_TYPE_ENVELOPE: /* envelope */
- draw_fcurve_modifier_controls_envelope(fcm, &ar->v2d);
- break;
- }
- }
- }
- else if (((fcu->bezt) || (fcu->fpt)) && (fcu->totvert)) {
- short mapping_flag = ANIM_get_normalization_flags(ac);
- float offset;
- float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag, &offset);
-
- /* apply unit-scaling to all values via OpenGL */
- GPU_matrix_push();
- GPU_matrix_scale_2f(1.0f, unit_scale);
- GPU_matrix_translate_2f(0.0f, offset);
-
- /* set this once and for all - all handles and handle-verts should use the same thickness */
- GPU_line_width(1.0);
-
- if (fcu->bezt) {
- bool do_handles = draw_fcurve_handles_check(sipo, fcu);
-
- if (do_handles) {
- /* only draw handles/vertices on keyframes */
- GPU_blend(true);
- draw_fcurve_handles(sipo, fcu);
- GPU_blend(false);
- }
-
- draw_fcurve_vertices(ar, fcu, do_handles, (sipo->flag & SIPO_SELVHANDLESONLY));
- }
- else {
- /* samples: only draw two indicators at either end as indicators */
- draw_fcurve_samples(sipo, ar, fcu);
- }
-
- GPU_matrix_pop();
- }
- }
-
- /* 3) draw driver debugging stuff */
- if ((ac->datatype == ANIMCONT_DRIVERS) && (fcu->flag & FCURVE_ACTIVE)) {
- graph_draw_driver_debug(ac, ale->id, fcu);
- }
-
- /* undo mapping of keyframes for drawing if scaled F-Curve */
- if (adt)
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 0);
- }
-
- /* free list of curves */
- ANIM_animdata_freelist(&anim_data);
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ /* build list of curves to draw */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE);
+ filter |= ((sel) ? (ANIMFILTER_SEL) : (ANIMFILTER_UNSEL));
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* for each curve:
+ * draw curve, then handle-lines, and finally vertices in this order so that
+ * the data will be layered correctly
+ */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ FCurve *fcu = (FCurve *)ale->key_data;
+ FModifier *fcm = find_active_fmodifier(&fcu->modifiers);
+ AnimData *adt = ANIM_nla_mapping_get(ac, ale);
+
+ /* map keyframes for drawing if scaled F-Curve */
+ if (adt) {
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0);
+ }
+
+ /* draw curve:
+ * - curve line may be result of one or more destructive modifiers or just the raw data,
+ * so we need to check which method should be used
+ * - controls from active modifier take precedence over keyframes
+ * (XXX! editing tools need to take this into account!)
+ */
+
+ /* 1) draw curve line */
+ if (((fcu->modifiers.first) || (fcu->flag & FCURVE_INT_VALUES)) ||
+ (((fcu->bezt) || (fcu->fpt)) && (fcu->totvert))) {
+ /* set color/drawing style for curve itself */
+ /* draw active F-Curve thicker than the rest to make it stand out */
+ if (fcu->flag & FCURVE_ACTIVE) {
+ GPU_line_width(2.5);
+ }
+ else {
+ GPU_line_width(1.0);
+ }
+
+ /* anti-aliased lines for less jagged appearance */
+ if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) {
+ GPU_line_smooth(true);
+ }
+ GPU_blend(true);
+
+ const uint shdr_pos = GPU_vertformat_attr_add(
+ immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
+
+ float viewport_size[4];
+ GPU_viewport_size_get_f(viewport_size);
+ immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
+
+ immUniform1i("colors_len", 0); /* Simple dashes. */
+
+ if (BKE_fcurve_is_protected(fcu)) {
+ /* protected curves (non editable) are drawn with dotted lines */
+ immUniform1f("dash_width", 4.0f);
+ immUniform1f("dash_factor", 0.5f);
+ }
+ else {
+ immUniform1f("dash_factor", 2.0f); /* solid line */
+ }
+
+ if (((fcu->grp) && (fcu->grp->flag & AGRP_MUTED)) || (fcu->flag & FCURVE_MUTED)) {
+ /* muted curves are drawn in a grayish hue */
+ /* XXX should we have some variations? */
+ immUniformThemeColorShade(TH_HEADER, 50);
+ }
+ else {
+ /* set whatever color the curve has set
+ * - unselected curves draw less opaque to help distinguish the selected ones
+ */
+ immUniformColor3fvAlpha(fcu->color, fcurve_display_alpha(fcu));
+ }
+
+ /* draw F-Curve */
+ if ((fcu->modifiers.first) || (fcu->flag & FCURVE_INT_VALUES)) {
+ /* draw a curve affected by modifiers or only allowed to have integer values
+ * by sampling it at various small-intervals over the visible region
+ */
+ draw_fcurve_curve(ac, ale->id, fcu, &ar->v2d, grid, shdr_pos);
+ }
+ else if (((fcu->bezt) || (fcu->fpt)) && (fcu->totvert)) {
+ /* just draw curve based on defined data (i.e. no modifiers) */
+ if (fcu->bezt) {
+ if (fcurve_can_use_simple_bezt_drawing(fcu)) {
+ draw_fcurve_curve_bezts(ac, ale->id, fcu, &ar->v2d, shdr_pos);
+ }
+ else {
+ draw_fcurve_curve(ac, ale->id, fcu, &ar->v2d, grid, shdr_pos);
+ }
+ }
+ else if (fcu->fpt) {
+ draw_fcurve_curve_samples(ac, ale->id, fcu, &ar->v2d, shdr_pos);
+ }
+ }
+
+ immUnbindProgram();
+
+ if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) {
+ GPU_line_smooth(false);
+ }
+ GPU_blend(false);
+ }
+
+ /* 2) draw handles and vertices as appropriate based on active
+ * - if the option to only show controls if the F-Curve is selected is enabled, we must obey this
+ */
+ if (!(sipo->flag & SIPO_SELCUVERTSONLY) || (fcu->flag & FCURVE_SELECTED)) {
+ if (!fcurve_are_keyframes_usable(fcu) && !(fcu->fpt && fcu->totvert)) {
+ /* only draw controls if this is the active modifier */
+ if ((fcu->flag & FCURVE_ACTIVE) && (fcm)) {
+ switch (fcm->type) {
+ case FMODIFIER_TYPE_ENVELOPE: /* envelope */
+ draw_fcurve_modifier_controls_envelope(fcm, &ar->v2d);
+ break;
+ }
+ }
+ }
+ else if (((fcu->bezt) || (fcu->fpt)) && (fcu->totvert)) {
+ short mapping_flag = ANIM_get_normalization_flags(ac);
+ float offset;
+ float unit_scale = ANIM_unit_mapping_get_factor(
+ ac->scene, ale->id, fcu, mapping_flag, &offset);
+
+ /* apply unit-scaling to all values via OpenGL */
+ GPU_matrix_push();
+ GPU_matrix_scale_2f(1.0f, unit_scale);
+ GPU_matrix_translate_2f(0.0f, offset);
+
+ /* set this once and for all - all handles and handle-verts should use the same thickness */
+ GPU_line_width(1.0);
+
+ if (fcu->bezt) {
+ bool do_handles = draw_fcurve_handles_check(sipo, fcu);
+
+ if (do_handles) {
+ /* only draw handles/vertices on keyframes */
+ GPU_blend(true);
+ draw_fcurve_handles(sipo, fcu);
+ GPU_blend(false);
+ }
+
+ draw_fcurve_vertices(ar, fcu, do_handles, (sipo->flag & SIPO_SELVHANDLESONLY));
+ }
+ else {
+ /* samples: only draw two indicators at either end as indicators */
+ draw_fcurve_samples(sipo, ar, fcu);
+ }
+
+ GPU_matrix_pop();
+ }
+ }
+
+ /* 3) draw driver debugging stuff */
+ if ((ac->datatype == ANIMCONT_DRIVERS) && (fcu->flag & FCURVE_ACTIVE)) {
+ graph_draw_driver_debug(ac, ale->id, fcu);
+ }
+
+ /* undo mapping of keyframes for drawing if scaled F-Curve */
+ if (adt)
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 0);
+ }
+
+ /* free list of curves */
+ ANIM_animdata_freelist(&anim_data);
}
/* ************************************************************************* */
@@ -1190,86 +1207,85 @@ void graph_draw_curves(bAnimContext *ac, SpaceGraph *sipo, ARegion *ar, View2DGr
/* left hand part */
void graph_draw_channel_names(bContext *C, bAnimContext *ac, ARegion *ar)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- View2D *v2d = &ar->v2d;
- float y = 0.0f, height;
- size_t items;
- int i = 0;
-
- /* build list of channels to draw */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
- items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* Update max-extent of channels here (taking into account scrollers):
- * - this is done to allow the channel list to be scrollable, but must be done here
- * to avoid regenerating the list again and/or also because channels list is drawn first
- * - offset of ACHANNEL_HEIGHT*2 is added to the height of the channels, as first is for
- * start of list offset, and the second is as a correction for the scrollers.
- */
- height = (float)((items * ACHANNEL_STEP(ac)) + (ACHANNEL_HEIGHT(ac) * 2));
- UI_view2d_totRect_set(v2d, BLI_rcti_size_x(&ar->v2d.mask), height);
-
- /* loop through channels, and set up drawing depending on their type */
- { /* first pass: just the standard GL-drawing for backdrop + text */
- size_t channel_index = 0;
-
- y = (float)ACHANNEL_FIRST(ac);
-
- for (ale = anim_data.first, i = 0; ale; ale = ale->next, i++) {
- const float yminc = (float)(y - ACHANNEL_HEIGHT_HALF(ac));
- const float ymaxc = (float)(y + ACHANNEL_HEIGHT_HALF(ac));
-
- /* check if visible */
- if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
- IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax) )
- {
- /* draw all channels using standard channel-drawing API */
- ANIM_channel_draw(ac, ale, yminc, ymaxc, channel_index);
- }
-
- /* adjust y-position for next one */
- y -= ACHANNEL_STEP(ac);
- channel_index++;
- }
- }
- { /* second pass: widgets */
- uiBlock *block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
- size_t channel_index = 0;
-
- y = (float)ACHANNEL_FIRST(ac);
-
- /* set blending again, as may not be set in previous step */
- GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- GPU_blend(true);
-
- for (ale = anim_data.first, i = 0; ale; ale = ale->next, i++) {
- const float yminc = (float)(y - ACHANNEL_HEIGHT_HALF(ac));
- const float ymaxc = (float)(y + ACHANNEL_HEIGHT_HALF(ac));
-
- /* check if visible */
- if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
- IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax) )
- {
- /* draw all channels using standard channel-drawing API */
- rctf channel_rect;
- BLI_rctf_init(&channel_rect, 0, v2d->cur.xmax - V2D_SCROLL_WIDTH, yminc, ymaxc);
- ANIM_channel_draw_widgets(C, ac, ale, block, &channel_rect, channel_index);
- }
-
- /* adjust y-position for next one */
- y -= ACHANNEL_STEP(ac);
- channel_index++;
- }
-
- UI_block_end(C, block);
- UI_block_draw(C, block);
-
- GPU_blend(false);
- }
-
- /* free tempolary channels */
- ANIM_animdata_freelist(&anim_data);
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ View2D *v2d = &ar->v2d;
+ float y = 0.0f, height;
+ size_t items;
+ int i = 0;
+
+ /* build list of channels to draw */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
+ items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* Update max-extent of channels here (taking into account scrollers):
+ * - this is done to allow the channel list to be scrollable, but must be done here
+ * to avoid regenerating the list again and/or also because channels list is drawn first
+ * - offset of ACHANNEL_HEIGHT*2 is added to the height of the channels, as first is for
+ * start of list offset, and the second is as a correction for the scrollers.
+ */
+ height = (float)((items * ACHANNEL_STEP(ac)) + (ACHANNEL_HEIGHT(ac) * 2));
+ UI_view2d_totRect_set(v2d, BLI_rcti_size_x(&ar->v2d.mask), height);
+
+ /* loop through channels, and set up drawing depending on their type */
+ { /* first pass: just the standard GL-drawing for backdrop + text */
+ size_t channel_index = 0;
+
+ y = (float)ACHANNEL_FIRST(ac);
+
+ for (ale = anim_data.first, i = 0; ale; ale = ale->next, i++) {
+ const float yminc = (float)(y - ACHANNEL_HEIGHT_HALF(ac));
+ const float ymaxc = (float)(y + ACHANNEL_HEIGHT_HALF(ac));
+
+ /* check if visible */
+ if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
+ IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax)) {
+ /* draw all channels using standard channel-drawing API */
+ ANIM_channel_draw(ac, ale, yminc, ymaxc, channel_index);
+ }
+
+ /* adjust y-position for next one */
+ y -= ACHANNEL_STEP(ac);
+ channel_index++;
+ }
+ }
+ { /* second pass: widgets */
+ uiBlock *block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
+ size_t channel_index = 0;
+
+ y = (float)ACHANNEL_FIRST(ac);
+
+ /* set blending again, as may not be set in previous step */
+ GPU_blend_set_func_separate(
+ GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(true);
+
+ for (ale = anim_data.first, i = 0; ale; ale = ale->next, i++) {
+ const float yminc = (float)(y - ACHANNEL_HEIGHT_HALF(ac));
+ const float ymaxc = (float)(y + ACHANNEL_HEIGHT_HALF(ac));
+
+ /* check if visible */
+ if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
+ IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax)) {
+ /* draw all channels using standard channel-drawing API */
+ rctf channel_rect;
+ BLI_rctf_init(&channel_rect, 0, v2d->cur.xmax - V2D_SCROLL_WIDTH, yminc, ymaxc);
+ ANIM_channel_draw_widgets(C, ac, ale, block, &channel_rect, channel_index);
+ }
+
+ /* adjust y-position for next one */
+ y -= ACHANNEL_STEP(ac);
+ channel_index++;
+ }
+
+ UI_block_end(C, block);
+ UI_block_draw(C, block);
+
+ GPU_blend(false);
+ }
+
+ /* free tempolary channels */
+ ANIM_animdata_freelist(&anim_data);
}
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index a85e638e6d8..29058e47199 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -21,7 +21,6 @@
* \ingroup spgraph
*/
-
#include <math.h>
#include <stdlib.h>
#include <string.h>
@@ -76,253 +75,288 @@
/* Get the min/max keyframes*/
/* note: it should return total boundbox, filter for selection only can be argument... */
-void get_graph_keyframe_extents(bAnimContext *ac, float *xmin, float *xmax, float *ymin, float *ymax,
- const bool do_sel_only, const bool include_handles)
-{
- Scene *scene = ac->scene;
-
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- /* get data to filter, from Dopesheet */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* set large values initial values that will be easy to override */
- if (xmin) *xmin = 999999999.0f;
- if (xmax) *xmax = -999999999.0f;
- if (ymin) *ymin = 999999999.0f;
- if (ymax) *ymax = -999999999.0f;
-
- /* check if any channels to set range with */
- if (anim_data.first) {
- bool foundBounds = false;
-
- /* go through channels, finding max extents */
- for (ale = anim_data.first; ale; ale = ale->next) {
- AnimData *adt = ANIM_nla_mapping_get(ac, ale);
- FCurve *fcu = (FCurve *)ale->key_data;
- float txmin, txmax, tymin, tymax;
- float unitFac, offset;
-
- /* get range */
- if (calc_fcurve_bounds(fcu, &txmin, &txmax, &tymin, &tymax, do_sel_only, include_handles)) {
- short mapping_flag = ANIM_get_normalization_flags(ac);
-
- /* apply NLA scaling */
- if (adt) {
- txmin = BKE_nla_tweakedit_remap(adt, txmin, NLATIME_CONVERT_MAP);
- txmax = BKE_nla_tweakedit_remap(adt, txmax, NLATIME_CONVERT_MAP);
- }
-
- /* apply unit corrections */
- unitFac = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag, &offset);
- tymin += offset;
- tymax += offset;
- tymin *= unitFac;
- tymax *= unitFac;
-
- /* try to set cur using these values, if they're more extreme than previously set values */
- if ((xmin) && (txmin < *xmin)) *xmin = txmin;
- if ((xmax) && (txmax > *xmax)) *xmax = txmax;
- if ((ymin) && (tymin < *ymin)) *ymin = tymin;
- if ((ymax) && (tymax > *ymax)) *ymax = tymax;
-
- foundBounds = true;
- }
- }
-
- /* ensure that the extents are not too extreme that view implodes...*/
- if (foundBounds) {
- if ((xmin && xmax) && (fabsf(*xmax - *xmin) < 0.001f)) {
- *xmin -= 0.0005f;
- *xmax += 0.0005f;
- }
- if ((ymin && ymax) && (fabsf(*ymax - *ymin) < 0.001f)) {
- *ymax -= 0.0005f;
- *ymax += 0.0005f;
- }
- }
- else {
- if (xmin) *xmin = (float)PSFRA;
- if (xmax) *xmax = (float)PEFRA;
- if (ymin) *ymin = -5;
- if (ymax) *ymax = 5;
- }
-
- /* free memory */
- ANIM_animdata_freelist(&anim_data);
- }
- else {
- /* set default range */
- if (ac->scene) {
- if (xmin) *xmin = (float)PSFRA;
- if (xmax) *xmax = (float)PEFRA;
- }
- else {
- if (xmin) *xmin = -5;
- if (xmax) *xmax = 100;
- }
-
- if (ymin) *ymin = -5;
- if (ymax) *ymax = 5;
- }
+void get_graph_keyframe_extents(bAnimContext *ac,
+ float *xmin,
+ float *xmax,
+ float *ymin,
+ float *ymax,
+ const bool do_sel_only,
+ const bool include_handles)
+{
+ Scene *scene = ac->scene;
+
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ /* get data to filter, from Dopesheet */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* set large values initial values that will be easy to override */
+ if (xmin)
+ *xmin = 999999999.0f;
+ if (xmax)
+ *xmax = -999999999.0f;
+ if (ymin)
+ *ymin = 999999999.0f;
+ if (ymax)
+ *ymax = -999999999.0f;
+
+ /* check if any channels to set range with */
+ if (anim_data.first) {
+ bool foundBounds = false;
+
+ /* go through channels, finding max extents */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ AnimData *adt = ANIM_nla_mapping_get(ac, ale);
+ FCurve *fcu = (FCurve *)ale->key_data;
+ float txmin, txmax, tymin, tymax;
+ float unitFac, offset;
+
+ /* get range */
+ if (calc_fcurve_bounds(fcu, &txmin, &txmax, &tymin, &tymax, do_sel_only, include_handles)) {
+ short mapping_flag = ANIM_get_normalization_flags(ac);
+
+ /* apply NLA scaling */
+ if (adt) {
+ txmin = BKE_nla_tweakedit_remap(adt, txmin, NLATIME_CONVERT_MAP);
+ txmax = BKE_nla_tweakedit_remap(adt, txmax, NLATIME_CONVERT_MAP);
+ }
+
+ /* apply unit corrections */
+ unitFac = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag, &offset);
+ tymin += offset;
+ tymax += offset;
+ tymin *= unitFac;
+ tymax *= unitFac;
+
+ /* try to set cur using these values, if they're more extreme than previously set values */
+ if ((xmin) && (txmin < *xmin))
+ *xmin = txmin;
+ if ((xmax) && (txmax > *xmax))
+ *xmax = txmax;
+ if ((ymin) && (tymin < *ymin))
+ *ymin = tymin;
+ if ((ymax) && (tymax > *ymax))
+ *ymax = tymax;
+
+ foundBounds = true;
+ }
+ }
+
+ /* ensure that the extents are not too extreme that view implodes...*/
+ if (foundBounds) {
+ if ((xmin && xmax) && (fabsf(*xmax - *xmin) < 0.001f)) {
+ *xmin -= 0.0005f;
+ *xmax += 0.0005f;
+ }
+ if ((ymin && ymax) && (fabsf(*ymax - *ymin) < 0.001f)) {
+ *ymax -= 0.0005f;
+ *ymax += 0.0005f;
+ }
+ }
+ else {
+ if (xmin)
+ *xmin = (float)PSFRA;
+ if (xmax)
+ *xmax = (float)PEFRA;
+ if (ymin)
+ *ymin = -5;
+ if (ymax)
+ *ymax = 5;
+ }
+
+ /* free memory */
+ ANIM_animdata_freelist(&anim_data);
+ }
+ else {
+ /* set default range */
+ if (ac->scene) {
+ if (xmin)
+ *xmin = (float)PSFRA;
+ if (xmax)
+ *xmax = (float)PEFRA;
+ }
+ else {
+ if (xmin)
+ *xmin = -5;
+ if (xmax)
+ *xmax = 100;
+ }
+
+ if (ymin)
+ *ymin = -5;
+ if (ymax)
+ *ymax = 5;
+ }
}
/* ****************** Automatic Preview-Range Operator ****************** */
static int graphkeys_previewrange_exec(bContext *C, wmOperator *UNUSED(op))
{
- bAnimContext ac;
- Scene *scene;
- float min, max;
+ bAnimContext ac;
+ Scene *scene;
+ float min, max;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
- if (ac.scene == NULL)
- return OPERATOR_CANCELLED;
- else
- scene = ac.scene;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+ if (ac.scene == NULL)
+ return OPERATOR_CANCELLED;
+ else
+ scene = ac.scene;
- /* set the range directly */
- get_graph_keyframe_extents(&ac, &min, &max, NULL, NULL, false, false);
- scene->r.flag |= SCER_PRV_RANGE;
- scene->r.psfra = round_fl_to_int(min);
- scene->r.pefra = round_fl_to_int(max);
+ /* set the range directly */
+ get_graph_keyframe_extents(&ac, &min, &max, NULL, NULL, false, false);
+ scene->r.flag |= SCER_PRV_RANGE;
+ scene->r.psfra = round_fl_to_int(min);
+ scene->r.pefra = round_fl_to_int(max);
- /* set notifier that things have changed */
- // XXX err... there's nothing for frame ranges yet, but this should do fine too
- WM_event_add_notifier(C, NC_SCENE | ND_FRAME, ac.scene);
+ /* set notifier that things have changed */
+ // XXX err... there's nothing for frame ranges yet, but this should do fine too
+ WM_event_add_notifier(C, NC_SCENE | ND_FRAME, ac.scene);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void GRAPH_OT_previewrange_set(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Auto-Set Preview Range";
- ot->idname = "GRAPH_OT_previewrange_set";
- ot->description = "Automatically set Preview Range based on range of keyframes";
+ /* identifiers */
+ ot->name = "Auto-Set Preview Range";
+ ot->idname = "GRAPH_OT_previewrange_set";
+ ot->description = "Automatically set Preview Range based on range of keyframes";
- /* api callbacks */
- ot->exec = graphkeys_previewrange_exec;
- ot->poll = ED_operator_graphedit_active; // XXX: unchecked poll to get fsamples working too, but makes modifier damage trickier...
+ /* api callbacks */
+ ot->exec = graphkeys_previewrange_exec;
+ ot->poll =
+ ED_operator_graphedit_active; // XXX: unchecked poll to get fsamples working too, but makes modifier damage trickier...
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ****************** View-All Operator ****************** */
-static int graphkeys_viewall(bContext *C, const bool do_sel_only, const bool include_handles,
+static int graphkeys_viewall(bContext *C,
+ const bool do_sel_only,
+ const bool include_handles,
const int smooth_viewtx)
{
- bAnimContext ac;
- rctf cur_new;
+ bAnimContext ac;
+ rctf cur_new;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* set the horizontal range, with an extra offset so that the extreme keys will be in view */
- get_graph_keyframe_extents(&ac,
- &cur_new.xmin, &cur_new.xmax,
- &cur_new.ymin, &cur_new.ymax,
- do_sel_only, include_handles);
+ /* set the horizontal range, with an extra offset so that the extreme keys will be in view */
+ get_graph_keyframe_extents(&ac,
+ &cur_new.xmin,
+ &cur_new.xmax,
+ &cur_new.ymin,
+ &cur_new.ymax,
+ do_sel_only,
+ include_handles);
- BLI_rctf_scale(&cur_new, 1.1f);
+ BLI_rctf_scale(&cur_new, 1.1f);
- UI_view2d_smooth_view(C, ac.ar, &cur_new, smooth_viewtx);
+ UI_view2d_smooth_view(C, ac.ar, &cur_new, smooth_viewtx);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
/* ......... */
static int graphkeys_viewall_exec(bContext *C, wmOperator *op)
{
- const bool include_handles = RNA_boolean_get(op->ptr, "include_handles");
- const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
+ const bool include_handles = RNA_boolean_get(op->ptr, "include_handles");
+ const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
- /* whole range */
- return graphkeys_viewall(C, false, include_handles, smooth_viewtx);
+ /* whole range */
+ return graphkeys_viewall(C, false, include_handles, smooth_viewtx);
}
static int graphkeys_view_selected_exec(bContext *C, wmOperator *op)
{
- const bool include_handles = RNA_boolean_get(op->ptr, "include_handles");
- const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
+ const bool include_handles = RNA_boolean_get(op->ptr, "include_handles");
+ const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
- /* only selected */
- return graphkeys_viewall(C, true, include_handles, smooth_viewtx);
+ /* only selected */
+ return graphkeys_viewall(C, true, include_handles, smooth_viewtx);
}
/* ......... */
void GRAPH_OT_view_all(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "View All";
- ot->idname = "GRAPH_OT_view_all";
- ot->description = "Reset viewable area to show full keyframe range";
+ /* identifiers */
+ ot->name = "View All";
+ ot->idname = "GRAPH_OT_view_all";
+ ot->description = "Reset viewable area to show full keyframe range";
- /* api callbacks */
- ot->exec = graphkeys_viewall_exec;
- /* XXX: unchecked poll to get fsamples working too, but makes modifier damage trickier... */
- ot->poll = ED_operator_graphedit_active;
+ /* api callbacks */
+ ot->exec = graphkeys_viewall_exec;
+ /* XXX: unchecked poll to get fsamples working too, but makes modifier damage trickier... */
+ ot->poll = ED_operator_graphedit_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* props */
- ot->prop = RNA_def_boolean(ot->srna, "include_handles", true, "Include Handles",
- "Include handles of keyframes when calculating extents");
+ /* props */
+ ot->prop = RNA_def_boolean(ot->srna,
+ "include_handles",
+ true,
+ "Include Handles",
+ "Include handles of keyframes when calculating extents");
}
void GRAPH_OT_view_selected(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "View Selected";
- ot->idname = "GRAPH_OT_view_selected";
- ot->description = "Reset viewable area to show selected keyframe range";
+ /* identifiers */
+ ot->name = "View Selected";
+ ot->idname = "GRAPH_OT_view_selected";
+ ot->description = "Reset viewable area to show selected keyframe range";
- /* api callbacks */
- ot->exec = graphkeys_view_selected_exec;
- /* XXX: unchecked poll to get fsamples working too, but makes modifier damage trickier... */
- ot->poll = ED_operator_graphedit_active;
+ /* api callbacks */
+ ot->exec = graphkeys_view_selected_exec;
+ /* XXX: unchecked poll to get fsamples working too, but makes modifier damage trickier... */
+ ot->poll = ED_operator_graphedit_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* props */
- ot->prop = RNA_def_boolean(ot->srna, "include_handles", true, "Include Handles",
- "Include handles of keyframes when calculating extents");
+ /* props */
+ ot->prop = RNA_def_boolean(ot->srna,
+ "include_handles",
+ true,
+ "Include Handles",
+ "Include handles of keyframes when calculating extents");
}
/* ********************** View Frame Operator ****************************** */
static int graphkeys_view_frame_exec(bContext *C, wmOperator *op)
{
- const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
- ANIM_center_frame(C, smooth_viewtx);
- return OPERATOR_FINISHED;
+ const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
+ ANIM_center_frame(C, smooth_viewtx);
+ return OPERATOR_FINISHED;
}
void GRAPH_OT_view_frame(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "View Frame";
- ot->idname = "GRAPH_OT_view_frame";
- ot->description = "Reset viewable area to show range around current frame";
+ /* identifiers */
+ ot->name = "View Frame";
+ ot->idname = "GRAPH_OT_view_frame";
+ ot->description = "Reset viewable area to show range around current frame";
- /* api callbacks */
- ot->exec = graphkeys_view_frame_exec;
- ot->poll = ED_operator_graphedit_active;
+ /* api callbacks */
+ ot->exec = graphkeys_view_frame_exec;
+ ot->poll = ED_operator_graphedit_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ******************** Create Ghost-Curves Operator *********************** */
@@ -333,114 +367,116 @@ void GRAPH_OT_view_frame(wmOperatorType *ot)
/* Bake each F-Curve into a set of samples, and store as a ghost curve */
static void create_ghost_curves(bAnimContext *ac, int start, int end)
{
- SpaceGraph *sipo = (SpaceGraph *)ac->sl;
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- /* free existing ghost curves */
- free_fcurves(&sipo->runtime.ghost_curves);
-
- /* sanity check */
- if (start >= end) {
- printf("Error: Frame range for Ghost F-Curve creation is inappropriate\n");
- return;
- }
-
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* loop through filtered data and add keys between selected keyframes on every frame */
- for (ale = anim_data.first; ale; ale = ale->next) {
- FCurve *fcu = (FCurve *)ale->key_data;
- FCurve *gcu = MEM_callocN(sizeof(FCurve), "Ghost FCurve");
- AnimData *adt = ANIM_nla_mapping_get(ac, ale);
- ChannelDriver *driver = fcu->driver;
- FPoint *fpt;
- float unitFac, offset;
- int cfra;
- short mapping_flag = ANIM_get_normalization_flags(ac);
-
- /* disable driver so that it don't muck up the sampling process */
- fcu->driver = NULL;
-
- /* calculate unit-mapping factor */
- unitFac = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag, &offset);
-
- /* create samples, but store them in a new curve
- * - we cannot use fcurve_store_samples() as that will only overwrite the original curve
- */
- gcu->fpt = fpt = MEM_callocN(sizeof(FPoint) * (end - start + 1), "Ghost FPoint Samples");
- gcu->totvert = end - start + 1;
-
- /* use the sampling callback at 1-frame intervals from start to end frames */
- for (cfra = start; cfra <= end; cfra++, fpt++) {
- float cfrae = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP);
-
- fpt->vec[0] = cfrae;
- fpt->vec[1] = (fcurve_samplingcb_evalcurve(fcu, NULL, cfrae) + offset) * unitFac;
- }
-
- /* set color of ghost curve
- * - make the color slightly darker
- */
- gcu->color[0] = fcu->color[0] - 0.07f;
- gcu->color[1] = fcu->color[1] - 0.07f;
- gcu->color[2] = fcu->color[2] - 0.07f;
-
- /* store new ghost curve */
- BLI_addtail(&sipo->runtime.ghost_curves, gcu);
-
- /* restore driver */
- fcu->driver = driver;
- }
-
- /* admin and redraws */
- ANIM_animdata_freelist(&anim_data);
+ SpaceGraph *sipo = (SpaceGraph *)ac->sl;
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ /* free existing ghost curves */
+ free_fcurves(&sipo->runtime.ghost_curves);
+
+ /* sanity check */
+ if (start >= end) {
+ printf("Error: Frame range for Ghost F-Curve creation is inappropriate\n");
+ return;
+ }
+
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_SEL |
+ ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* loop through filtered data and add keys between selected keyframes on every frame */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ FCurve *fcu = (FCurve *)ale->key_data;
+ FCurve *gcu = MEM_callocN(sizeof(FCurve), "Ghost FCurve");
+ AnimData *adt = ANIM_nla_mapping_get(ac, ale);
+ ChannelDriver *driver = fcu->driver;
+ FPoint *fpt;
+ float unitFac, offset;
+ int cfra;
+ short mapping_flag = ANIM_get_normalization_flags(ac);
+
+ /* disable driver so that it don't muck up the sampling process */
+ fcu->driver = NULL;
+
+ /* calculate unit-mapping factor */
+ unitFac = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag, &offset);
+
+ /* create samples, but store them in a new curve
+ * - we cannot use fcurve_store_samples() as that will only overwrite the original curve
+ */
+ gcu->fpt = fpt = MEM_callocN(sizeof(FPoint) * (end - start + 1), "Ghost FPoint Samples");
+ gcu->totvert = end - start + 1;
+
+ /* use the sampling callback at 1-frame intervals from start to end frames */
+ for (cfra = start; cfra <= end; cfra++, fpt++) {
+ float cfrae = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP);
+
+ fpt->vec[0] = cfrae;
+ fpt->vec[1] = (fcurve_samplingcb_evalcurve(fcu, NULL, cfrae) + offset) * unitFac;
+ }
+
+ /* set color of ghost curve
+ * - make the color slightly darker
+ */
+ gcu->color[0] = fcu->color[0] - 0.07f;
+ gcu->color[1] = fcu->color[1] - 0.07f;
+ gcu->color[2] = fcu->color[2] - 0.07f;
+
+ /* store new ghost curve */
+ BLI_addtail(&sipo->runtime.ghost_curves, gcu);
+
+ /* restore driver */
+ fcu->driver = driver;
+ }
+
+ /* admin and redraws */
+ ANIM_animdata_freelist(&anim_data);
}
/* ------------------- */
static int graphkeys_create_ghostcurves_exec(bContext *C, wmOperator *UNUSED(op))
{
- bAnimContext ac;
- View2D *v2d;
- int start, end;
+ bAnimContext ac;
+ View2D *v2d;
+ int start, end;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* ghost curves are snapshots of the visible portions of the curves, so set range to be the visible range */
- v2d = &ac.ar->v2d;
- start = (int)v2d->cur.xmin;
- end = (int)v2d->cur.xmax;
+ /* ghost curves are snapshots of the visible portions of the curves, so set range to be the visible range */
+ v2d = &ac.ar->v2d;
+ start = (int)v2d->cur.xmin;
+ end = (int)v2d->cur.xmax;
- /* bake selected curves into a ghost curve */
- create_ghost_curves(&ac, start, end);
+ /* bake selected curves into a ghost curve */
+ create_ghost_curves(&ac, start, end);
- /* update this editor only */
- ED_area_tag_redraw(CTX_wm_area(C));
+ /* update this editor only */
+ ED_area_tag_redraw(CTX_wm_area(C));
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void GRAPH_OT_ghost_curves_create(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Create Ghost Curves";
- ot->idname = "GRAPH_OT_ghost_curves_create";
- ot->description = "Create snapshot (Ghosts) of selected F-Curves as background aid for active Graph Editor";
+ /* identifiers */
+ ot->name = "Create Ghost Curves";
+ ot->idname = "GRAPH_OT_ghost_curves_create";
+ ot->description =
+ "Create snapshot (Ghosts) of selected F-Curves as background aid for active Graph Editor";
- /* api callbacks */
- ot->exec = graphkeys_create_ghostcurves_exec;
- ot->poll = graphop_visible_keyframes_poll;
+ /* api callbacks */
+ ot->exec = graphkeys_create_ghostcurves_exec;
+ ot->poll = graphop_visible_keyframes_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- // todo: add props for start/end frames
+ // todo: add props for start/end frames
}
/* ******************** Clear Ghost-Curves Operator *********************** */
@@ -448,40 +484,40 @@ void GRAPH_OT_ghost_curves_create(wmOperatorType *ot)
static int graphkeys_clear_ghostcurves_exec(bContext *C, wmOperator *UNUSED(op))
{
- bAnimContext ac;
- SpaceGraph *sipo;
+ bAnimContext ac;
+ SpaceGraph *sipo;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
- sipo = (SpaceGraph *)ac.sl;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+ sipo = (SpaceGraph *)ac.sl;
- /* if no ghost curves, don't do anything */
- if (BLI_listbase_is_empty(&sipo->runtime.ghost_curves)) {
- return OPERATOR_CANCELLED;
- }
- /* free ghost curves */
- free_fcurves(&sipo->runtime.ghost_curves);
+ /* if no ghost curves, don't do anything */
+ if (BLI_listbase_is_empty(&sipo->runtime.ghost_curves)) {
+ return OPERATOR_CANCELLED;
+ }
+ /* free ghost curves */
+ free_fcurves(&sipo->runtime.ghost_curves);
- /* update this editor only */
- ED_area_tag_redraw(CTX_wm_area(C));
+ /* update this editor only */
+ ED_area_tag_redraw(CTX_wm_area(C));
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void GRAPH_OT_ghost_curves_clear(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Clear Ghost Curves";
- ot->idname = "GRAPH_OT_ghost_curves_clear";
- ot->description = "Clear F-Curve snapshots (Ghosts) for active Graph Editor";
+ /* identifiers */
+ ot->name = "Clear Ghost Curves";
+ ot->idname = "GRAPH_OT_ghost_curves_clear";
+ ot->description = "Clear F-Curve snapshots (Ghosts) for active Graph Editor";
- /* api callbacks */
- ot->exec = graphkeys_clear_ghostcurves_exec;
- ot->poll = ED_operator_graphedit_active;
+ /* api callbacks */
+ ot->exec = graphkeys_clear_ghostcurves_exec;
+ ot->poll = ED_operator_graphedit_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ************************************************************************** */
@@ -491,310 +527,350 @@ void GRAPH_OT_ghost_curves_clear(wmOperatorType *ot)
/* Mode defines for insert keyframes tool */
typedef enum eGraphKeys_InsertKey_Types {
- GRAPHKEYS_INSERTKEY_ALL = (1 << 0),
- GRAPHKEYS_INSERTKEY_SEL = (1 << 1),
- GRAPHKEYS_INSERTKEY_CURSOR = (1 << 2),
- GRAPHKEYS_INSERTKEY_ACTIVE = (1 << 3),
+ GRAPHKEYS_INSERTKEY_ALL = (1 << 0),
+ GRAPHKEYS_INSERTKEY_SEL = (1 << 1),
+ GRAPHKEYS_INSERTKEY_CURSOR = (1 << 2),
+ GRAPHKEYS_INSERTKEY_ACTIVE = (1 << 3),
} eGraphKeys_InsertKey_Types;
/* RNA mode types for insert keyframes tool */
static const EnumPropertyItem prop_graphkeys_insertkey_types[] = {
- {GRAPHKEYS_INSERTKEY_ALL, "ALL", 0, "All Channels",
- "Insert a keyframe on all visible and editable F-Curves using each curve's current value"},
- {GRAPHKEYS_INSERTKEY_SEL, "SEL", 0, "Only Selected Channels",
- "Insert a keyframe on selected F-Curves using each curve's current value"},
- {0, "", 0, "", ""},
- {GRAPHKEYS_INSERTKEY_ACTIVE | GRAPHKEYS_INSERTKEY_CURSOR, "CURSOR_ACTIVE", 0,
- "Active Channels At Cursor", "Insert a keyframe for the active F-Curve at the cursor point"},
- {GRAPHKEYS_INSERTKEY_SEL | GRAPHKEYS_INSERTKEY_CURSOR, "CURSOR_SEL", 0,
- "Selected Channels At Cursor", "Insert a keyframe for selected F-Curves at the cursor point"},
- {0, NULL, 0, NULL, NULL},
+ {GRAPHKEYS_INSERTKEY_ALL,
+ "ALL",
+ 0,
+ "All Channels",
+ "Insert a keyframe on all visible and editable F-Curves using each curve's current value"},
+ {GRAPHKEYS_INSERTKEY_SEL,
+ "SEL",
+ 0,
+ "Only Selected Channels",
+ "Insert a keyframe on selected F-Curves using each curve's current value"},
+ {0, "", 0, "", ""},
+ {GRAPHKEYS_INSERTKEY_ACTIVE | GRAPHKEYS_INSERTKEY_CURSOR,
+ "CURSOR_ACTIVE",
+ 0,
+ "Active Channels At Cursor",
+ "Insert a keyframe for the active F-Curve at the cursor point"},
+ {GRAPHKEYS_INSERTKEY_SEL | GRAPHKEYS_INSERTKEY_CURSOR,
+ "CURSOR_SEL",
+ 0,
+ "Selected Channels At Cursor",
+ "Insert a keyframe for selected F-Curves at the cursor point"},
+ {0, NULL, 0, NULL, NULL},
};
/* this function is responsible for snapping keyframes to frame-times */
static void insert_graph_keys(bAnimContext *ac, eGraphKeys_InsertKey_Types mode)
{
- ListBase anim_data = {NULL, NULL};
- ListBase nla_cache = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
- size_t num_items;
-
- ReportList *reports = ac->reports;
- SpaceGraph *sipo = (SpaceGraph *)ac->sl;
- struct Depsgraph *depsgraph = ac->depsgraph;
- Scene *scene = ac->scene;
- ToolSettings *ts = scene->toolsettings;
- short flag = 0;
-
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
- if (mode & GRAPHKEYS_INSERTKEY_SEL)
- filter |= ANIMFILTER_SEL;
- else if (mode & GRAPHKEYS_INSERTKEY_ACTIVE)
- filter |= ANIMFILTER_ACTIVE;
-
- num_items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
- if (num_items == 0) {
- if (mode & GRAPHKEYS_INSERTKEY_ACTIVE)
- BKE_report(reports, RPT_ERROR, "No active F-Curve to add a keyframe to. Select an editable F-Curve first");
- else if (mode & GRAPHKEYS_INSERTKEY_SEL)
- BKE_report(reports, RPT_ERROR, "No selected F-Curves to add keyframes to");
- else
- BKE_report(reports, RPT_ERROR, "No channels to add keyframes to");
-
- return;
- }
-
- /* init keyframing flag */
- flag = ANIM_get_keyframing_flags(scene, 1);
-
- /* insert keyframes */
- if (mode & GRAPHKEYS_INSERTKEY_CURSOR) {
- for (ale = anim_data.first; ale; ale = ale->next) {
- AnimData *adt = ANIM_nla_mapping_get(ac, ale);
- FCurve *fcu = (FCurve *)ale->key_data;
-
- short mapping_flag = ANIM_get_normalization_flags(ac);
- float offset;
- float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, ale->key_data, mapping_flag, &offset);
-
- float x, y;
-
-
- /* perform time remapping for x-coordinate (if necessary) */
- if ((sipo) && (sipo->mode == SIPO_MODE_DRIVERS))
- x = sipo->cursorTime;
- else if (adt)
- x = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
- else
- x = (float)CFRA;
-
- /* normalise units of cursor's value */
- if (sipo)
- y = (sipo->cursorVal / unit_scale) - offset;
- else
- y = 0.0f;
-
- /* insert keyframe directly into the F-Curve */
- insert_vert_fcurve(fcu, x, y, ts->keyframe_type, 0);
-
- ale->update |= ANIM_UPDATE_DEFAULT;
- }
- }
- else {
- for (ale = anim_data.first; ale; ale = ale->next) {
- FCurve *fcu = (FCurve *)ale->key_data;
- float cfra = (float)CFRA;
-
- /* read value from property the F-Curve represents, or from the curve only?
- * - ale->id != NULL: Typically, this means that we have enough info to try resolving the path
- * - ale->owner != NULL: If this is set, then the path may not be resolvable from the ID alone,
- * so it's easier for now to just read the F-Curve directly.
- * (TODO: add the full-blown PointerRNA relative parsing case here...)
- * - fcu->driver != NULL: If this is set, then it's a driver. If we don't check for this, we'd end
- * up adding the keyframes on a new F-Curve in the action data instead.
- */
- if (ale->id && !ale->owner && !fcu->driver) {
- insert_keyframe(ac->bmain, depsgraph, reports, ale->id, NULL, ((fcu->grp) ? (fcu->grp->name) : (NULL)),
- fcu->rna_path, fcu->array_index, cfra, ts->keyframe_type, &nla_cache, flag);
- }
- else {
- AnimData *adt = ANIM_nla_mapping_get(ac, ale);
-
- /* adjust current frame for NLA-mapping */
- if ((sipo) && (sipo->mode == SIPO_MODE_DRIVERS))
- cfra = sipo->cursorTime;
- else if (adt)
- cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
-
- const float curval = evaluate_fcurve_only_curve(fcu, cfra);
- insert_vert_fcurve(fcu, cfra, curval, ts->keyframe_type, 0);
- }
-
- ale->update |= ANIM_UPDATE_DEFAULT;
- }
- }
-
- BKE_animsys_free_nla_keyframing_context_cache(&nla_cache);
-
- ANIM_animdata_update(ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
+ ListBase anim_data = {NULL, NULL};
+ ListBase nla_cache = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+ size_t num_items;
+
+ ReportList *reports = ac->reports;
+ SpaceGraph *sipo = (SpaceGraph *)ac->sl;
+ struct Depsgraph *depsgraph = ac->depsgraph;
+ Scene *scene = ac->scene;
+ ToolSettings *ts = scene->toolsettings;
+ short flag = 0;
+
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT |
+ ANIMFILTER_NODUPLIS);
+ if (mode & GRAPHKEYS_INSERTKEY_SEL)
+ filter |= ANIMFILTER_SEL;
+ else if (mode & GRAPHKEYS_INSERTKEY_ACTIVE)
+ filter |= ANIMFILTER_ACTIVE;
+
+ num_items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+ if (num_items == 0) {
+ if (mode & GRAPHKEYS_INSERTKEY_ACTIVE)
+ BKE_report(reports,
+ RPT_ERROR,
+ "No active F-Curve to add a keyframe to. Select an editable F-Curve first");
+ else if (mode & GRAPHKEYS_INSERTKEY_SEL)
+ BKE_report(reports, RPT_ERROR, "No selected F-Curves to add keyframes to");
+ else
+ BKE_report(reports, RPT_ERROR, "No channels to add keyframes to");
+
+ return;
+ }
+
+ /* init keyframing flag */
+ flag = ANIM_get_keyframing_flags(scene, 1);
+
+ /* insert keyframes */
+ if (mode & GRAPHKEYS_INSERTKEY_CURSOR) {
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ AnimData *adt = ANIM_nla_mapping_get(ac, ale);
+ FCurve *fcu = (FCurve *)ale->key_data;
+
+ short mapping_flag = ANIM_get_normalization_flags(ac);
+ float offset;
+ float unit_scale = ANIM_unit_mapping_get_factor(
+ ac->scene, ale->id, ale->key_data, mapping_flag, &offset);
+
+ float x, y;
+
+ /* perform time remapping for x-coordinate (if necessary) */
+ if ((sipo) && (sipo->mode == SIPO_MODE_DRIVERS))
+ x = sipo->cursorTime;
+ else if (adt)
+ x = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
+ else
+ x = (float)CFRA;
+
+ /* normalise units of cursor's value */
+ if (sipo)
+ y = (sipo->cursorVal / unit_scale) - offset;
+ else
+ y = 0.0f;
+
+ /* insert keyframe directly into the F-Curve */
+ insert_vert_fcurve(fcu, x, y, ts->keyframe_type, 0);
+
+ ale->update |= ANIM_UPDATE_DEFAULT;
+ }
+ }
+ else {
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ FCurve *fcu = (FCurve *)ale->key_data;
+ float cfra = (float)CFRA;
+
+ /* read value from property the F-Curve represents, or from the curve only?
+ * - ale->id != NULL: Typically, this means that we have enough info to try resolving the path
+ * - ale->owner != NULL: If this is set, then the path may not be resolvable from the ID alone,
+ * so it's easier for now to just read the F-Curve directly.
+ * (TODO: add the full-blown PointerRNA relative parsing case here...)
+ * - fcu->driver != NULL: If this is set, then it's a driver. If we don't check for this, we'd end
+ * up adding the keyframes on a new F-Curve in the action data instead.
+ */
+ if (ale->id && !ale->owner && !fcu->driver) {
+ insert_keyframe(ac->bmain,
+ depsgraph,
+ reports,
+ ale->id,
+ NULL,
+ ((fcu->grp) ? (fcu->grp->name) : (NULL)),
+ fcu->rna_path,
+ fcu->array_index,
+ cfra,
+ ts->keyframe_type,
+ &nla_cache,
+ flag);
+ }
+ else {
+ AnimData *adt = ANIM_nla_mapping_get(ac, ale);
+
+ /* adjust current frame for NLA-mapping */
+ if ((sipo) && (sipo->mode == SIPO_MODE_DRIVERS))
+ cfra = sipo->cursorTime;
+ else if (adt)
+ cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
+
+ const float curval = evaluate_fcurve_only_curve(fcu, cfra);
+ insert_vert_fcurve(fcu, cfra, curval, ts->keyframe_type, 0);
+ }
+
+ ale->update |= ANIM_UPDATE_DEFAULT;
+ }
+ }
+
+ BKE_animsys_free_nla_keyframing_context_cache(&nla_cache);
+
+ ANIM_animdata_update(ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
}
/* ------------------- */
static int graphkeys_insertkey_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- eGraphKeys_InsertKey_Types mode;
+ bAnimContext ac;
+ eGraphKeys_InsertKey_Types mode;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* which channels to affect? */
- mode = RNA_enum_get(op->ptr, "type");
+ /* which channels to affect? */
+ mode = RNA_enum_get(op->ptr, "type");
- /* insert keyframes */
- insert_graph_keys(&ac, mode);
+ /* insert keyframes */
+ insert_graph_keys(&ac, mode);
- /* set notifier that keyframes have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
+ /* set notifier that keyframes have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void GRAPH_OT_keyframe_insert(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Insert Keyframes";
- ot->idname = "GRAPH_OT_keyframe_insert";
- ot->description = "Insert keyframes for the specified channels";
+ /* identifiers */
+ ot->name = "Insert Keyframes";
+ ot->idname = "GRAPH_OT_keyframe_insert";
+ ot->description = "Insert keyframes for the specified channels";
- /* api callbacks */
- ot->invoke = WM_menu_invoke;
- ot->exec = graphkeys_insertkey_exec;
- ot->poll = graphop_editable_keyframes_poll;
+ /* api callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = graphkeys_insertkey_exec;
+ ot->poll = graphop_editable_keyframes_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* id-props */
- ot->prop = RNA_def_enum(ot->srna, "type", prop_graphkeys_insertkey_types, 0, "Type", "");
+ /* id-props */
+ ot->prop = RNA_def_enum(ot->srna, "type", prop_graphkeys_insertkey_types, 0, "Type", "");
}
/* ******************** Click-Insert Keyframes Operator ************************* */
static int graphkeys_click_insert_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- bAnimListElem *ale;
- AnimData *adt;
- FCurve *fcu;
- float frame, val;
-
- /* get animation context */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
-
- /* get active F-Curve 'anim-list-element' */
- ale = get_active_fcurve_channel(&ac);
- if (ELEM(NULL, ale, ale->data)) {
- if (ale) MEM_freeN(ale);
- return OPERATOR_CANCELLED;
- }
- fcu = ale->data;
-
- /* when there are F-Modifiers on the curve, only allow adding
- * keyframes if these will be visible after doing so...
- */
- if (fcurve_is_keyframable(fcu)) {
- ListBase anim_data;
- ToolSettings *ts = ac.scene->toolsettings;
-
- short mapping_flag = ANIM_get_normalization_flags(&ac);
- float scale, offset;
-
- /* preserve selection? */
- if (RNA_boolean_get(op->ptr, "extend") == false) {
- /* deselect all keyframes first, so that we can immediately start manipulating the newly added one(s)
- * - only affect the keyframes themselves, as we don't want channels popping in and out...
- */
- deselect_graph_keys(&ac, false, SELECT_SUBTRACT, false);
- }
-
- /* get frame and value from props */
- frame = RNA_float_get(op->ptr, "frame");
- val = RNA_float_get(op->ptr, "value");
-
- /* apply inverse NLA-mapping to frame to get correct time in un-scaled action */
- adt = ANIM_nla_mapping_get(&ac, ale);
- frame = BKE_nla_tweakedit_remap(adt, frame, NLATIME_CONVERT_UNMAP);
-
- /* apply inverse unit-mapping to value to get correct value for F-Curves */
- scale = ANIM_unit_mapping_get_factor(ac.scene, ale->id, fcu, mapping_flag | ANIM_UNITCONV_RESTORE, &offset);
-
- val = val * scale - offset;
-
- /* insert keyframe on the specified frame + value */
- insert_vert_fcurve(fcu, frame, val, ts->keyframe_type, 0);
-
- ale->update |= ANIM_UPDATE_DEPS;
-
- BLI_listbase_clear(&anim_data);
- BLI_addtail(&anim_data, ale);
-
- ANIM_animdata_update(&ac, &anim_data);
- }
- else {
- /* warn about why this can't happen */
- if (fcu->fpt)
- BKE_report(op->reports, RPT_ERROR, "Keyframes cannot be added to sampled F-Curves");
- else if (fcu->flag & FCURVE_PROTECTED)
- BKE_report(op->reports, RPT_ERROR, "Active F-Curve is not editable");
- else
- BKE_report(op->reports, RPT_ERROR, "Remove F-Modifiers from F-Curve to add keyframes");
- }
-
- /* free temp data */
- MEM_freeN(ale);
-
- /* set notifier that keyframes have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
-
- /* done */
- return OPERATOR_FINISHED;
+ bAnimContext ac;
+ bAnimListElem *ale;
+ AnimData *adt;
+ FCurve *fcu;
+ float frame, val;
+
+ /* get animation context */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* get active F-Curve 'anim-list-element' */
+ ale = get_active_fcurve_channel(&ac);
+ if (ELEM(NULL, ale, ale->data)) {
+ if (ale)
+ MEM_freeN(ale);
+ return OPERATOR_CANCELLED;
+ }
+ fcu = ale->data;
+
+ /* when there are F-Modifiers on the curve, only allow adding
+ * keyframes if these will be visible after doing so...
+ */
+ if (fcurve_is_keyframable(fcu)) {
+ ListBase anim_data;
+ ToolSettings *ts = ac.scene->toolsettings;
+
+ short mapping_flag = ANIM_get_normalization_flags(&ac);
+ float scale, offset;
+
+ /* preserve selection? */
+ if (RNA_boolean_get(op->ptr, "extend") == false) {
+ /* deselect all keyframes first, so that we can immediately start manipulating the newly added one(s)
+ * - only affect the keyframes themselves, as we don't want channels popping in and out...
+ */
+ deselect_graph_keys(&ac, false, SELECT_SUBTRACT, false);
+ }
+
+ /* get frame and value from props */
+ frame = RNA_float_get(op->ptr, "frame");
+ val = RNA_float_get(op->ptr, "value");
+
+ /* apply inverse NLA-mapping to frame to get correct time in un-scaled action */
+ adt = ANIM_nla_mapping_get(&ac, ale);
+ frame = BKE_nla_tweakedit_remap(adt, frame, NLATIME_CONVERT_UNMAP);
+
+ /* apply inverse unit-mapping to value to get correct value for F-Curves */
+ scale = ANIM_unit_mapping_get_factor(
+ ac.scene, ale->id, fcu, mapping_flag | ANIM_UNITCONV_RESTORE, &offset);
+
+ val = val * scale - offset;
+
+ /* insert keyframe on the specified frame + value */
+ insert_vert_fcurve(fcu, frame, val, ts->keyframe_type, 0);
+
+ ale->update |= ANIM_UPDATE_DEPS;
+
+ BLI_listbase_clear(&anim_data);
+ BLI_addtail(&anim_data, ale);
+
+ ANIM_animdata_update(&ac, &anim_data);
+ }
+ else {
+ /* warn about why this can't happen */
+ if (fcu->fpt)
+ BKE_report(op->reports, RPT_ERROR, "Keyframes cannot be added to sampled F-Curves");
+ else if (fcu->flag & FCURVE_PROTECTED)
+ BKE_report(op->reports, RPT_ERROR, "Active F-Curve is not editable");
+ else
+ BKE_report(op->reports, RPT_ERROR, "Remove F-Modifiers from F-Curve to add keyframes");
+ }
+
+ /* free temp data */
+ MEM_freeN(ale);
+
+ /* set notifier that keyframes have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+
+ /* done */
+ return OPERATOR_FINISHED;
}
static int graphkeys_click_insert_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- bAnimContext ac;
- ARegion *ar;
- View2D *v2d;
- int mval[2];
- float x, y;
+ bAnimContext ac;
+ ARegion *ar;
+ View2D *v2d;
+ int mval[2];
+ float x, y;
- /* get animation context */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get animation context */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* store mouse coordinates in View2D space, into the operator's properties */
- ar = ac.ar;
- v2d = &ar->v2d;
+ /* store mouse coordinates in View2D space, into the operator's properties */
+ ar = ac.ar;
+ v2d = &ar->v2d;
- mval[0] = (event->x - ar->winrct.xmin);
- mval[1] = (event->y - ar->winrct.ymin);
+ mval[0] = (event->x - ar->winrct.xmin);
+ mval[1] = (event->y - ar->winrct.ymin);
- UI_view2d_region_to_view(v2d, mval[0], mval[1], &x, &y);
+ UI_view2d_region_to_view(v2d, mval[0], mval[1], &x, &y);
- RNA_float_set(op->ptr, "frame", x);
- RNA_float_set(op->ptr, "value", y);
+ RNA_float_set(op->ptr, "frame", x);
+ RNA_float_set(op->ptr, "value", y);
- /* run exec now */
- return graphkeys_click_insert_exec(C, op);
+ /* run exec now */
+ return graphkeys_click_insert_exec(C, op);
}
void GRAPH_OT_click_insert(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Click-Insert Keyframes";
- ot->idname = "GRAPH_OT_click_insert";
- ot->description = "Insert new keyframe at the cursor position for the active F-Curve";
-
- /* api callbacks */
- ot->invoke = graphkeys_click_insert_invoke;
- ot->exec = graphkeys_click_insert_exec;
- ot->poll = graphop_active_fcurve_poll;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* properties */
- RNA_def_float(ot->srna, "frame", 1.0f, -FLT_MAX, FLT_MAX, "Frame Number", "Frame to insert keyframe on", 0, 100);
- RNA_def_float(ot->srna, "value", 1.0f, -FLT_MAX, FLT_MAX, "Value", "Value for keyframe on", 0, 100);
-
- RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend selection instead of deselecting everything first");
+ /* identifiers */
+ ot->name = "Click-Insert Keyframes";
+ ot->idname = "GRAPH_OT_click_insert";
+ ot->description = "Insert new keyframe at the cursor position for the active F-Curve";
+
+ /* api callbacks */
+ ot->invoke = graphkeys_click_insert_invoke;
+ ot->exec = graphkeys_click_insert_exec;
+ ot->poll = graphop_active_fcurve_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ RNA_def_float(ot->srna,
+ "frame",
+ 1.0f,
+ -FLT_MAX,
+ FLT_MAX,
+ "Frame Number",
+ "Frame to insert keyframe on",
+ 0,
+ 100);
+ RNA_def_float(
+ ot->srna, "value", 1.0f, -FLT_MAX, FLT_MAX, "Value", "Value for keyframe on", 0, 100);
+
+ RNA_def_boolean(ot->srna,
+ "extend",
+ false,
+ "Extend",
+ "Extend selection instead of deselecting everything first");
}
/* ******************** Copy/Paste Keyframes Operator ************************* */
@@ -802,342 +878,359 @@ void GRAPH_OT_click_insert(wmOperatorType *ot)
static short copy_graph_keys(bAnimContext *ac)
{
- ListBase anim_data = {NULL, NULL};
- int filter, ok = 0;
+ ListBase anim_data = {NULL, NULL};
+ int filter, ok = 0;
- /* clear buffer first */
- ANIM_fcurves_copybuf_free();
+ /* clear buffer first */
+ ANIM_fcurves_copybuf_free();
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
- /* copy keyframes */
- ok = copy_animedit_keys(ac, &anim_data);
+ /* copy keyframes */
+ ok = copy_animedit_keys(ac, &anim_data);
- /* clean up */
- ANIM_animdata_freelist(&anim_data);
+ /* clean up */
+ ANIM_animdata_freelist(&anim_data);
- return ok;
+ return ok;
}
static short paste_graph_keys(bAnimContext *ac,
- const eKeyPasteOffset offset_mode, const eKeyMergeMode merge_mode, bool flip)
+ const eKeyPasteOffset offset_mode,
+ const eKeyMergeMode merge_mode,
+ bool flip)
{
- ListBase anim_data = {NULL, NULL};
- int filter, ok = 0;
+ ListBase anim_data = {NULL, NULL};
+ int filter, ok = 0;
- /* filter data
- * - First time we try to filter more strictly, allowing only selected channels
- * to allow copying animation between channels
- * - Second time, we loosen things up if nothing was found the first time, allowing
- * users to just paste keyframes back into the original curve again [#31670]
- */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
+ /* filter data
+ * - First time we try to filter more strictly, allowing only selected channels
+ * to allow copying animation between channels
+ * - Second time, we loosen things up if nothing was found the first time, allowing
+ * users to just paste keyframes back into the original curve again [#31670]
+ */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT |
+ ANIMFILTER_NODUPLIS);
- if (ANIM_animdata_filter(ac, &anim_data, filter | ANIMFILTER_SEL, ac->data, ac->datatype) == 0)
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+ if (ANIM_animdata_filter(ac, &anim_data, filter | ANIMFILTER_SEL, ac->data, ac->datatype) == 0)
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
- /* paste keyframes */
- ok = paste_animedit_keys(ac, &anim_data, offset_mode, merge_mode, flip);
+ /* paste keyframes */
+ ok = paste_animedit_keys(ac, &anim_data, offset_mode, merge_mode, flip);
- /* clean up */
- ANIM_animdata_freelist(&anim_data);
+ /* clean up */
+ ANIM_animdata_freelist(&anim_data);
- return ok;
+ return ok;
}
/* ------------------- */
static int graphkeys_copy_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
+ bAnimContext ac;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* copy keyframes */
- if (copy_graph_keys(&ac)) {
- BKE_report(op->reports, RPT_ERROR, "No keyframes copied to keyframes copy/paste buffer");
- return OPERATOR_CANCELLED;
- }
+ /* copy keyframes */
+ if (copy_graph_keys(&ac)) {
+ BKE_report(op->reports, RPT_ERROR, "No keyframes copied to keyframes copy/paste buffer");
+ return OPERATOR_CANCELLED;
+ }
- /* just return - no operator needed here (no changes) */
- return OPERATOR_FINISHED;
+ /* just return - no operator needed here (no changes) */
+ return OPERATOR_FINISHED;
}
void GRAPH_OT_copy(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Copy Keyframes";
- ot->idname = "GRAPH_OT_copy";
- ot->description = "Copy selected keyframes to the copy/paste buffer";
+ /* identifiers */
+ ot->name = "Copy Keyframes";
+ ot->idname = "GRAPH_OT_copy";
+ ot->description = "Copy selected keyframes to the copy/paste buffer";
- /* api callbacks */
- ot->exec = graphkeys_copy_exec;
- ot->poll = graphop_editable_keyframes_poll;
+ /* api callbacks */
+ ot->exec = graphkeys_copy_exec;
+ ot->poll = graphop_editable_keyframes_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-
-
static int graphkeys_paste_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
+ bAnimContext ac;
- const eKeyPasteOffset offset_mode = RNA_enum_get(op->ptr, "offset");
- const eKeyMergeMode merge_mode = RNA_enum_get(op->ptr, "merge");
- const bool flipped = RNA_boolean_get(op->ptr, "flipped");
+ const eKeyPasteOffset offset_mode = RNA_enum_get(op->ptr, "offset");
+ const eKeyMergeMode merge_mode = RNA_enum_get(op->ptr, "merge");
+ const bool flipped = RNA_boolean_get(op->ptr, "flipped");
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* ac.reports by default will be the global reports list, which won't show warnings */
- ac.reports = op->reports;
+ /* ac.reports by default will be the global reports list, which won't show warnings */
+ ac.reports = op->reports;
- /* paste keyframes - non-zero return means an error occurred while trying to paste */
- if (paste_graph_keys(&ac, offset_mode, merge_mode, flipped)) {
- return OPERATOR_CANCELLED;
- }
+ /* paste keyframes - non-zero return means an error occurred while trying to paste */
+ if (paste_graph_keys(&ac, offset_mode, merge_mode, flipped)) {
+ return OPERATOR_CANCELLED;
+ }
- /* set notifier that keyframes have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+ /* set notifier that keyframes have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void GRAPH_OT_paste(wmOperatorType *ot)
{
- PropertyRNA *prop;
-
- /* identifiers */
- ot->name = "Paste Keyframes";
- ot->idname = "GRAPH_OT_paste";
- ot->description = "Paste keyframes from copy/paste buffer for the selected channels, starting on the current frame";
-
- /* api callbacks */
-// ot->invoke = WM_operator_props_popup; // better wait for graph redo panel
- ot->exec = graphkeys_paste_exec;
- ot->poll = graphop_editable_keyframes_poll;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* props */
- RNA_def_enum(ot->srna, "offset", rna_enum_keyframe_paste_offset_items, KEYFRAME_PASTE_OFFSET_CFRA_START, "Offset", "Paste time offset of keys");
- RNA_def_enum(ot->srna, "merge", rna_enum_keyframe_paste_merge_items, KEYFRAME_PASTE_MERGE_MIX, "Type", "Method of merging pasted keys and existing");
- prop = RNA_def_boolean(ot->srna, "flipped", false, "Flipped", "Paste keyframes from mirrored bones if they exist");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Paste Keyframes";
+ ot->idname = "GRAPH_OT_paste";
+ ot->description =
+ "Paste keyframes from copy/paste buffer for the selected channels, starting on the current "
+ "frame";
+
+ /* api callbacks */
+ // ot->invoke = WM_operator_props_popup; // better wait for graph redo panel
+ ot->exec = graphkeys_paste_exec;
+ ot->poll = graphop_editable_keyframes_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* props */
+ RNA_def_enum(ot->srna,
+ "offset",
+ rna_enum_keyframe_paste_offset_items,
+ KEYFRAME_PASTE_OFFSET_CFRA_START,
+ "Offset",
+ "Paste time offset of keys");
+ RNA_def_enum(ot->srna,
+ "merge",
+ rna_enum_keyframe_paste_merge_items,
+ KEYFRAME_PASTE_MERGE_MIX,
+ "Type",
+ "Method of merging pasted keys and existing");
+ prop = RNA_def_boolean(
+ ot->srna, "flipped", false, "Flipped", "Paste keyframes from mirrored bones if they exist");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
/* ******************** Duplicate Keyframes Operator ************************* */
static void duplicate_graph_keys(bAnimContext *ac)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT |
+ ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
- /* loop through filtered data and delete selected keys */
- for (ale = anim_data.first; ale; ale = ale->next) {
- duplicate_fcurve_keys((FCurve *)ale->key_data);
+ /* loop through filtered data and delete selected keys */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ duplicate_fcurve_keys((FCurve *)ale->key_data);
- ale->update |= ANIM_UPDATE_DEFAULT;
- }
+ ale->update |= ANIM_UPDATE_DEFAULT;
+ }
- ANIM_animdata_update(ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
+ ANIM_animdata_update(ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
}
/* ------------------- */
static int graphkeys_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
{
- bAnimContext ac;
+ bAnimContext ac;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* duplicate keyframes */
- duplicate_graph_keys(&ac);
+ /* duplicate keyframes */
+ duplicate_graph_keys(&ac);
- /* set notifier that keyframes have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
+ /* set notifier that keyframes have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void GRAPH_OT_duplicate(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Duplicate Keyframes";
- ot->idname = "GRAPH_OT_duplicate";
- ot->description = "Make a copy of all selected keyframes";
+ /* identifiers */
+ ot->name = "Duplicate Keyframes";
+ ot->idname = "GRAPH_OT_duplicate";
+ ot->description = "Make a copy of all selected keyframes";
- /* api callbacks */
- ot->exec = graphkeys_duplicate_exec;
- ot->poll = graphop_editable_keyframes_poll;
+ /* api callbacks */
+ ot->exec = graphkeys_duplicate_exec;
+ ot->poll = graphop_editable_keyframes_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* to give to transform */
- RNA_def_enum(ot->srna, "mode", rna_enum_transform_mode_types, TFM_TRANSLATION, "Mode", "");
+ /* to give to transform */
+ RNA_def_enum(ot->srna, "mode", rna_enum_transform_mode_types, TFM_TRANSLATION, "Mode", "");
}
/* ******************** Delete Keyframes Operator ************************* */
static bool delete_graph_keys(bAnimContext *ac)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
- bool changed_final = false;
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+ bool changed_final = false;
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT |
+ ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
- /* loop through filtered data and delete selected keys */
- for (ale = anim_data.first; ale; ale = ale->next) {
- FCurve *fcu = (FCurve *)ale->key_data;
- AnimData *adt = ale->adt;
- bool changed;
+ /* loop through filtered data and delete selected keys */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ FCurve *fcu = (FCurve *)ale->key_data;
+ AnimData *adt = ale->adt;
+ bool changed;
- /* delete selected keyframes only */
- changed = delete_fcurve_keys(fcu);
+ /* delete selected keyframes only */
+ changed = delete_fcurve_keys(fcu);
- if (changed) {
- ale->update |= ANIM_UPDATE_DEFAULT;
- changed_final = true;
- }
+ if (changed) {
+ ale->update |= ANIM_UPDATE_DEFAULT;
+ changed_final = true;
+ }
- /* Only delete curve too if it won't be doing anything anymore */
- if ((fcu->totvert == 0) &&
- (list_has_suitable_fmodifier(&fcu->modifiers, 0, FMI_TYPE_GENERATE_CURVE) == 0) &&
- (fcu->driver == NULL))
- {
- ANIM_fcurve_delete_from_animdata(ac, adt, fcu);
- ale->key_data = NULL;
- }
- }
+ /* Only delete curve too if it won't be doing anything anymore */
+ if ((fcu->totvert == 0) &&
+ (list_has_suitable_fmodifier(&fcu->modifiers, 0, FMI_TYPE_GENERATE_CURVE) == 0) &&
+ (fcu->driver == NULL)) {
+ ANIM_fcurve_delete_from_animdata(ac, adt, fcu);
+ ale->key_data = NULL;
+ }
+ }
- ANIM_animdata_update(ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
+ ANIM_animdata_update(ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
- return changed_final;
+ return changed_final;
}
/* ------------------- */
static int graphkeys_delete_exec(bContext *C, wmOperator *UNUSED(op))
{
- bAnimContext ac;
+ bAnimContext ac;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* delete keyframes */
- if (!delete_graph_keys(&ac))
- return OPERATOR_CANCELLED;
+ /* delete keyframes */
+ if (!delete_graph_keys(&ac))
+ return OPERATOR_CANCELLED;
- /* set notifier that keyframes have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_REMOVED, NULL);
+ /* set notifier that keyframes have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_REMOVED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void GRAPH_OT_delete(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Delete Keyframes";
- ot->idname = "GRAPH_OT_delete";
- ot->description = "Remove all selected keyframes";
+ /* identifiers */
+ ot->name = "Delete Keyframes";
+ ot->idname = "GRAPH_OT_delete";
+ ot->description = "Remove all selected keyframes";
- /* api callbacks */
- ot->invoke = WM_operator_confirm;
- ot->exec = graphkeys_delete_exec;
- ot->poll = graphop_editable_keyframes_poll;
+ /* api callbacks */
+ ot->invoke = WM_operator_confirm;
+ ot->exec = graphkeys_delete_exec;
+ ot->poll = graphop_editable_keyframes_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ******************** Clean Keyframes Operator ************************* */
static void clean_graph_keys(bAnimContext *ac, float thresh, bool clean_chan)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_SEL | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT |
+ ANIMFILTER_SEL | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
- /* loop through filtered data and clean curves */
- for (ale = anim_data.first; ale; ale = ale->next) {
- clean_fcurve(ac, ale, thresh, clean_chan);
+ /* loop through filtered data and clean curves */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ clean_fcurve(ac, ale, thresh, clean_chan);
- ale->update |= ANIM_UPDATE_DEFAULT;
- }
+ ale->update |= ANIM_UPDATE_DEFAULT;
+ }
- ANIM_animdata_update(ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
+ ANIM_animdata_update(ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
}
/* ------------------- */
static int graphkeys_clean_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- float thresh;
- bool clean_chan;
+ bAnimContext ac;
+ float thresh;
+ bool clean_chan;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* get cleaning threshold */
- thresh = RNA_float_get(op->ptr, "threshold");
- clean_chan = RNA_boolean_get(op->ptr, "channels");
- /* clean keyframes */
- clean_graph_keys(&ac, thresh, clean_chan);
+ /* get cleaning threshold */
+ thresh = RNA_float_get(op->ptr, "threshold");
+ clean_chan = RNA_boolean_get(op->ptr, "channels");
+ /* clean keyframes */
+ clean_graph_keys(&ac, thresh, clean_chan);
- /* set notifier that keyframes have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+ /* set notifier that keyframes have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void GRAPH_OT_clean(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Clean Keyframes";
- ot->idname = "GRAPH_OT_clean";
- ot->description = "Simplify F-Curves by removing closely spaced keyframes";
+ /* identifiers */
+ ot->name = "Clean Keyframes";
+ ot->idname = "GRAPH_OT_clean";
+ ot->description = "Simplify F-Curves by removing closely spaced keyframes";
- /* api callbacks */
- //ot->invoke = // XXX we need that number popup for this!
- ot->exec = graphkeys_clean_exec;
- ot->poll = graphop_editable_keyframes_poll;
+ /* api callbacks */
+ //ot->invoke = // XXX we need that number popup for this!
+ ot->exec = graphkeys_clean_exec;
+ ot->poll = graphop_editable_keyframes_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* properties */
- ot->prop = RNA_def_float(ot->srna, "threshold", 0.001f, 0.0f, FLT_MAX, "Threshold", "", 0.0f, 1000.0f);
- RNA_def_boolean(ot->srna, "channels", false, "Channels", "");
+ /* properties */
+ ot->prop = RNA_def_float(
+ ot->srna, "threshold", 0.001f, 0.0f, FLT_MAX, "Threshold", "", 0.0f, 1000.0f);
+ RNA_def_boolean(ot->srna, "channels", false, "Channels", "");
}
/* ******************** Bake F-Curve Operator *********************** */
@@ -1146,79 +1239,80 @@ void GRAPH_OT_clean(wmOperatorType *ot)
/* Bake each F-Curve into a set of samples */
static void bake_graph_curves(bAnimContext *ac, int start, int end)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_SEL |
+ ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
- /* loop through filtered data and add keys between selected keyframes on every frame */
- for (ale = anim_data.first; ale; ale = ale->next) {
- FCurve *fcu = (FCurve *)ale->key_data;
- ChannelDriver *driver = fcu->driver;
+ /* loop through filtered data and add keys between selected keyframes on every frame */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ FCurve *fcu = (FCurve *)ale->key_data;
+ ChannelDriver *driver = fcu->driver;
- /* disable driver so that it don't muck up the sampling process */
- fcu->driver = NULL;
+ /* disable driver so that it don't muck up the sampling process */
+ fcu->driver = NULL;
- /* create samples */
- fcurve_store_samples(fcu, NULL, start, end, fcurve_samplingcb_evalcurve);
+ /* create samples */
+ fcurve_store_samples(fcu, NULL, start, end, fcurve_samplingcb_evalcurve);
- /* restore driver */
- fcu->driver = driver;
+ /* restore driver */
+ fcu->driver = driver;
- ale->update |= ANIM_UPDATE_DEPS;
- }
+ ale->update |= ANIM_UPDATE_DEPS;
+ }
- ANIM_animdata_update(ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
+ ANIM_animdata_update(ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
}
/* ------------------- */
static int graphkeys_bake_exec(bContext *C, wmOperator *UNUSED(op))
{
- bAnimContext ac;
- Scene *scene = NULL;
- int start, end;
+ bAnimContext ac;
+ Scene *scene = NULL;
+ int start, end;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* for now, init start/end from preview-range extents */
- // TODO: add properties for this
- scene = ac.scene;
- start = PSFRA;
- end = PEFRA;
+ /* for now, init start/end from preview-range extents */
+ // TODO: add properties for this
+ scene = ac.scene;
+ start = PSFRA;
+ end = PEFRA;
- /* bake keyframes */
- bake_graph_curves(&ac, start, end);
+ /* bake keyframes */
+ bake_graph_curves(&ac, start, end);
- /* set notifier that keyframes have changed */
- // NOTE: some distinction between order/number of keyframes and type should be made?
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+ /* set notifier that keyframes have changed */
+ // NOTE: some distinction between order/number of keyframes and type should be made?
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void GRAPH_OT_bake(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Bake Curve";
- ot->idname = "GRAPH_OT_bake";
- ot->description = "Bake selected F-Curves to a set of sampled points defining a similar curve";
+ /* identifiers */
+ ot->name = "Bake Curve";
+ ot->idname = "GRAPH_OT_bake";
+ ot->description = "Bake selected F-Curves to a set of sampled points defining a similar curve";
- /* api callbacks */
- ot->invoke = WM_operator_confirm; // FIXME...
- ot->exec = graphkeys_bake_exec;
- ot->poll = graphop_selected_fcurve_poll;
+ /* api callbacks */
+ ot->invoke = WM_operator_confirm; // FIXME...
+ ot->exec = graphkeys_bake_exec;
+ ot->poll = graphop_selected_fcurve_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- // todo: add props for start/end frames
+ // todo: add props for start/end frames
}
#ifdef WITH_AUDASPACE
@@ -1232,9 +1326,9 @@ void GRAPH_OT_bake(wmOperatorType *ot)
* which provides the necessary info for baking the sound
*/
typedef struct tSoundBakeInfo {
- float *samples;
- int length;
- int cfra;
+ float *samples;
+ int length;
+ int cfra;
} tSoundBakeInfo;
/* ------------------- */
@@ -1244,154 +1338,214 @@ typedef struct tSoundBakeInfo {
*/
static float fcurve_samplingcb_sound(FCurve *UNUSED(fcu), void *data, float evaltime)
{
- tSoundBakeInfo *sbi = (tSoundBakeInfo *)data;
+ tSoundBakeInfo *sbi = (tSoundBakeInfo *)data;
- int position = evaltime - sbi->cfra;
- if ((position < 0) || (position >= sbi->length))
- return 0.0f;
+ int position = evaltime - sbi->cfra;
+ if ((position < 0) || (position >= sbi->length))
+ return 0.0f;
- return sbi->samples[position];
+ return sbi->samples[position];
}
/* ------------------- */
static int graphkeys_sound_bake_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
+ bAnimContext ac;
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
- tSoundBakeInfo sbi;
- Scene *scene = NULL;
- int start, end;
+ tSoundBakeInfo sbi;
+ Scene *scene = NULL;
+ int start, end;
- char path[FILE_MAX];
+ char path[FILE_MAX];
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- RNA_string_get(op->ptr, "filepath", path);
+ RNA_string_get(op->ptr, "filepath", path);
- if (!BLI_is_file(path)) {
- BKE_reportf(op->reports, RPT_ERROR, "File not found '%s'", path);
- return OPERATOR_CANCELLED;
- }
+ if (!BLI_is_file(path)) {
+ BKE_reportf(op->reports, RPT_ERROR, "File not found '%s'", path);
+ return OPERATOR_CANCELLED;
+ }
- scene = ac.scene; /* current scene */
+ scene = ac.scene; /* current scene */
- /* store necessary data for the baking steps */
- sbi.samples = AUD_readSoundBuffer(path,
- RNA_float_get(op->ptr, "low"),
- RNA_float_get(op->ptr, "high"),
- RNA_float_get(op->ptr, "attack"),
- RNA_float_get(op->ptr, "release"),
- RNA_float_get(op->ptr, "threshold"),
- RNA_boolean_get(op->ptr, "use_accumulate"),
- RNA_boolean_get(op->ptr, "use_additive"),
- RNA_boolean_get(op->ptr, "use_square"),
- RNA_float_get(op->ptr, "sthreshold"),
- FPS, &sbi.length);
+ /* store necessary data for the baking steps */
+ sbi.samples = AUD_readSoundBuffer(path,
+ RNA_float_get(op->ptr, "low"),
+ RNA_float_get(op->ptr, "high"),
+ RNA_float_get(op->ptr, "attack"),
+ RNA_float_get(op->ptr, "release"),
+ RNA_float_get(op->ptr, "threshold"),
+ RNA_boolean_get(op->ptr, "use_accumulate"),
+ RNA_boolean_get(op->ptr, "use_additive"),
+ RNA_boolean_get(op->ptr, "use_square"),
+ RNA_float_get(op->ptr, "sthreshold"),
+ FPS,
+ &sbi.length);
- if (sbi.samples == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Unsupported audio format");
- return OPERATOR_CANCELLED;
- }
+ if (sbi.samples == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "Unsupported audio format");
+ return OPERATOR_CANCELLED;
+ }
- /* determine extents of the baking */
- sbi.cfra = start = CFRA;
- end = CFRA + sbi.length - 1;
+ /* determine extents of the baking */
+ sbi.cfra = start = CFRA;
+ end = CFRA + sbi.length - 1;
- /* filter anim channels */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+ /* filter anim channels */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_SEL |
+ ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
- /* loop through all selected F-Curves, replacing its data with the sound samples */
- for (ale = anim_data.first; ale; ale = ale->next) {
- FCurve *fcu = (FCurve *)ale->key_data;
+ /* loop through all selected F-Curves, replacing its data with the sound samples */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ FCurve *fcu = (FCurve *)ale->key_data;
- /* sample the sound */
- fcurve_store_samples(fcu, &sbi, start, end, fcurve_samplingcb_sound);
+ /* sample the sound */
+ fcurve_store_samples(fcu, &sbi, start, end, fcurve_samplingcb_sound);
- ale->update |= ANIM_UPDATE_DEFAULT;
- }
+ ale->update |= ANIM_UPDATE_DEFAULT;
+ }
- /* free sample data */
- free(sbi.samples);
+ /* free sample data */
+ free(sbi.samples);
- /* validate keyframes after editing */
- ANIM_animdata_update(&ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
+ /* validate keyframes after editing */
+ ANIM_animdata_update(&ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
- /* set notifier that 'keyframes' have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+ /* set notifier that 'keyframes' have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
-#else //WITH_AUDASPACE
+#else //WITH_AUDASPACE
static int graphkeys_sound_bake_exec(bContext *UNUSED(C), wmOperator *op)
{
- BKE_report(op->reports, RPT_ERROR, "Compiled without sound support");
+ BKE_report(op->reports, RPT_ERROR, "Compiled without sound support");
- return OPERATOR_CANCELLED;
+ return OPERATOR_CANCELLED;
}
-#endif //WITH_AUDASPACE
+#endif //WITH_AUDASPACE
static int graphkeys_sound_bake_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- bAnimContext ac;
+ bAnimContext ac;
- /* verify editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* verify editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- return WM_operator_filesel(C, op, event);
+ return WM_operator_filesel(C, op, event);
}
void GRAPH_OT_sound_bake(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Bake Sound to F-Curves";
- ot->idname = "GRAPH_OT_sound_bake";
- ot->description = "Bakes a sound wave to selected F-Curves";
-
- /* api callbacks */
- ot->invoke = graphkeys_sound_bake_invoke;
- ot->exec = graphkeys_sound_bake_exec;
- ot->poll = graphop_selected_fcurve_poll;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* properties */
- WM_operator_properties_filesel(
- ot, FILE_TYPE_FOLDER | FILE_TYPE_SOUND | FILE_TYPE_MOVIE, FILE_SPECIAL, FILE_OPENFILE,
- WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA);
- RNA_def_float(ot->srna, "low", 0.0f, 0.0, 100000.0, "Lowest frequency",
- "Cutoff frequency of a high-pass filter that is applied to the audio data", 0.1, 1000.00);
- RNA_def_float(ot->srna, "high", 100000.0, 0.0, 100000.0, "Highest frequency",
- "Cutoff frequency of a low-pass filter that is applied to the audio data", 0.1, 1000.00);
- RNA_def_float(ot->srna, "attack", 0.005, 0.0, 2.0, "Attack time",
- "Value for the hull curve calculation that tells how fast the hull curve can rise "
- "(the lower the value the steeper it can rise)", 0.01, 0.1);
- RNA_def_float(ot->srna, "release", 0.2, 0.0, 5.0, "Release time",
- "Value for the hull curve calculation that tells how fast the hull curve can fall "
- "(the lower the value the steeper it can fall)", 0.01, 0.2);
- RNA_def_float(ot->srna, "threshold", 0.0, 0.0, 1.0, "Threshold",
- "Minimum amplitude value needed to influence the hull curve", 0.01, 0.1);
- RNA_def_boolean(ot->srna, "use_accumulate", 0, "Accumulate",
- "Only the positive differences of the hull curve amplitudes are summarized to produce the output");
- RNA_def_boolean(ot->srna, "use_additive", 0, "Additive",
- "The amplitudes of the hull curve are summarized (or, when Accumulate is enabled, "
- "both positive and negative differences are accumulated)");
- RNA_def_boolean(ot->srna, "use_square", 0, "Square",
- "The output is a square curve (negative values always result in -1, and positive ones in 1)");
- RNA_def_float(ot->srna, "sthreshold", 0.1, 0.0, 1.0, "Square Threshold",
- "Square only: all values with an absolute amplitude lower than that result in 0", 0.01, 0.1);
+ /* identifiers */
+ ot->name = "Bake Sound to F-Curves";
+ ot->idname = "GRAPH_OT_sound_bake";
+ ot->description = "Bakes a sound wave to selected F-Curves";
+
+ /* api callbacks */
+ ot->invoke = graphkeys_sound_bake_invoke;
+ ot->exec = graphkeys_sound_bake_exec;
+ ot->poll = graphop_selected_fcurve_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ WM_operator_properties_filesel(ot,
+ FILE_TYPE_FOLDER | FILE_TYPE_SOUND | FILE_TYPE_MOVIE,
+ FILE_SPECIAL,
+ FILE_OPENFILE,
+ WM_FILESEL_FILEPATH,
+ FILE_DEFAULTDISPLAY,
+ FILE_SORT_ALPHA);
+ RNA_def_float(ot->srna,
+ "low",
+ 0.0f,
+ 0.0,
+ 100000.0,
+ "Lowest frequency",
+ "Cutoff frequency of a high-pass filter that is applied to the audio data",
+ 0.1,
+ 1000.00);
+ RNA_def_float(ot->srna,
+ "high",
+ 100000.0,
+ 0.0,
+ 100000.0,
+ "Highest frequency",
+ "Cutoff frequency of a low-pass filter that is applied to the audio data",
+ 0.1,
+ 1000.00);
+ RNA_def_float(ot->srna,
+ "attack",
+ 0.005,
+ 0.0,
+ 2.0,
+ "Attack time",
+ "Value for the hull curve calculation that tells how fast the hull curve can rise "
+ "(the lower the value the steeper it can rise)",
+ 0.01,
+ 0.1);
+ RNA_def_float(ot->srna,
+ "release",
+ 0.2,
+ 0.0,
+ 5.0,
+ "Release time",
+ "Value for the hull curve calculation that tells how fast the hull curve can fall "
+ "(the lower the value the steeper it can fall)",
+ 0.01,
+ 0.2);
+ RNA_def_float(ot->srna,
+ "threshold",
+ 0.0,
+ 0.0,
+ 1.0,
+ "Threshold",
+ "Minimum amplitude value needed to influence the hull curve",
+ 0.01,
+ 0.1);
+ RNA_def_boolean(ot->srna,
+ "use_accumulate",
+ 0,
+ "Accumulate",
+ "Only the positive differences of the hull curve amplitudes are summarized to "
+ "produce the output");
+ RNA_def_boolean(
+ ot->srna,
+ "use_additive",
+ 0,
+ "Additive",
+ "The amplitudes of the hull curve are summarized (or, when Accumulate is enabled, "
+ "both positive and negative differences are accumulated)");
+ RNA_def_boolean(ot->srna,
+ "use_square",
+ 0,
+ "Square",
+ "The output is a square curve (negative values always result in -1, and "
+ "positive ones in 1)");
+ RNA_def_float(ot->srna,
+ "sthreshold",
+ 0.1,
+ 0.0,
+ 1.0,
+ "Square Threshold",
+ "Square only: all values with an absolute amplitude lower than that result in 0",
+ 0.01,
+ 0.1);
}
/* ******************** Sample Keyframes Operator *********************** */
@@ -1402,171 +1556,188 @@ void GRAPH_OT_sound_bake(wmOperatorType *ot)
/* Evaluates the curves between each selected keyframe on each frame, and keys the value */
static void sample_graph_keys(bAnimContext *ac)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT |
+ ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
- /* loop through filtered data and add keys between selected keyframes on every frame */
- for (ale = anim_data.first; ale; ale = ale->next) {
- sample_fcurve((FCurve *)ale->key_data);
+ /* loop through filtered data and add keys between selected keyframes on every frame */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ sample_fcurve((FCurve *)ale->key_data);
- ale->update |= ANIM_UPDATE_DEPS;
- }
+ ale->update |= ANIM_UPDATE_DEPS;
+ }
- ANIM_animdata_update(ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
+ ANIM_animdata_update(ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
}
/* ------------------- */
static int graphkeys_sample_exec(bContext *C, wmOperator *UNUSED(op))
{
- bAnimContext ac;
+ bAnimContext ac;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* sample keyframes */
- sample_graph_keys(&ac);
+ /* sample keyframes */
+ sample_graph_keys(&ac);
- /* set notifier that keyframes have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+ /* set notifier that keyframes have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void GRAPH_OT_sample(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Sample Keyframes";
- ot->idname = "GRAPH_OT_sample";
- ot->description = "Add keyframes on every frame between the selected keyframes";
+ /* identifiers */
+ ot->name = "Sample Keyframes";
+ ot->idname = "GRAPH_OT_sample";
+ ot->description = "Add keyframes on every frame between the selected keyframes";
- /* api callbacks */
- ot->exec = graphkeys_sample_exec;
- ot->poll = graphop_editable_keyframes_poll;
+ /* api callbacks */
+ ot->exec = graphkeys_sample_exec;
+ ot->poll = graphop_editable_keyframes_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-
/* ************************************************************************** */
/* SETTINGS STUFF */
/* ******************** Set Extrapolation-Type Operator *********************** */
/* defines for make/clear cyclic extrapolation tools */
-#define MAKE_CYCLIC_EXPO -1
-#define CLEAR_CYCLIC_EXPO -2
+#define MAKE_CYCLIC_EXPO -1
+#define CLEAR_CYCLIC_EXPO -2
/* defines for set extrapolation-type for selected keyframes tool */
static const EnumPropertyItem prop_graphkeys_expo_types[] = {
- {FCURVE_EXTRAPOLATE_CONSTANT, "CONSTANT", 0, "Constant Extrapolation", "Values on endpoint keyframes are held"},
- {FCURVE_EXTRAPOLATE_LINEAR, "LINEAR", 0, "Linear Extrapolation", "Straight-line slope of end segments are extended past the endpoint keyframes"},
-
- {MAKE_CYCLIC_EXPO, "MAKE_CYCLIC", 0, "Make Cyclic (F-Modifier)", "Add Cycles F-Modifier if one doesn't exist already"},
- {CLEAR_CYCLIC_EXPO, "CLEAR_CYCLIC", 0, "Clear Cyclic (F-Modifier)", "Remove Cycles F-Modifier if not needed anymore"},
- {0, NULL, 0, NULL, NULL},
+ {FCURVE_EXTRAPOLATE_CONSTANT,
+ "CONSTANT",
+ 0,
+ "Constant Extrapolation",
+ "Values on endpoint keyframes are held"},
+ {FCURVE_EXTRAPOLATE_LINEAR,
+ "LINEAR",
+ 0,
+ "Linear Extrapolation",
+ "Straight-line slope of end segments are extended past the endpoint keyframes"},
+
+ {MAKE_CYCLIC_EXPO,
+ "MAKE_CYCLIC",
+ 0,
+ "Make Cyclic (F-Modifier)",
+ "Add Cycles F-Modifier if one doesn't exist already"},
+ {CLEAR_CYCLIC_EXPO,
+ "CLEAR_CYCLIC",
+ 0,
+ "Clear Cyclic (F-Modifier)",
+ "Remove Cycles F-Modifier if not needed anymore"},
+ {0, NULL, 0, NULL, NULL},
};
/* this function is responsible for setting extrapolation mode for keyframes */
static void setexpo_graph_keys(bAnimContext *ac, short mode)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* loop through setting mode per F-Curve */
- for (ale = anim_data.first; ale; ale = ale->next) {
- FCurve *fcu = (FCurve *)ale->data;
-
- if (mode >= 0) {
- /* just set mode setting */
- fcu->extend = mode;
-
- ale->update |= ANIM_UPDATE_HANDLES;
- }
- else {
- /* shortcuts for managing Cycles F-Modifiers to make it easier to toggle cyclic animation
- * without having to go through FModifier UI in Graph Editor to do so
- */
- if (mode == MAKE_CYCLIC_EXPO) {
- /* only add if one doesn't exist */
- if (list_has_suitable_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_CYCLES, -1) == 0) {
- // TODO: add some more preset versions which set different extrapolation options?
- add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_CYCLES, fcu);
- }
- }
- else if (mode == CLEAR_CYCLIC_EXPO) {
- /* remove all the modifiers fitting this description */
- FModifier *fcm, *fcn = NULL;
-
- for (fcm = fcu->modifiers.first; fcm; fcm = fcn) {
- fcn = fcm->next;
-
- if (fcm->type == FMODIFIER_TYPE_CYCLES)
- remove_fmodifier(&fcu->modifiers, fcm);
- }
- }
- }
-
- ale->update |= ANIM_UPDATE_DEPS;
- }
-
- ANIM_animdata_update(ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_SEL |
+ ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* loop through setting mode per F-Curve */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ FCurve *fcu = (FCurve *)ale->data;
+
+ if (mode >= 0) {
+ /* just set mode setting */
+ fcu->extend = mode;
+
+ ale->update |= ANIM_UPDATE_HANDLES;
+ }
+ else {
+ /* shortcuts for managing Cycles F-Modifiers to make it easier to toggle cyclic animation
+ * without having to go through FModifier UI in Graph Editor to do so
+ */
+ if (mode == MAKE_CYCLIC_EXPO) {
+ /* only add if one doesn't exist */
+ if (list_has_suitable_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_CYCLES, -1) == 0) {
+ // TODO: add some more preset versions which set different extrapolation options?
+ add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_CYCLES, fcu);
+ }
+ }
+ else if (mode == CLEAR_CYCLIC_EXPO) {
+ /* remove all the modifiers fitting this description */
+ FModifier *fcm, *fcn = NULL;
+
+ for (fcm = fcu->modifiers.first; fcm; fcm = fcn) {
+ fcn = fcm->next;
+
+ if (fcm->type == FMODIFIER_TYPE_CYCLES)
+ remove_fmodifier(&fcu->modifiers, fcm);
+ }
+ }
+ }
+
+ ale->update |= ANIM_UPDATE_DEPS;
+ }
+
+ ANIM_animdata_update(ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
}
/* ------------------- */
static int graphkeys_expo_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- short mode;
+ bAnimContext ac;
+ short mode;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* get handle setting mode */
- mode = RNA_enum_get(op->ptr, "type");
+ /* get handle setting mode */
+ mode = RNA_enum_get(op->ptr, "type");
- /* set handle type */
- setexpo_graph_keys(&ac, mode);
+ /* set handle type */
+ setexpo_graph_keys(&ac, mode);
- /* set notifier that keyframe properties have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
+ /* set notifier that keyframe properties have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void GRAPH_OT_extrapolation_type(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Set Keyframe Extrapolation";
- ot->idname = "GRAPH_OT_extrapolation_type";
- ot->description = "Set extrapolation mode for selected F-Curves";
+ /* identifiers */
+ ot->name = "Set Keyframe Extrapolation";
+ ot->idname = "GRAPH_OT_extrapolation_type";
+ ot->description = "Set extrapolation mode for selected F-Curves";
- /* api callbacks */
- ot->invoke = WM_menu_invoke;
- ot->exec = graphkeys_expo_exec;
- ot->poll = graphop_editable_keyframes_poll;
+ /* api callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = graphkeys_expo_exec;
+ ot->poll = graphop_editable_keyframes_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* id-props */
- ot->prop = RNA_def_enum(ot->srna, "type", prop_graphkeys_expo_types, 0, "Type", "");
+ /* id-props */
+ ot->prop = RNA_def_enum(ot->srna, "type", prop_graphkeys_expo_types, 0, "Type", "");
}
/* ******************** Set Interpolation-Type Operator *********************** */
@@ -1574,134 +1745,140 @@ void GRAPH_OT_extrapolation_type(wmOperatorType *ot)
/* this function is responsible for setting interpolation mode for keyframes */
static void setipo_graph_keys(bAnimContext *ac, short mode)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
- KeyframeEditFunc set_cb = ANIM_editkeyframes_ipo(mode);
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+ KeyframeEditFunc set_cb = ANIM_editkeyframes_ipo(mode);
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT |
+ ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
- /* loop through setting BezTriple interpolation
- * Note: we do not supply KeyframeEditData to the looper yet. Currently that's not necessary here...
- */
- for (ale = anim_data.first; ale; ale = ale->next) {
- ANIM_fcurve_keyframes_loop(NULL, ale->key_data, NULL, set_cb, calchandles_fcurve);
+ /* loop through setting BezTriple interpolation
+ * Note: we do not supply KeyframeEditData to the looper yet. Currently that's not necessary here...
+ */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ ANIM_fcurve_keyframes_loop(NULL, ale->key_data, NULL, set_cb, calchandles_fcurve);
- ale->update |= ANIM_UPDATE_DEFAULT_NOHANDLES;
- }
+ ale->update |= ANIM_UPDATE_DEFAULT_NOHANDLES;
+ }
- ANIM_animdata_update(ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
+ ANIM_animdata_update(ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
}
/* ------------------- */
static int graphkeys_ipo_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- short mode;
+ bAnimContext ac;
+ short mode;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* get handle setting mode */
- mode = RNA_enum_get(op->ptr, "type");
+ /* get handle setting mode */
+ mode = RNA_enum_get(op->ptr, "type");
- /* set handle type */
- setipo_graph_keys(&ac, mode);
+ /* set handle type */
+ setipo_graph_keys(&ac, mode);
- /* set notifier that keyframe properties have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
+ /* set notifier that keyframe properties have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void GRAPH_OT_interpolation_type(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Set Keyframe Interpolation";
- ot->idname = "GRAPH_OT_interpolation_type";
- ot->description = "Set interpolation mode for the F-Curve segments starting from the selected keyframes";
+ /* identifiers */
+ ot->name = "Set Keyframe Interpolation";
+ ot->idname = "GRAPH_OT_interpolation_type";
+ ot->description =
+ "Set interpolation mode for the F-Curve segments starting from the selected keyframes";
- /* api callbacks */
- ot->invoke = WM_menu_invoke;
- ot->exec = graphkeys_ipo_exec;
- ot->poll = graphop_editable_keyframes_poll;
+ /* api callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = graphkeys_ipo_exec;
+ ot->poll = graphop_editable_keyframes_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* id-props */
- ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_beztriple_interpolation_mode_items, 0, "Type", "");
+ /* id-props */
+ ot->prop = RNA_def_enum(
+ ot->srna, "type", rna_enum_beztriple_interpolation_mode_items, 0, "Type", "");
}
/* ******************** Set Easing Operator *********************** */
static void seteasing_graph_keys(bAnimContext *ac, short mode)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
- KeyframeEditFunc set_cb = ANIM_editkeyframes_easing(mode);
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+ KeyframeEditFunc set_cb = ANIM_editkeyframes_easing(mode);
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT |
+ ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
- /* loop through setting BezTriple easing
- * Note: we do not supply KeyframeEditData to the looper yet. Currently that's not necessary here...
- */
- for (ale = anim_data.first; ale; ale = ale->next) {
- ANIM_fcurve_keyframes_loop(NULL, ale->key_data, NULL, set_cb, calchandles_fcurve);
+ /* loop through setting BezTriple easing
+ * Note: we do not supply KeyframeEditData to the looper yet. Currently that's not necessary here...
+ */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ ANIM_fcurve_keyframes_loop(NULL, ale->key_data, NULL, set_cb, calchandles_fcurve);
- ale->update |= ANIM_UPDATE_DEFAULT_NOHANDLES;
- }
+ ale->update |= ANIM_UPDATE_DEFAULT_NOHANDLES;
+ }
- ANIM_animdata_update(ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
+ ANIM_animdata_update(ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
}
static int graphkeys_easing_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- short mode;
+ bAnimContext ac;
+ short mode;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* get handle setting mode */
- mode = RNA_enum_get(op->ptr, "type");
+ /* get handle setting mode */
+ mode = RNA_enum_get(op->ptr, "type");
- /* set handle type */
- seteasing_graph_keys(&ac, mode);
+ /* set handle type */
+ seteasing_graph_keys(&ac, mode);
- /* set notifier that keyframe properties have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
+ /* set notifier that keyframe properties have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void GRAPH_OT_easing_type(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Set Keyframe Easing Type";
- ot->idname = "GRAPH_OT_easing_type";
- ot->description = "Set easing type for the F-Curve segments starting from the selected keyframes";
+ /* identifiers */
+ ot->name = "Set Keyframe Easing Type";
+ ot->idname = "GRAPH_OT_easing_type";
+ ot->description =
+ "Set easing type for the F-Curve segments starting from the selected keyframes";
- /* api callbacks */
- ot->invoke = WM_menu_invoke;
- ot->exec = graphkeys_easing_exec;
- ot->poll = graphop_editable_keyframes_poll;
+ /* api callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = graphkeys_easing_exec;
+ ot->poll = graphop_editable_keyframes_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* id-props */
- ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_beztriple_interpolation_easing_items, 0, "Type", "");
+ /* id-props */
+ ot->prop = RNA_def_enum(
+ ot->srna, "type", rna_enum_beztriple_interpolation_easing_items, 0, "Type", "");
}
/* ******************** Set Handle-Type Operator *********************** */
@@ -1709,75 +1886,76 @@ void GRAPH_OT_easing_type(wmOperatorType *ot)
/* this function is responsible for setting handle-type of selected keyframes */
static void sethandles_graph_keys(bAnimContext *ac, short mode)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
- KeyframeEditFunc edit_cb = ANIM_editkeyframes_handles(mode);
- KeyframeEditFunc sel_cb = ANIM_editkeyframes_ok(BEZT_OK_SELECTED);
+ KeyframeEditFunc edit_cb = ANIM_editkeyframes_handles(mode);
+ KeyframeEditFunc sel_cb = ANIM_editkeyframes_ok(BEZT_OK_SELECTED);
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT |
+ ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
- /* loop through setting flags for handles
- * Note: we do not supply KeyframeEditData to the looper yet. Currently that's not necessary here...
- */
- for (ale = anim_data.first; ale; ale = ale->next) {
- FCurve *fcu = (FCurve *)ale->key_data;
+ /* loop through setting flags for handles
+ * Note: we do not supply KeyframeEditData to the looper yet. Currently that's not necessary here...
+ */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ FCurve *fcu = (FCurve *)ale->key_data;
- /* any selected keyframes for editing? */
- if (ANIM_fcurve_keyframes_loop(NULL, fcu, NULL, sel_cb, NULL)) {
- /* change type of selected handles */
- ANIM_fcurve_keyframes_loop(NULL, fcu, NULL, edit_cb, calchandles_fcurve);
+ /* any selected keyframes for editing? */
+ if (ANIM_fcurve_keyframes_loop(NULL, fcu, NULL, sel_cb, NULL)) {
+ /* change type of selected handles */
+ ANIM_fcurve_keyframes_loop(NULL, fcu, NULL, edit_cb, calchandles_fcurve);
- ale->update |= ANIM_UPDATE_DEFAULT;
- }
- }
+ ale->update |= ANIM_UPDATE_DEFAULT;
+ }
+ }
- ANIM_animdata_update(ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
+ ANIM_animdata_update(ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
}
/* ------------------- */
static int graphkeys_handletype_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- short mode;
+ bAnimContext ac;
+ short mode;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* get handle setting mode */
- mode = RNA_enum_get(op->ptr, "type");
+ /* get handle setting mode */
+ mode = RNA_enum_get(op->ptr, "type");
- /* set handle type */
- sethandles_graph_keys(&ac, mode);
+ /* set handle type */
+ sethandles_graph_keys(&ac, mode);
- /* set notifier that keyframe properties have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
+ /* set notifier that keyframe properties have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void GRAPH_OT_handle_type(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Set Keyframe Handle Type";
- ot->idname = "GRAPH_OT_handle_type";
- ot->description = "Set type of handle for selected keyframes";
+ /* identifiers */
+ ot->name = "Set Keyframe Handle Type";
+ ot->idname = "GRAPH_OT_handle_type";
+ ot->description = "Set type of handle for selected keyframes";
- /* api callbacks */
- ot->invoke = WM_menu_invoke;
- ot->exec = graphkeys_handletype_exec;
- ot->poll = graphop_editable_keyframes_poll;
+ /* api callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = graphkeys_handletype_exec;
+ ot->poll = graphop_editable_keyframes_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* id-props */
- ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_keyframe_handle_type_items, 0, "Type", "");
+ /* id-props */
+ ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_keyframe_handle_type_items, 0, "Type", "");
}
/* ************************************************************************** */
@@ -1792,599 +1970,652 @@ void GRAPH_OT_handle_type(wmOperatorType *ot)
/* set of three euler-rotation F-Curves */
typedef struct tEulerFilter {
- struct tEulerFilter *next, *prev;
-
- /** ID-block which owns the channels */
- ID *id;
- /** 3 Pointers to F-Curves */
- FCurve *(fcurves[3]);
- /** Pointer to one of the RNA Path's used by one of the F-Curves */
- const char *rna_path;
+ struct tEulerFilter *next, *prev;
+
+ /** ID-block which owns the channels */
+ ID *id;
+ /** 3 Pointers to F-Curves */
+ FCurve *(fcurves[3]);
+ /** Pointer to one of the RNA Path's used by one of the F-Curves */
+ const char *rna_path;
} tEulerFilter;
static int graphkeys_euler_filter_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
-
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- ListBase eulers = {NULL, NULL};
- tEulerFilter *euf = NULL;
- int groups = 0, failed = 0;
-
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
-
- /* The process is done in two passes:
- * 1) Sets of three related rotation curves are identified from the selected channels,
- * and are stored as a single 'operation unit' for the next step
- * 2) Each set of three F-Curves is processed for each keyframe, with the values being
- * processed as necessary
- */
-
- /* step 1: extract only the rotation f-curves */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
- for (ale = anim_data.first; ale; ale = ale->next) {
- FCurve *fcu = (FCurve *)ale->data;
-
- /* check if this is an appropriate F-Curve
- * - only rotation curves
- * - for pchan curves, make sure we're only using the euler curves
- */
- if (strstr(fcu->rna_path, "rotation_euler") == NULL)
- continue;
- else if (ELEM(fcu->array_index, 0, 1, 2) == 0) {
- BKE_reportf(op->reports, RPT_WARNING,
- "Euler Rotation F-Curve has invalid index (ID='%s', Path='%s', Index=%d)",
- (ale->id) ? ale->id->name : TIP_("<No ID>"), fcu->rna_path, fcu->array_index);
- continue;
- }
-
- /* optimization: assume that xyz curves will always be stored consecutively,
- * so if the paths or the ID's don't match up, then a curve needs to be added
- * to a new group
- */
- if ((euf) && (euf->id == ale->id) && (STREQ(euf->rna_path, fcu->rna_path))) {
- /* this should be fine to add to the existing group then */
- euf->fcurves[fcu->array_index] = fcu;
- }
- else {
- /* just add to a new block */
- euf = MEM_callocN(sizeof(tEulerFilter), "tEulerFilter");
- BLI_addtail(&eulers, euf);
- groups++;
-
- euf->id = ale->id;
- /* this should be safe, since we're only using it for a short time */
- euf->rna_path = fcu->rna_path;
- euf->fcurves[fcu->array_index] = fcu;
- }
-
- ale->update |= ANIM_UPDATE_DEFAULT;
- }
-
- if (groups == 0) {
- ANIM_animdata_freelist(&anim_data);
- BKE_report(op->reports, RPT_WARNING, "No Euler Rotation F-Curves to fix up");
- return OPERATOR_CANCELLED;
- }
-
- /* step 2: go through each set of curves, processing the values at each keyframe
- * - it is assumed that there must be a full set of keyframes at each keyframe position
- */
- for (euf = eulers.first; euf; euf = euf->next) {
- int f;
-
- /* sanity check: ensure that there are enough F-Curves to work on in this group */
- /* TODO: also enforce assumption that there be a full set of keyframes
- * at each position by ensuring that totvert counts are same? */
- if (ELEM(NULL, euf->fcurves[0], euf->fcurves[1], euf->fcurves[2])) {
- /* report which components are missing */
- BKE_reportf(op->reports, RPT_WARNING,
- "Missing %s%s%s component(s) of euler rotation for ID='%s' and RNA-Path='%s'",
- (euf->fcurves[0] == NULL) ? "X" : "",
- (euf->fcurves[1] == NULL) ? "Y" : "",
- (euf->fcurves[2] == NULL) ? "Z" : "",
- euf->id->name, euf->rna_path);
-
- /* keep track of number of failed sets, and carry on to next group */
- failed++;
- continue;
- }
-
- /* simple method: just treat any difference between keys of greater than 180 degrees as being a flip */
- /* FIXME: there are more complicated methods that will be needed to fix more cases than just some */
- for (f = 0; f < 3; f++) {
- FCurve *fcu = euf->fcurves[f];
- BezTriple *bezt, *prev;
- unsigned int i;
-
- /* skip if not enough vets to do a decent analysis of... */
- if (fcu->totvert <= 2)
- continue;
-
- /* prev follows bezt, bezt = "current" point to be fixed */
- /* our method depends on determining a "difference" from the previous vert */
- for (i = 1, prev = fcu->bezt, bezt = fcu->bezt + 1; i < fcu->totvert; i++, prev = bezt++) {
- const float sign = (prev->vec[1][1] > bezt->vec[1][1]) ? 1.0f : -1.0f;
-
- /* > 180 degree flip? */
- if ((sign * (prev->vec[1][1] - bezt->vec[1][1])) >= (float)M_PI) {
- /* 360 degrees to add/subtract frame value until difference
- * is acceptably small that there's no more flip */
- const float fac = sign * 2.0f * (float)M_PI;
-
- while ((sign * (prev->vec[1][1] - bezt->vec[1][1])) >= (float)M_PI) {
- bezt->vec[0][1] += fac;
- bezt->vec[1][1] += fac;
- bezt->vec[2][1] += fac;
- }
- }
- }
- }
- }
- BLI_freelistN(&eulers);
-
- ANIM_animdata_update(&ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
-
- /* updates + finishing warnings */
- if (failed == groups) {
- BKE_report(op->reports, RPT_ERROR,
- "No Euler Rotations could be corrected, ensure each rotation has keys for all components, "
- "and that F-Curves for these are in consecutive XYZ order and selected");
- return OPERATOR_CANCELLED;
- }
- else {
- if (failed) {
- BKE_report(op->reports, RPT_ERROR,
- "Some Euler Rotations could not be corrected due to missing/unselected/out-of-order F-Curves, "
- "ensure each rotation has keys for all components, and that F-Curves for these are in "
- "consecutive XYZ order and selected");
- }
-
- /* set notifier that keyframes have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
-
- /* done at last */
- return OPERATOR_FINISHED;
- }
+ bAnimContext ac;
+
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ ListBase eulers = {NULL, NULL};
+ tEulerFilter *euf = NULL;
+ int groups = 0, failed = 0;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* The process is done in two passes:
+ * 1) Sets of three related rotation curves are identified from the selected channels,
+ * and are stored as a single 'operation unit' for the next step
+ * 2) Each set of three F-Curves is processed for each keyframe, with the values being
+ * processed as necessary
+ */
+
+ /* step 1: extract only the rotation f-curves */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_CURVE_VISIBLE |
+ ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ FCurve *fcu = (FCurve *)ale->data;
+
+ /* check if this is an appropriate F-Curve
+ * - only rotation curves
+ * - for pchan curves, make sure we're only using the euler curves
+ */
+ if (strstr(fcu->rna_path, "rotation_euler") == NULL)
+ continue;
+ else if (ELEM(fcu->array_index, 0, 1, 2) == 0) {
+ BKE_reportf(op->reports,
+ RPT_WARNING,
+ "Euler Rotation F-Curve has invalid index (ID='%s', Path='%s', Index=%d)",
+ (ale->id) ? ale->id->name : TIP_("<No ID>"),
+ fcu->rna_path,
+ fcu->array_index);
+ continue;
+ }
+
+ /* optimization: assume that xyz curves will always be stored consecutively,
+ * so if the paths or the ID's don't match up, then a curve needs to be added
+ * to a new group
+ */
+ if ((euf) && (euf->id == ale->id) && (STREQ(euf->rna_path, fcu->rna_path))) {
+ /* this should be fine to add to the existing group then */
+ euf->fcurves[fcu->array_index] = fcu;
+ }
+ else {
+ /* just add to a new block */
+ euf = MEM_callocN(sizeof(tEulerFilter), "tEulerFilter");
+ BLI_addtail(&eulers, euf);
+ groups++;
+
+ euf->id = ale->id;
+ /* this should be safe, since we're only using it for a short time */
+ euf->rna_path = fcu->rna_path;
+ euf->fcurves[fcu->array_index] = fcu;
+ }
+
+ ale->update |= ANIM_UPDATE_DEFAULT;
+ }
+
+ if (groups == 0) {
+ ANIM_animdata_freelist(&anim_data);
+ BKE_report(op->reports, RPT_WARNING, "No Euler Rotation F-Curves to fix up");
+ return OPERATOR_CANCELLED;
+ }
+
+ /* step 2: go through each set of curves, processing the values at each keyframe
+ * - it is assumed that there must be a full set of keyframes at each keyframe position
+ */
+ for (euf = eulers.first; euf; euf = euf->next) {
+ int f;
+
+ /* sanity check: ensure that there are enough F-Curves to work on in this group */
+ /* TODO: also enforce assumption that there be a full set of keyframes
+ * at each position by ensuring that totvert counts are same? */
+ if (ELEM(NULL, euf->fcurves[0], euf->fcurves[1], euf->fcurves[2])) {
+ /* report which components are missing */
+ BKE_reportf(op->reports,
+ RPT_WARNING,
+ "Missing %s%s%s component(s) of euler rotation for ID='%s' and RNA-Path='%s'",
+ (euf->fcurves[0] == NULL) ? "X" : "",
+ (euf->fcurves[1] == NULL) ? "Y" : "",
+ (euf->fcurves[2] == NULL) ? "Z" : "",
+ euf->id->name,
+ euf->rna_path);
+
+ /* keep track of number of failed sets, and carry on to next group */
+ failed++;
+ continue;
+ }
+
+ /* simple method: just treat any difference between keys of greater than 180 degrees as being a flip */
+ /* FIXME: there are more complicated methods that will be needed to fix more cases than just some */
+ for (f = 0; f < 3; f++) {
+ FCurve *fcu = euf->fcurves[f];
+ BezTriple *bezt, *prev;
+ unsigned int i;
+
+ /* skip if not enough vets to do a decent analysis of... */
+ if (fcu->totvert <= 2)
+ continue;
+
+ /* prev follows bezt, bezt = "current" point to be fixed */
+ /* our method depends on determining a "difference" from the previous vert */
+ for (i = 1, prev = fcu->bezt, bezt = fcu->bezt + 1; i < fcu->totvert; i++, prev = bezt++) {
+ const float sign = (prev->vec[1][1] > bezt->vec[1][1]) ? 1.0f : -1.0f;
+
+ /* > 180 degree flip? */
+ if ((sign * (prev->vec[1][1] - bezt->vec[1][1])) >= (float)M_PI) {
+ /* 360 degrees to add/subtract frame value until difference
+ * is acceptably small that there's no more flip */
+ const float fac = sign * 2.0f * (float)M_PI;
+
+ while ((sign * (prev->vec[1][1] - bezt->vec[1][1])) >= (float)M_PI) {
+ bezt->vec[0][1] += fac;
+ bezt->vec[1][1] += fac;
+ bezt->vec[2][1] += fac;
+ }
+ }
+ }
+ }
+ }
+ BLI_freelistN(&eulers);
+
+ ANIM_animdata_update(&ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
+
+ /* updates + finishing warnings */
+ if (failed == groups) {
+ BKE_report(
+ op->reports,
+ RPT_ERROR,
+ "No Euler Rotations could be corrected, ensure each rotation has keys for all components, "
+ "and that F-Curves for these are in consecutive XYZ order and selected");
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ if (failed) {
+ BKE_report(
+ op->reports,
+ RPT_ERROR,
+ "Some Euler Rotations could not be corrected due to missing/unselected/out-of-order "
+ "F-Curves, "
+ "ensure each rotation has keys for all components, and that F-Curves for these are in "
+ "consecutive XYZ order and selected");
+ }
+
+ /* set notifier that keyframes have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+
+ /* done at last */
+ return OPERATOR_FINISHED;
+ }
}
void GRAPH_OT_euler_filter(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Euler Discontinuity Filter";
- ot->idname = "GRAPH_OT_euler_filter";
- ot->description = "Fix large jumps and flips in the selected "
- "Euler Rotation F-Curves arising from rotation "
- "values being clipped when baking physics";
+ /* identifiers */
+ ot->name = "Euler Discontinuity Filter";
+ ot->idname = "GRAPH_OT_euler_filter";
+ ot->description =
+ "Fix large jumps and flips in the selected "
+ "Euler Rotation F-Curves arising from rotation "
+ "values being clipped when baking physics";
- /* api callbacks */
- ot->exec = graphkeys_euler_filter_exec;
- ot->poll = graphop_editable_keyframes_poll;
+ /* api callbacks */
+ ot->exec = graphkeys_euler_filter_exec;
+ ot->poll = graphop_editable_keyframes_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ***************** Jump to Selected Frames Operator *********************** */
static bool graphkeys_framejump_poll(bContext *C)
{
- /* prevent changes during render */
- if (G.is_rendering)
- return 0;
+ /* prevent changes during render */
+ if (G.is_rendering)
+ return 0;
- return graphop_visible_keyframes_poll(C);
+ return graphop_visible_keyframes_poll(C);
}
/* snap current-frame indicator to 'average time' of selected keyframe */
static int graphkeys_framejump_exec(bContext *C, wmOperator *UNUSED(op))
{
- bAnimContext ac;
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
- KeyframeEditData ked;
-
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
-
- /* init edit data */
- memset(&ked, 0, sizeof(KeyframeEditData));
-
- /* loop over action data, averaging values */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
- for (ale = anim_data.first; ale; ale = ale->next) {
- AnimData *adt = ANIM_nla_mapping_get(&ac, ale);
- short mapping_flag = ANIM_get_normalization_flags(&ac);
- KeyframeEditData current_ked;
- float offset;
- float unit_scale = ANIM_unit_mapping_get_factor(ac.scene, ale->id, ale->key_data, mapping_flag | ANIM_UNITCONV_ONLYKEYS, &offset);
-
- memset(&current_ked, 0, sizeof(current_ked));
-
- if (adt) {
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
- ANIM_fcurve_keyframes_loop(&current_ked, ale->key_data, NULL, bezt_calc_average, NULL);
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1);
- }
- else
- ANIM_fcurve_keyframes_loop(&current_ked, ale->key_data, NULL, bezt_calc_average, NULL);
-
- ked.f1 += current_ked.f1;
- ked.i1 += current_ked.i1;
- ked.f2 += (current_ked.f2 + offset) * unit_scale;
- ked.i2 += current_ked.i2;
- }
-
- ANIM_animdata_freelist(&anim_data);
-
- /* set the new current frame and cursor values, based on the average time and value */
- if (ked.i1) {
- SpaceGraph *sipo = (SpaceGraph *)ac.sl;
- Scene *scene = ac.scene;
-
- /* take the average values, rounding to the nearest int as necessary for int results */
- if (sipo->mode == SIPO_MODE_DRIVERS) {
- /* Drivers Mode - Affects cursor (float) */
- sipo->cursorTime = ked.f1 / (float)ked.i1;
- sipo->cursorVal = ked.f2 / (float)ked.i1;
- }
- else {
- /* Animation Mode - Affects current frame (int) */
- CFRA = round_fl_to_int(ked.f1 / ked.i1);
- SUBFRA = 0.f;
- sipo->cursorVal = ked.f2 / (float)ked.i1;
- }
- }
-
- /* set notifier that things have changed */
- WM_event_add_notifier(C, NC_SCENE | ND_FRAME, ac.scene);
-
- return OPERATOR_FINISHED;
+ bAnimContext ac;
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+ KeyframeEditData ked;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* init edit data */
+ memset(&ked, 0, sizeof(KeyframeEditData));
+
+ /* loop over action data, averaging values */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ AnimData *adt = ANIM_nla_mapping_get(&ac, ale);
+ short mapping_flag = ANIM_get_normalization_flags(&ac);
+ KeyframeEditData current_ked;
+ float offset;
+ float unit_scale = ANIM_unit_mapping_get_factor(
+ ac.scene, ale->id, ale->key_data, mapping_flag | ANIM_UNITCONV_ONLYKEYS, &offset);
+
+ memset(&current_ked, 0, sizeof(current_ked));
+
+ if (adt) {
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
+ ANIM_fcurve_keyframes_loop(&current_ked, ale->key_data, NULL, bezt_calc_average, NULL);
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1);
+ }
+ else
+ ANIM_fcurve_keyframes_loop(&current_ked, ale->key_data, NULL, bezt_calc_average, NULL);
+
+ ked.f1 += current_ked.f1;
+ ked.i1 += current_ked.i1;
+ ked.f2 += (current_ked.f2 + offset) * unit_scale;
+ ked.i2 += current_ked.i2;
+ }
+
+ ANIM_animdata_freelist(&anim_data);
+
+ /* set the new current frame and cursor values, based on the average time and value */
+ if (ked.i1) {
+ SpaceGraph *sipo = (SpaceGraph *)ac.sl;
+ Scene *scene = ac.scene;
+
+ /* take the average values, rounding to the nearest int as necessary for int results */
+ if (sipo->mode == SIPO_MODE_DRIVERS) {
+ /* Drivers Mode - Affects cursor (float) */
+ sipo->cursorTime = ked.f1 / (float)ked.i1;
+ sipo->cursorVal = ked.f2 / (float)ked.i1;
+ }
+ else {
+ /* Animation Mode - Affects current frame (int) */
+ CFRA = round_fl_to_int(ked.f1 / ked.i1);
+ SUBFRA = 0.f;
+ sipo->cursorVal = ked.f2 / (float)ked.i1;
+ }
+ }
+
+ /* set notifier that things have changed */
+ WM_event_add_notifier(C, NC_SCENE | ND_FRAME, ac.scene);
+
+ return OPERATOR_FINISHED;
}
void GRAPH_OT_frame_jump(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Jump to Keyframes";
- ot->idname = "GRAPH_OT_frame_jump";
- ot->description = "Place the cursor on the midpoint of selected keyframes";
+ /* identifiers */
+ ot->name = "Jump to Keyframes";
+ ot->idname = "GRAPH_OT_frame_jump";
+ ot->description = "Place the cursor on the midpoint of selected keyframes";
- /* api callbacks */
- ot->exec = graphkeys_framejump_exec;
- ot->poll = graphkeys_framejump_poll;
+ /* api callbacks */
+ ot->exec = graphkeys_framejump_exec;
+ ot->poll = graphkeys_framejump_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ******************** Snap Keyframes Operator *********************** */
/* defines for snap keyframes tool */
static const EnumPropertyItem prop_graphkeys_snap_types[] = {
- {GRAPHKEYS_SNAP_CFRA, "CFRA", 0, "Current Frame",
- "Snap selected keyframes to the current frame"},
- {GRAPHKEYS_SNAP_VALUE, "VALUE", 0, "Cursor Value",
- "Set values of selected keyframes to the cursor value (Y/Horizontal component)"},
- {GRAPHKEYS_SNAP_NEAREST_FRAME, "NEAREST_FRAME", 0, "Nearest Frame",
- "Snap selected keyframes to the nearest (whole) frame (use to fix accidental sub-frame offsets)"},
- {GRAPHKEYS_SNAP_NEAREST_SECOND, "NEAREST_SECOND", 0, "Nearest Second",
- "Snap selected keyframes to the nearest second"},
- {GRAPHKEYS_SNAP_NEAREST_MARKER, "NEAREST_MARKER", 0, "Nearest Marker",
- "Snap selected keyframes to the nearest marker"},
- {GRAPHKEYS_SNAP_HORIZONTAL, "HORIZONTAL", 0, "Flatten Handles",
- "Flatten handles for a smoother transition"},
- {0, NULL, 0, NULL, NULL},
+ {GRAPHKEYS_SNAP_CFRA,
+ "CFRA",
+ 0,
+ "Current Frame",
+ "Snap selected keyframes to the current frame"},
+ {GRAPHKEYS_SNAP_VALUE,
+ "VALUE",
+ 0,
+ "Cursor Value",
+ "Set values of selected keyframes to the cursor value (Y/Horizontal component)"},
+ {GRAPHKEYS_SNAP_NEAREST_FRAME,
+ "NEAREST_FRAME",
+ 0,
+ "Nearest Frame",
+ "Snap selected keyframes to the nearest (whole) frame (use to fix accidental sub-frame "
+ "offsets)"},
+ {GRAPHKEYS_SNAP_NEAREST_SECOND,
+ "NEAREST_SECOND",
+ 0,
+ "Nearest Second",
+ "Snap selected keyframes to the nearest second"},
+ {GRAPHKEYS_SNAP_NEAREST_MARKER,
+ "NEAREST_MARKER",
+ 0,
+ "Nearest Marker",
+ "Snap selected keyframes to the nearest marker"},
+ {GRAPHKEYS_SNAP_HORIZONTAL,
+ "HORIZONTAL",
+ 0,
+ "Flatten Handles",
+ "Flatten handles for a smoother transition"},
+ {0, NULL, 0, NULL, NULL},
};
/* this function is responsible for snapping keyframes to frame-times */
static void snap_graph_keys(bAnimContext *ac, short mode)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- SpaceGraph *sipo = (SpaceGraph *)ac->sl;
- KeyframeEditData ked;
- KeyframeEditFunc edit_cb;
- float cursor_value = 0.0f;
-
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* init custom data for iterating over keyframes */
- memset(&ked, 0, sizeof(KeyframeEditData));
- ked.scene = ac->scene;
- if (mode == GRAPHKEYS_SNAP_NEAREST_MARKER) {
- ked.list.first = (ac->markers) ? ac->markers->first : NULL;
- ked.list.last = (ac->markers) ? ac->markers->last : NULL;
- }
- else if (mode == GRAPHKEYS_SNAP_VALUE) {
- cursor_value = (sipo) ? sipo->cursorVal : 0.0f;
- }
- else if (mode == GRAPHKEYS_SNAP_CFRA) {
- /* In drivers mode, use the cursor value instead
- * (We need to use a different callback for that though)
- */
- if (sipo->mode == SIPO_MODE_DRIVERS) {
- ked.f1 = sipo->cursorTime;
- mode = SNAP_KEYS_TIME;
- }
- }
-
- /* get beztriple editing callbacks */
- edit_cb = ANIM_editkeyframes_snap(mode);
-
- /* snap keyframes */
- for (ale = anim_data.first; ale; ale = ale->next) {
- AnimData *adt = ANIM_nla_mapping_get(ac, ale);
-
- /* normalise cursor value (for normalised F-Curves display) */
- if (mode == GRAPHKEYS_SNAP_VALUE) {
- short mapping_flag = ANIM_get_normalization_flags(ac);
- float offset;
- float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, ale->key_data, mapping_flag, &offset);
-
- ked.f1 = (cursor_value / unit_scale) - offset;
- }
-
- /* perform snapping */
- if (adt) {
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0);
- ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, edit_cb, calchandles_fcurve);
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 0);
- }
- else
- ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, edit_cb, calchandles_fcurve);
-
- ale->update |= ANIM_UPDATE_DEFAULT;
- }
-
- ANIM_animdata_update(ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ SpaceGraph *sipo = (SpaceGraph *)ac->sl;
+ KeyframeEditData ked;
+ KeyframeEditFunc edit_cb;
+ float cursor_value = 0.0f;
+
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT |
+ ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* init custom data for iterating over keyframes */
+ memset(&ked, 0, sizeof(KeyframeEditData));
+ ked.scene = ac->scene;
+ if (mode == GRAPHKEYS_SNAP_NEAREST_MARKER) {
+ ked.list.first = (ac->markers) ? ac->markers->first : NULL;
+ ked.list.last = (ac->markers) ? ac->markers->last : NULL;
+ }
+ else if (mode == GRAPHKEYS_SNAP_VALUE) {
+ cursor_value = (sipo) ? sipo->cursorVal : 0.0f;
+ }
+ else if (mode == GRAPHKEYS_SNAP_CFRA) {
+ /* In drivers mode, use the cursor value instead
+ * (We need to use a different callback for that though)
+ */
+ if (sipo->mode == SIPO_MODE_DRIVERS) {
+ ked.f1 = sipo->cursorTime;
+ mode = SNAP_KEYS_TIME;
+ }
+ }
+
+ /* get beztriple editing callbacks */
+ edit_cb = ANIM_editkeyframes_snap(mode);
+
+ /* snap keyframes */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ AnimData *adt = ANIM_nla_mapping_get(ac, ale);
+
+ /* normalise cursor value (for normalised F-Curves display) */
+ if (mode == GRAPHKEYS_SNAP_VALUE) {
+ short mapping_flag = ANIM_get_normalization_flags(ac);
+ float offset;
+ float unit_scale = ANIM_unit_mapping_get_factor(
+ ac->scene, ale->id, ale->key_data, mapping_flag, &offset);
+
+ ked.f1 = (cursor_value / unit_scale) - offset;
+ }
+
+ /* perform snapping */
+ if (adt) {
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0);
+ ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, edit_cb, calchandles_fcurve);
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 0);
+ }
+ else
+ ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, edit_cb, calchandles_fcurve);
+
+ ale->update |= ANIM_UPDATE_DEFAULT;
+ }
+
+ ANIM_animdata_update(ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
}
/* ------------------- */
static int graphkeys_snap_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- short mode;
+ bAnimContext ac;
+ short mode;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* get snapping mode */
- mode = RNA_enum_get(op->ptr, "type");
+ /* get snapping mode */
+ mode = RNA_enum_get(op->ptr, "type");
- /* snap keyframes */
- snap_graph_keys(&ac, mode);
+ /* snap keyframes */
+ snap_graph_keys(&ac, mode);
- /* set notifier that keyframes have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+ /* set notifier that keyframes have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void GRAPH_OT_snap(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Snap Keys";
- ot->idname = "GRAPH_OT_snap";
- ot->description = "Snap selected keyframes to the chosen times/values";
+ /* identifiers */
+ ot->name = "Snap Keys";
+ ot->idname = "GRAPH_OT_snap";
+ ot->description = "Snap selected keyframes to the chosen times/values";
- /* api callbacks */
- ot->invoke = WM_menu_invoke;
- ot->exec = graphkeys_snap_exec;
- ot->poll = graphop_editable_keyframes_poll;
+ /* api callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = graphkeys_snap_exec;
+ ot->poll = graphop_editable_keyframes_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* id-props */
- ot->prop = RNA_def_enum(ot->srna, "type", prop_graphkeys_snap_types, 0, "Type", "");
+ /* id-props */
+ ot->prop = RNA_def_enum(ot->srna, "type", prop_graphkeys_snap_types, 0, "Type", "");
}
/* ******************** Mirror Keyframes Operator *********************** */
/* defines for mirror keyframes tool */
static const EnumPropertyItem prop_graphkeys_mirror_types[] = {
- {GRAPHKEYS_MIRROR_CFRA, "CFRA", 0, "By Times over Current Frame",
- "Flip times of selected keyframes using the current frame as the mirror line"},
- {GRAPHKEYS_MIRROR_VALUE, "VALUE", 0, "By Values over Cursor Value",
- "Flip values of selected keyframes using the cursor value (Y/Horizontal component) as the mirror line"},
- {GRAPHKEYS_MIRROR_YAXIS, "YAXIS", 0, "By Times over Time=0",
- "Flip times of selected keyframes, effectively reversing the order they appear in"},
- {GRAPHKEYS_MIRROR_XAXIS, "XAXIS", 0, "By Values over Value=0",
- "Flip values of selected keyframes (i.e. negative values become positive, and vice versa)"},
- {GRAPHKEYS_MIRROR_MARKER, "MARKER", 0, "By Times over First Selected Marker",
- "Flip times of selected keyframes using the first selected marker as the reference point"},
- {0, NULL, 0, NULL, NULL},
+ {GRAPHKEYS_MIRROR_CFRA,
+ "CFRA",
+ 0,
+ "By Times over Current Frame",
+ "Flip times of selected keyframes using the current frame as the mirror line"},
+ {GRAPHKEYS_MIRROR_VALUE,
+ "VALUE",
+ 0,
+ "By Values over Cursor Value",
+ "Flip values of selected keyframes using the cursor value (Y/Horizontal component) as the "
+ "mirror line"},
+ {GRAPHKEYS_MIRROR_YAXIS,
+ "YAXIS",
+ 0,
+ "By Times over Time=0",
+ "Flip times of selected keyframes, effectively reversing the order they appear in"},
+ {GRAPHKEYS_MIRROR_XAXIS,
+ "XAXIS",
+ 0,
+ "By Values over Value=0",
+ "Flip values of selected keyframes (i.e. negative values become positive, and vice versa)"},
+ {GRAPHKEYS_MIRROR_MARKER,
+ "MARKER",
+ 0,
+ "By Times over First Selected Marker",
+ "Flip times of selected keyframes using the first selected marker as the reference point"},
+ {0, NULL, 0, NULL, NULL},
};
/* this function is responsible for mirroring keyframes */
static void mirror_graph_keys(bAnimContext *ac, short mode)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- SpaceGraph *sipo = (SpaceGraph *)ac->sl;
- KeyframeEditData ked;
- KeyframeEditFunc edit_cb;
- float cursor_value = 0.0f;
-
- /* init custom data for looping over keyframes */
- memset(&ked, 0, sizeof(KeyframeEditData));
- ked.scene = ac->scene;
-
- /* store mode-specific custom data... */
- if (mode == GRAPHKEYS_MIRROR_MARKER) {
- TimeMarker *marker = NULL;
-
- /* find first selected marker */
- marker = ED_markers_get_first_selected(ac->markers);
-
- /* store marker's time (if available) */
- if (marker)
- ked.f1 = (float)marker->frame;
- else
- return;
- }
- else if (mode == GRAPHKEYS_MIRROR_VALUE) {
- cursor_value = (sipo) ? sipo->cursorVal : 0.0f;
- }
- else if (mode == GRAPHKEYS_MIRROR_CFRA) {
- /* In drivers mode, use the cursor value instead
- * (We need to use a different callback for that though)
- */
- if (sipo->mode == SIPO_MODE_DRIVERS) {
- ked.f1 = sipo->cursorTime;
- mode = MIRROR_KEYS_TIME;
- }
- }
-
- /* get beztriple editing callbacks */
- edit_cb = ANIM_editkeyframes_mirror(mode);
-
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* mirror keyframes */
- for (ale = anim_data.first; ale; ale = ale->next) {
- AnimData *adt = ANIM_nla_mapping_get(ac, ale);
-
- /* apply unit corrections */
- if (mode == GRAPHKEYS_MIRROR_VALUE) {
- short mapping_flag = ANIM_get_normalization_flags(ac);
- float offset;
- float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, ale->key_data, mapping_flag | ANIM_UNITCONV_ONLYKEYS, &offset);
-
- ked.f1 = (cursor_value + offset) * unit_scale;
- }
-
- /* perform actual mirroring */
- if (adt) {
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0);
- ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, edit_cb, calchandles_fcurve);
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 0);
- }
- else
- ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, edit_cb, calchandles_fcurve);
-
- ale->update |= ANIM_UPDATE_DEFAULT;
- }
-
- ANIM_animdata_update(ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ SpaceGraph *sipo = (SpaceGraph *)ac->sl;
+ KeyframeEditData ked;
+ KeyframeEditFunc edit_cb;
+ float cursor_value = 0.0f;
+
+ /* init custom data for looping over keyframes */
+ memset(&ked, 0, sizeof(KeyframeEditData));
+ ked.scene = ac->scene;
+
+ /* store mode-specific custom data... */
+ if (mode == GRAPHKEYS_MIRROR_MARKER) {
+ TimeMarker *marker = NULL;
+
+ /* find first selected marker */
+ marker = ED_markers_get_first_selected(ac->markers);
+
+ /* store marker's time (if available) */
+ if (marker)
+ ked.f1 = (float)marker->frame;
+ else
+ return;
+ }
+ else if (mode == GRAPHKEYS_MIRROR_VALUE) {
+ cursor_value = (sipo) ? sipo->cursorVal : 0.0f;
+ }
+ else if (mode == GRAPHKEYS_MIRROR_CFRA) {
+ /* In drivers mode, use the cursor value instead
+ * (We need to use a different callback for that though)
+ */
+ if (sipo->mode == SIPO_MODE_DRIVERS) {
+ ked.f1 = sipo->cursorTime;
+ mode = MIRROR_KEYS_TIME;
+ }
+ }
+
+ /* get beztriple editing callbacks */
+ edit_cb = ANIM_editkeyframes_mirror(mode);
+
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT |
+ ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* mirror keyframes */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ AnimData *adt = ANIM_nla_mapping_get(ac, ale);
+
+ /* apply unit corrections */
+ if (mode == GRAPHKEYS_MIRROR_VALUE) {
+ short mapping_flag = ANIM_get_normalization_flags(ac);
+ float offset;
+ float unit_scale = ANIM_unit_mapping_get_factor(
+ ac->scene, ale->id, ale->key_data, mapping_flag | ANIM_UNITCONV_ONLYKEYS, &offset);
+
+ ked.f1 = (cursor_value + offset) * unit_scale;
+ }
+
+ /* perform actual mirroring */
+ if (adt) {
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0);
+ ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, edit_cb, calchandles_fcurve);
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 0);
+ }
+ else
+ ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, edit_cb, calchandles_fcurve);
+
+ ale->update |= ANIM_UPDATE_DEFAULT;
+ }
+
+ ANIM_animdata_update(ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
}
/* ------------------- */
static int graphkeys_mirror_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- short mode;
+ bAnimContext ac;
+ short mode;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* get mirroring mode */
- mode = RNA_enum_get(op->ptr, "type");
+ /* get mirroring mode */
+ mode = RNA_enum_get(op->ptr, "type");
- /* mirror keyframes */
- mirror_graph_keys(&ac, mode);
+ /* mirror keyframes */
+ mirror_graph_keys(&ac, mode);
- /* set notifier that keyframes have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+ /* set notifier that keyframes have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void GRAPH_OT_mirror(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Mirror Keys";
- ot->idname = "GRAPH_OT_mirror";
- ot->description = "Flip selected keyframes over the selected mirror line";
+ /* identifiers */
+ ot->name = "Mirror Keys";
+ ot->idname = "GRAPH_OT_mirror";
+ ot->description = "Flip selected keyframes over the selected mirror line";
- /* api callbacks */
- ot->invoke = WM_menu_invoke;
- ot->exec = graphkeys_mirror_exec;
- ot->poll = graphop_editable_keyframes_poll;
+ /* api callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = graphkeys_mirror_exec;
+ ot->poll = graphop_editable_keyframes_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* id-props */
- ot->prop = RNA_def_enum(ot->srna, "type", prop_graphkeys_mirror_types, 0, "Type", "");
+ /* id-props */
+ ot->prop = RNA_def_enum(ot->srna, "type", prop_graphkeys_mirror_types, 0, "Type", "");
}
/* ******************** Smooth Keyframes Operator *********************** */
static int graphkeys_smooth_exec(bContext *C, wmOperator *UNUSED(op))
{
- bAnimContext ac;
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
+ bAnimContext ac;
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT |
+ ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
- /* smooth keyframes */
- for (ale = anim_data.first; ale; ale = ale->next) {
- /* For now, we can only smooth by flattening handles AND smoothing curve values.
- * Perhaps the mode argument could be removed, as that functionality is offered through
- * Snap->Flatten Handles anyway.
- */
- smooth_fcurve(ale->key_data);
+ /* smooth keyframes */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ /* For now, we can only smooth by flattening handles AND smoothing curve values.
+ * Perhaps the mode argument could be removed, as that functionality is offered through
+ * Snap->Flatten Handles anyway.
+ */
+ smooth_fcurve(ale->key_data);
- ale->update |= ANIM_UPDATE_DEFAULT;
- }
+ ale->update |= ANIM_UPDATE_DEFAULT;
+ }
- ANIM_animdata_update(&ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
+ ANIM_animdata_update(&ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
- /* set notifier that keyframes have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+ /* set notifier that keyframes have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void GRAPH_OT_smooth(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Smooth Keys";
- ot->idname = "GRAPH_OT_smooth";
- ot->description = "Apply weighted moving means to make selected F-Curves less bumpy";
+ /* identifiers */
+ ot->name = "Smooth Keys";
+ ot->idname = "GRAPH_OT_smooth";
+ ot->description = "Apply weighted moving means to make selected F-Curves less bumpy";
- /* api callbacks */
- ot->exec = graphkeys_smooth_exec;
- ot->poll = graphop_editable_keyframes_poll;
+ /* api callbacks */
+ ot->exec = graphkeys_smooth_exec;
+ ot->poll = graphop_editable_keyframes_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ************************************************************************** */
@@ -2392,246 +2623,258 @@ void GRAPH_OT_smooth(wmOperatorType *ot)
/* ******************** Add F-Modifier Operator *********************** */
-static const EnumPropertyItem *graph_fmodifier_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
+static const EnumPropertyItem *graph_fmodifier_itemf(bContext *C,
+ PointerRNA *UNUSED(ptr),
+ PropertyRNA *UNUSED(prop),
+ bool *r_free)
{
- EnumPropertyItem *item = NULL;
- int totitem = 0;
- int i = 0;
+ EnumPropertyItem *item = NULL;
+ int totitem = 0;
+ int i = 0;
- if (C == NULL) {
- return rna_enum_fmodifier_type_items;
- }
+ if (C == NULL) {
+ return rna_enum_fmodifier_type_items;
+ }
- /* start from 1 to skip the 'Invalid' modifier type */
- for (i = 1; i < FMODIFIER_NUM_TYPES; i++) {
- const FModifierTypeInfo *fmi = get_fmodifier_typeinfo(i);
- int index;
+ /* start from 1 to skip the 'Invalid' modifier type */
+ for (i = 1; i < FMODIFIER_NUM_TYPES; i++) {
+ const FModifierTypeInfo *fmi = get_fmodifier_typeinfo(i);
+ int index;
- /* check if modifier is valid for this context */
- if (fmi == NULL)
- continue;
+ /* check if modifier is valid for this context */
+ if (fmi == NULL)
+ continue;
- index = RNA_enum_from_value(rna_enum_fmodifier_type_items, fmi->type);
- if (index != -1) { /* Not all types are implemented yet... */
- RNA_enum_item_add(&item, &totitem, &rna_enum_fmodifier_type_items[index]);
- }
- }
+ index = RNA_enum_from_value(rna_enum_fmodifier_type_items, fmi->type);
+ if (index != -1) { /* Not all types are implemented yet... */
+ RNA_enum_item_add(&item, &totitem, &rna_enum_fmodifier_type_items[index]);
+ }
+ }
- RNA_enum_item_end(&item, &totitem);
- *r_free = true;
+ RNA_enum_item_end(&item, &totitem);
+ *r_free = true;
- return item;
+ return item;
}
static int graph_fmodifier_add_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
- short type;
+ bAnimContext ac;
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+ short type;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* get type of modifier to add */
- type = RNA_enum_get(op->ptr, "type");
+ /* get type of modifier to add */
+ type = RNA_enum_get(op->ptr, "type");
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
- if (RNA_boolean_get(op->ptr, "only_active"))
- filter |= ANIMFILTER_ACTIVE; // FIXME: enforce in this case only a single channel to get handled?
- else
- filter |= (ANIMFILTER_SEL | ANIMFILTER_CURVE_VISIBLE);
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
+ if (RNA_boolean_get(op->ptr, "only_active"))
+ filter |=
+ ANIMFILTER_ACTIVE; // FIXME: enforce in this case only a single channel to get handled?
+ else
+ filter |= (ANIMFILTER_SEL | ANIMFILTER_CURVE_VISIBLE);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
- /* add f-modifier to each curve */
- for (ale = anim_data.first; ale; ale = ale->next) {
- FCurve *fcu = (FCurve *)ale->data;
- FModifier *fcm;
+ /* add f-modifier to each curve */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ FCurve *fcu = (FCurve *)ale->data;
+ FModifier *fcm;
- /* add F-Modifier of specified type to active F-Curve, and make it the active one */
- fcm = add_fmodifier(&fcu->modifiers, type, fcu);
- if (fcm) {
- set_active_fmodifier(&fcu->modifiers, fcm);
- }
- else {
- BKE_report(op->reports, RPT_ERROR, "Modifier could not be added (see console for details)");
- break;
- }
+ /* add F-Modifier of specified type to active F-Curve, and make it the active one */
+ fcm = add_fmodifier(&fcu->modifiers, type, fcu);
+ if (fcm) {
+ set_active_fmodifier(&fcu->modifiers, fcm);
+ }
+ else {
+ BKE_report(op->reports, RPT_ERROR, "Modifier could not be added (see console for details)");
+ break;
+ }
- ale->update |= ANIM_UPDATE_DEPS;
- }
+ ale->update |= ANIM_UPDATE_DEPS;
+ }
- ANIM_animdata_update(&ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
+ ANIM_animdata_update(&ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
- /* set notifier that things have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+ /* set notifier that things have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void GRAPH_OT_fmodifier_add(wmOperatorType *ot)
{
- PropertyRNA *prop;
+ PropertyRNA *prop;
- /* identifiers */
- ot->name = "Add F-Curve Modifier";
- ot->idname = "GRAPH_OT_fmodifier_add";
- ot->description = "Add F-Modifier to the active/selected F-Curves";
+ /* identifiers */
+ ot->name = "Add F-Curve Modifier";
+ ot->idname = "GRAPH_OT_fmodifier_add";
+ ot->description = "Add F-Modifier to the active/selected F-Curves";
- /* api callbacks */
- ot->invoke = WM_menu_invoke;
- ot->exec = graph_fmodifier_add_exec;
- ot->poll = graphop_selected_fcurve_poll;
+ /* api callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = graph_fmodifier_add_exec;
+ ot->poll = graphop_selected_fcurve_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* id-props */
- prop = RNA_def_enum(ot->srna, "type", rna_enum_fmodifier_type_items, 0, "Type", "");
- RNA_def_enum_funcs(prop, graph_fmodifier_itemf);
- ot->prop = prop;
+ /* id-props */
+ prop = RNA_def_enum(ot->srna, "type", rna_enum_fmodifier_type_items, 0, "Type", "");
+ RNA_def_enum_funcs(prop, graph_fmodifier_itemf);
+ ot->prop = prop;
- RNA_def_boolean(ot->srna, "only_active", 1, "Only Active", "Only add F-Modifier to active F-Curve");
+ RNA_def_boolean(
+ ot->srna, "only_active", 1, "Only Active", "Only add F-Modifier to active F-Curve");
}
/* ******************** Copy F-Modifiers Operator *********************** */
static int graph_fmodifier_copy_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- bAnimListElem *ale;
- bool ok = false;
+ bAnimContext ac;
+ bAnimListElem *ale;
+ bool ok = false;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* clear buffer first */
- ANIM_fmodifiers_copybuf_free();
+ /* clear buffer first */
+ ANIM_fmodifiers_copybuf_free();
- /* get the active F-Curve */
- ale = get_active_fcurve_channel(&ac);
+ /* get the active F-Curve */
+ ale = get_active_fcurve_channel(&ac);
- /* if this exists, call the copy F-Modifiers API function */
- if (ale && ale->data) {
- FCurve *fcu = (FCurve *)ale->data;
+ /* if this exists, call the copy F-Modifiers API function */
+ if (ale && ale->data) {
+ FCurve *fcu = (FCurve *)ale->data;
- /* TODO: when 'active' vs 'all' boolean is added, change last param! */
- ok = ANIM_fmodifiers_copy_to_buf(&fcu->modifiers, 0);
+ /* TODO: when 'active' vs 'all' boolean is added, change last param! */
+ ok = ANIM_fmodifiers_copy_to_buf(&fcu->modifiers, 0);
- /* free temp data now */
- MEM_freeN(ale);
- }
+ /* free temp data now */
+ MEM_freeN(ale);
+ }
- /* successful or not? */
- if (ok == 0) {
- BKE_report(op->reports, RPT_ERROR, "No F-Modifiers available to be copied");
- return OPERATOR_CANCELLED;
- }
- else
- return OPERATOR_FINISHED;
+ /* successful or not? */
+ if (ok == 0) {
+ BKE_report(op->reports, RPT_ERROR, "No F-Modifiers available to be copied");
+ return OPERATOR_CANCELLED;
+ }
+ else
+ return OPERATOR_FINISHED;
}
void GRAPH_OT_fmodifier_copy(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Copy F-Modifiers";
- ot->idname = "GRAPH_OT_fmodifier_copy";
- ot->description = "Copy the F-Modifier(s) of the active F-Curve";
+ /* identifiers */
+ ot->name = "Copy F-Modifiers";
+ ot->idname = "GRAPH_OT_fmodifier_copy";
+ ot->description = "Copy the F-Modifier(s) of the active F-Curve";
- /* api callbacks */
- ot->exec = graph_fmodifier_copy_exec;
- ot->poll = graphop_active_fcurve_poll;
+ /* api callbacks */
+ ot->exec = graph_fmodifier_copy_exec;
+ ot->poll = graphop_active_fcurve_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* id-props */
- //ot->prop = RNA_def_boolean(ot->srna, "all", 1, "All F-Modifiers", "Copy all the F-Modifiers, instead of just the active one");
+ /* id-props */
+ //ot->prop = RNA_def_boolean(ot->srna, "all", 1, "All F-Modifiers", "Copy all the F-Modifiers, instead of just the active one");
}
/* ******************** Paste F-Modifiers Operator *********************** */
static int graph_fmodifier_paste_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
+ bAnimContext ac;
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
- const bool replace = RNA_boolean_get(op->ptr, "replace");
- bool ok = false;
+ const bool replace = RNA_boolean_get(op->ptr, "replace");
+ bool ok = false;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* filter data */
- if (RNA_boolean_get(op->ptr, "only_active")) {
- /* This should be the default (for buttons) - Just paste to the active FCurve */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_ACTIVE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
- }
- else {
- /* This is only if the operator gets called from a hotkey or search - Paste to all visible curves */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
- }
+ /* filter data */
+ if (RNA_boolean_get(op->ptr, "only_active")) {
+ /* This should be the default (for buttons) - Just paste to the active FCurve */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_ACTIVE | ANIMFILTER_FOREDIT |
+ ANIMFILTER_NODUPLIS);
+ }
+ else {
+ /* This is only if the operator gets called from a hotkey or search - Paste to all visible curves */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_SEL |
+ ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
+ }
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
- /* paste modifiers */
- for (ale = anim_data.first; ale; ale = ale->next) {
- FCurve *fcu = (FCurve *)ale->data;
- int tot;
+ /* paste modifiers */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ FCurve *fcu = (FCurve *)ale->data;
+ int tot;
- tot = ANIM_fmodifiers_paste_from_buf(&fcu->modifiers, replace, fcu);
+ tot = ANIM_fmodifiers_paste_from_buf(&fcu->modifiers, replace, fcu);
- if (tot) {
- ale->update |= ANIM_UPDATE_DEPS;
- ok = true;
- }
- }
+ if (tot) {
+ ale->update |= ANIM_UPDATE_DEPS;
+ ok = true;
+ }
+ }
- if (ok) {
- ANIM_animdata_update(&ac, &anim_data);
- }
- ANIM_animdata_freelist(&anim_data);
+ if (ok) {
+ ANIM_animdata_update(&ac, &anim_data);
+ }
+ ANIM_animdata_freelist(&anim_data);
- /* successful or not? */
- if (ok) {
- /* set notifier that keyframes have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+ /* successful or not? */
+ if (ok) {
+ /* set notifier that keyframes have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
- return OPERATOR_FINISHED;
- }
- else {
- BKE_report(op->reports, RPT_ERROR, "No F-Modifiers to paste");
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_FINISHED;
+ }
+ else {
+ BKE_report(op->reports, RPT_ERROR, "No F-Modifiers to paste");
+ return OPERATOR_CANCELLED;
+ }
}
void GRAPH_OT_fmodifier_paste(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Paste F-Modifiers";
- ot->idname = "GRAPH_OT_fmodifier_paste";
- ot->description = "Add copied F-Modifiers to the selected F-Curves";
+ /* identifiers */
+ ot->name = "Paste F-Modifiers";
+ ot->idname = "GRAPH_OT_fmodifier_paste";
+ ot->description = "Add copied F-Modifiers to the selected F-Curves";
- /* api callbacks */
- ot->exec = graph_fmodifier_paste_exec;
- ot->poll = graphop_active_fcurve_poll;
+ /* api callbacks */
+ ot->exec = graph_fmodifier_paste_exec;
+ ot->poll = graphop_active_fcurve_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* properties */
- RNA_def_boolean(ot->srna, "only_active", true, "Only Active", "Only paste F-Modifiers on active F-Curve");
- RNA_def_boolean(ot->srna, "replace", false, "Replace Existing",
- "Replace existing F-Modifiers, instead of just appending to the end of the existing list");
+ /* properties */
+ RNA_def_boolean(
+ ot->srna, "only_active", true, "Only Active", "Only paste F-Modifiers on active F-Curve");
+ RNA_def_boolean(
+ ot->srna,
+ "replace",
+ false,
+ "Replace Existing",
+ "Replace existing F-Modifiers, instead of just appending to the end of the existing list");
}
/* ************************************************************************** */
@@ -2641,200 +2884,204 @@ void GRAPH_OT_fmodifier_paste(wmOperatorType *ot)
static int graph_driver_vars_copy_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- bAnimListElem *ale;
- bool ok = false;
+ bAnimContext ac;
+ bAnimListElem *ale;
+ bool ok = false;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* clear buffer first */
- ANIM_driver_vars_copybuf_free();
+ /* clear buffer first */
+ ANIM_driver_vars_copybuf_free();
- /* get the active F-Curve */
- ale = get_active_fcurve_channel(&ac);
+ /* get the active F-Curve */
+ ale = get_active_fcurve_channel(&ac);
- /* if this exists, call the copy driver vars API function */
- if (ale && ale->data) {
- FCurve *fcu = (FCurve *)ale->data;
+ /* if this exists, call the copy driver vars API function */
+ if (ale && ale->data) {
+ FCurve *fcu = (FCurve *)ale->data;
- ok = ANIM_driver_vars_copy(op->reports, fcu);
+ ok = ANIM_driver_vars_copy(op->reports, fcu);
- /* free temp data now */
- MEM_freeN(ale);
- }
+ /* free temp data now */
+ MEM_freeN(ale);
+ }
- /* successful or not? */
- if (ok)
- return OPERATOR_FINISHED;
- else
- return OPERATOR_CANCELLED;
+ /* successful or not? */
+ if (ok)
+ return OPERATOR_FINISHED;
+ else
+ return OPERATOR_CANCELLED;
}
void GRAPH_OT_driver_variables_copy(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Copy Driver Variables";
- ot->idname = "GRAPH_OT_driver_variables_copy";
- ot->description = "Copy the driver variables of the active F-Curve";
+ /* identifiers */
+ ot->name = "Copy Driver Variables";
+ ot->idname = "GRAPH_OT_driver_variables_copy";
+ ot->description = "Copy the driver variables of the active F-Curve";
- /* api callbacks */
- ot->exec = graph_driver_vars_copy_exec;
- ot->poll = graphop_active_fcurve_poll;
+ /* api callbacks */
+ ot->exec = graph_driver_vars_copy_exec;
+ ot->poll = graphop_active_fcurve_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ******************** Paste Driver Vars Operator *********************** */
static int graph_driver_vars_paste_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
+ bAnimContext ac;
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
- const bool replace = RNA_boolean_get(op->ptr, "replace");
- bool ok = false;
+ const bool replace = RNA_boolean_get(op->ptr, "replace");
+ bool ok = false;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_ACTIVE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_ACTIVE | ANIMFILTER_FOREDIT |
+ ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
- /* paste variables */
- for (ale = anim_data.first; ale; ale = ale->next) {
- FCurve *fcu = (FCurve *)ale->data;
- ok |= ANIM_driver_vars_paste(op->reports, fcu, replace);
- }
+ /* paste variables */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ FCurve *fcu = (FCurve *)ale->data;
+ ok |= ANIM_driver_vars_paste(op->reports, fcu, replace);
+ }
- /* cleanup */
- ANIM_animdata_freelist(&anim_data);
+ /* cleanup */
+ ANIM_animdata_freelist(&anim_data);
- /* successful or not? */
- if (ok) {
- /* rebuild depsgraph, now that there are extra deps here */
- DEG_relations_tag_update(CTX_data_main(C));
+ /* successful or not? */
+ if (ok) {
+ /* rebuild depsgraph, now that there are extra deps here */
+ DEG_relations_tag_update(CTX_data_main(C));
- /* set notifier that keyframes have changed */
- WM_event_add_notifier(C, NC_SCENE | ND_FRAME, CTX_data_scene(C));
+ /* set notifier that keyframes have changed */
+ WM_event_add_notifier(C, NC_SCENE | ND_FRAME, CTX_data_scene(C));
- return OPERATOR_FINISHED;
- }
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
}
void GRAPH_OT_driver_variables_paste(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Paste Driver Variables";
- ot->idname = "GRAPH_OT_driver_variables_paste";
- ot->description = "Add copied driver variables to the active driver";
+ /* identifiers */
+ ot->name = "Paste Driver Variables";
+ ot->idname = "GRAPH_OT_driver_variables_paste";
+ ot->description = "Add copied driver variables to the active driver";
- /* api callbacks */
- ot->exec = graph_driver_vars_paste_exec;
- ot->poll = graphop_active_fcurve_poll;
+ /* api callbacks */
+ ot->exec = graph_driver_vars_paste_exec;
+ ot->poll = graphop_active_fcurve_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* properties */
- RNA_def_boolean(ot->srna, "replace", false, "Replace Existing",
- "Replace existing driver variables, instead of just appending to the end of the existing list");
+ /* properties */
+ RNA_def_boolean(ot->srna,
+ "replace",
+ false,
+ "Replace Existing",
+ "Replace existing driver variables, instead of just appending to the end of the "
+ "existing list");
}
/* ************************************************************************** */
static int graph_driver_delete_invalid_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
- bool ok = false;
- unsigned int deleted = 0;
-
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
-
- /* NOTE: we might need a scene update to evaluate the driver flags */
-
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
- /* find invalid drivers */
- for (ale = anim_data.first; ale; ale = ale->next) {
- FCurve *fcu = (FCurve *)ale->data;
- if (ELEM(NULL, fcu, fcu->driver)) {
- continue;
- }
- if (!(fcu->driver->flag & DRIVER_FLAG_INVALID)) {
- continue;
- }
-
- ok |= ANIM_remove_driver(op->reports, ale->id, fcu->rna_path, fcu->array_index, 0);
- if (!ok) {
- break;
- }
- deleted += 1;
- }
-
- /* cleanup */
- ANIM_animdata_freelist(&anim_data);
-
- if (deleted > 0) {
- /* notify the world of any changes */
- DEG_relations_tag_update(CTX_data_main(C));
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_REMOVED, NULL);
- WM_reportf(RPT_INFO, "Deleted %u drivers", deleted);
- }
- else {
- WM_report(RPT_INFO, "No drivers deleted");
- }
-
- /* successful or not? */
- if (!ok) {
- return OPERATOR_CANCELLED;
- }
-
- return OPERATOR_FINISHED;
+ bAnimContext ac;
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+ bool ok = false;
+ unsigned int deleted = 0;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* NOTE: we might need a scene update to evaluate the driver flags */
+
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+
+ /* find invalid drivers */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ FCurve *fcu = (FCurve *)ale->data;
+ if (ELEM(NULL, fcu, fcu->driver)) {
+ continue;
+ }
+ if (!(fcu->driver->flag & DRIVER_FLAG_INVALID)) {
+ continue;
+ }
+
+ ok |= ANIM_remove_driver(op->reports, ale->id, fcu->rna_path, fcu->array_index, 0);
+ if (!ok) {
+ break;
+ }
+ deleted += 1;
+ }
+
+ /* cleanup */
+ ANIM_animdata_freelist(&anim_data);
+
+ if (deleted > 0) {
+ /* notify the world of any changes */
+ DEG_relations_tag_update(CTX_data_main(C));
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_REMOVED, NULL);
+ WM_reportf(RPT_INFO, "Deleted %u drivers", deleted);
+ }
+ else {
+ WM_report(RPT_INFO, "No drivers deleted");
+ }
+
+ /* successful or not? */
+ if (!ok) {
+ return OPERATOR_CANCELLED;
+ }
+
+ return OPERATOR_FINISHED;
}
static bool graph_driver_delete_invalid_poll(bContext *C)
{
- bAnimContext ac;
- ScrArea *sa = CTX_wm_area(C);
+ bAnimContext ac;
+ ScrArea *sa = CTX_wm_area(C);
- /* firstly, check if in Graph Editor */
- if ((sa == NULL) || (sa->spacetype != SPACE_GRAPH))
- return 0;
+ /* firstly, check if in Graph Editor */
+ if ((sa == NULL) || (sa->spacetype != SPACE_GRAPH))
+ return 0;
- /* try to init Anim-Context stuff ourselves and check */
- return ANIM_animdata_get_context(C, &ac) != 0;
+ /* try to init Anim-Context stuff ourselves and check */
+ return ANIM_animdata_get_context(C, &ac) != 0;
}
-
void GRAPH_OT_driver_delete_invalid(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Delete Invalid Drivers";
- ot->idname = "GRAPH_OT_driver_delete_invalid";
- ot->description = "Delete all visible drivers considered invalid";
+ /* identifiers */
+ ot->name = "Delete Invalid Drivers";
+ ot->idname = "GRAPH_OT_driver_delete_invalid";
+ ot->description = "Delete all visible drivers considered invalid";
- /* api callbacks */
- ot->exec = graph_driver_delete_invalid_exec;
- ot->poll = graph_driver_delete_invalid_poll;
+ /* api callbacks */
+ ot->exec = graph_driver_delete_invalid_exec;
+ ot->poll = graph_driver_delete_invalid_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
diff --git a/source/blender/editors/space_graph/graph_intern.h b/source/blender/editors/space_graph/graph_intern.h
index 617233f2a20..7d0a3a1f13d 100644
--- a/source/blender/editors/space_graph/graph_intern.h
+++ b/source/blender/editors/space_graph/graph_intern.h
@@ -43,7 +43,11 @@ struct ARegion *graph_has_buttons_region(struct ScrArea *sa);
/* graph_draw.c */
void graph_draw_channel_names(struct bContext *C, struct bAnimContext *ac, struct ARegion *ar);
-void graph_draw_curves(struct bAnimContext *ac, struct SpaceGraph *sipo, struct ARegion *ar, struct View2DGrid *grid, short sel);
+void graph_draw_curves(struct bAnimContext *ac,
+ struct SpaceGraph *sipo,
+ struct ARegion *ar,
+ struct View2DGrid *grid,
+ short sel);
void graph_draw_ghost_curves(struct bAnimContext *ac, struct SpaceGraph *sipo, struct ARegion *ar);
/* ***************************************** */
@@ -64,24 +68,29 @@ void GRAPH_OT_clickselect(struct wmOperatorType *ot);
/* defines for left-right select tool */
enum eGraphKeys_LeftRightSelect_Mode {
- GRAPHKEYS_LRSEL_TEST = 0,
- GRAPHKEYS_LRSEL_LEFT,
- GRAPHKEYS_LRSEL_RIGHT,
+ GRAPHKEYS_LRSEL_TEST = 0,
+ GRAPHKEYS_LRSEL_LEFT,
+ GRAPHKEYS_LRSEL_RIGHT,
};
/* defines for column-select mode */
enum eGraphKeys_ColumnSelect_Mode {
- GRAPHKEYS_COLUMNSEL_KEYS = 0,
- GRAPHKEYS_COLUMNSEL_CFRA,
- GRAPHKEYS_COLUMNSEL_MARKERS_COLUMN,
- GRAPHKEYS_COLUMNSEL_MARKERS_BETWEEN,
+ GRAPHKEYS_COLUMNSEL_KEYS = 0,
+ GRAPHKEYS_COLUMNSEL_CFRA,
+ GRAPHKEYS_COLUMNSEL_MARKERS_COLUMN,
+ GRAPHKEYS_COLUMNSEL_MARKERS_BETWEEN,
};
/* ***************************************** */
/* graph_edit.c */
-void get_graph_keyframe_extents(struct bAnimContext *ac, float *xmin, float *xmax, float *ymin, float *ymax,
- const bool do_selected, const bool include_handles);
+void get_graph_keyframe_extents(struct bAnimContext *ac,
+ float *xmin,
+ float *xmax,
+ float *ymin,
+ float *ymax,
+ const bool do_selected,
+ const bool include_handles);
void GRAPH_OT_previewrange_set(struct wmOperatorType *ot);
void GRAPH_OT_view_all(struct wmOperatorType *ot);
@@ -116,23 +125,23 @@ void GRAPH_OT_mirror(struct wmOperatorType *ot);
* NOTE: keep in sync with eEditKeyframes_Snap (in ED_keyframes_edit.h)
*/
enum eGraphKeys_Snap_Mode {
- GRAPHKEYS_SNAP_CFRA = 1,
- GRAPHKEYS_SNAP_NEAREST_FRAME,
- GRAPHKEYS_SNAP_NEAREST_SECOND,
- GRAPHKEYS_SNAP_NEAREST_MARKER,
- GRAPHKEYS_SNAP_HORIZONTAL,
- GRAPHKEYS_SNAP_VALUE,
+ GRAPHKEYS_SNAP_CFRA = 1,
+ GRAPHKEYS_SNAP_NEAREST_FRAME,
+ GRAPHKEYS_SNAP_NEAREST_SECOND,
+ GRAPHKEYS_SNAP_NEAREST_MARKER,
+ GRAPHKEYS_SNAP_HORIZONTAL,
+ GRAPHKEYS_SNAP_VALUE,
};
/* defines for mirror keyframes
* NOTE: keep in sync with eEditKeyframes_Mirror (in ED_keyframes_edit.h)
*/
enum eGraphKeys_Mirror_Mode {
- GRAPHKEYS_MIRROR_CFRA = 1,
- GRAPHKEYS_MIRROR_YAXIS,
- GRAPHKEYS_MIRROR_XAXIS,
- GRAPHKEYS_MIRROR_MARKER,
- GRAPHKEYS_MIRROR_VALUE,
+ GRAPHKEYS_MIRROR_CFRA = 1,
+ GRAPHKEYS_MIRROR_YAXIS,
+ GRAPHKEYS_MIRROR_XAXIS,
+ GRAPHKEYS_MIRROR_MARKER,
+ GRAPHKEYS_MIRROR_VALUE,
};
/* ----------- */
@@ -173,5 +182,4 @@ bool graphop_selected_fcurve_poll(struct bContext *C);
void graphedit_keymap(struct wmKeyConfig *keyconf);
void graphedit_operatortypes(void);
-
#endif /* __GRAPH_INTERN_H__ */
diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c
index 1c9bbbcdae5..6bbc6a2de1c 100644
--- a/source/blender/editors/space_graph/graph_ops.c
+++ b/source/blender/editors/space_graph/graph_ops.c
@@ -21,7 +21,6 @@
* \ingroup spgraph
*/
-
#include <stdlib.h>
#include <math.h>
@@ -64,55 +63,55 @@
static bool graphview_cursor_poll(bContext *C)
{
- /* prevent changes during render */
- if (G.is_rendering)
- return 0;
+ /* prevent changes during render */
+ if (G.is_rendering)
+ return 0;
- return ED_operator_graphedit_active(C);
+ return ED_operator_graphedit_active(C);
}
/* Set the new frame number */
static void graphview_cursor_apply(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
- SpaceGraph *sipo = CTX_wm_space_graph(C);
- /* this isn't technically "frame", but it'll do... */
- float frame = RNA_float_get(op->ptr, "frame");
-
- /* adjust the frame or the cursor x-value */
- if (sipo->mode == SIPO_MODE_DRIVERS) {
- /* adjust cursor x-value */
- sipo->cursorTime = frame;
- }
- else {
- /* adjust the frame
- * NOTE: sync this part of the code with ANIM_OT_change_frame
- */
- /* 1) frame is rounded to the nearest int, since frames are ints */
- CFRA = round_fl_to_int(frame);
-
- if (scene->r.flag & SCER_LOCK_FRAME_SELECTION) {
- /* Clip to preview range
- * NOTE: Preview range won't go into negative values,
- * so only clamping once should be fine.
- */
- CLAMP(CFRA, PSFRA, PEFRA);
- }
- else {
- /* Prevent negative frames */
- FRAMENUMBER_MIN_CLAMP(CFRA);
- }
-
- SUBFRA = 0.0f;
- BKE_sound_seek_scene(bmain, scene);
- }
-
- /* set the cursor value */
- sipo->cursorVal = RNA_float_get(op->ptr, "value");
-
- /* send notifiers - notifiers for frame should force an update for both vars ok... */
- WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ SpaceGraph *sipo = CTX_wm_space_graph(C);
+ /* this isn't technically "frame", but it'll do... */
+ float frame = RNA_float_get(op->ptr, "frame");
+
+ /* adjust the frame or the cursor x-value */
+ if (sipo->mode == SIPO_MODE_DRIVERS) {
+ /* adjust cursor x-value */
+ sipo->cursorTime = frame;
+ }
+ else {
+ /* adjust the frame
+ * NOTE: sync this part of the code with ANIM_OT_change_frame
+ */
+ /* 1) frame is rounded to the nearest int, since frames are ints */
+ CFRA = round_fl_to_int(frame);
+
+ if (scene->r.flag & SCER_LOCK_FRAME_SELECTION) {
+ /* Clip to preview range
+ * NOTE: Preview range won't go into negative values,
+ * so only clamping once should be fine.
+ */
+ CLAMP(CFRA, PSFRA, PEFRA);
+ }
+ else {
+ /* Prevent negative frames */
+ FRAMENUMBER_MIN_CLAMP(CFRA);
+ }
+
+ SUBFRA = 0.0f;
+ BKE_sound_seek_scene(bmain, scene);
+ }
+
+ /* set the cursor value */
+ sipo->cursorVal = RNA_float_get(op->ptr, "value");
+
+ /* send notifiers - notifiers for frame should force an update for both vars ok... */
+ WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
}
/* ... */
@@ -120,8 +119,8 @@ static void graphview_cursor_apply(bContext *C, wmOperator *op)
/* Non-modal callback for running operator without user input */
static int graphview_cursor_exec(bContext *C, wmOperator *op)
{
- graphview_cursor_apply(C, op);
- return OPERATOR_FINISHED;
+ graphview_cursor_apply(C, op);
+ return OPERATOR_FINISHED;
}
/* ... */
@@ -129,374 +128,377 @@ static int graphview_cursor_exec(bContext *C, wmOperator *op)
/* set the operator properties from the initial event */
static void graphview_cursor_setprops(bContext *C, wmOperator *op, const wmEvent *event)
{
- ARegion *ar = CTX_wm_region(C);
- float viewx, viewy;
+ ARegion *ar = CTX_wm_region(C);
+ float viewx, viewy;
- /* abort if not active region (should not really be possible) */
- if (ar == NULL)
- return;
+ /* abort if not active region (should not really be possible) */
+ if (ar == NULL)
+ return;
- /* convert from region coordinates to View2D 'tot' space */
- UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &viewx, &viewy);
+ /* convert from region coordinates to View2D 'tot' space */
+ UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &viewx, &viewy);
- /* store the values in the operator properties */
- /* NOTE: we don't clamp frame here, as it might be used for the drivers cursor */
- RNA_float_set(op->ptr, "frame", viewx);
- RNA_float_set(op->ptr, "value", viewy);
+ /* store the values in the operator properties */
+ /* NOTE: we don't clamp frame here, as it might be used for the drivers cursor */
+ RNA_float_set(op->ptr, "frame", viewx);
+ RNA_float_set(op->ptr, "value", viewy);
}
/* Modal Operator init */
static int graphview_cursor_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- bScreen *screen = CTX_wm_screen(C);
-
- /* Change to frame that mouse is over before adding modal handler,
- * as user could click on a single frame (jump to frame) as well as
- * click-dragging over a range (modal scrubbing). Apply this change.
- */
- graphview_cursor_setprops(C, op, event);
- graphview_cursor_apply(C, op);
-
- /* Signal that a scrubbing operating is starting */
- if (screen)
- screen->scrubbing = true;
-
- /* add temp handler */
- WM_event_add_modal_handler(C, op);
- return OPERATOR_RUNNING_MODAL;
+ bScreen *screen = CTX_wm_screen(C);
+
+ /* Change to frame that mouse is over before adding modal handler,
+ * as user could click on a single frame (jump to frame) as well as
+ * click-dragging over a range (modal scrubbing). Apply this change.
+ */
+ graphview_cursor_setprops(C, op, event);
+ graphview_cursor_apply(C, op);
+
+ /* Signal that a scrubbing operating is starting */
+ if (screen)
+ screen->scrubbing = true;
+
+ /* add temp handler */
+ WM_event_add_modal_handler(C, op);
+ return OPERATOR_RUNNING_MODAL;
}
/* Modal event handling of cursor changing */
static int graphview_cursor_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
- bScreen *screen = CTX_wm_screen(C);
- Scene *scene = CTX_data_scene(C);
-
- /* execute the events */
- switch (event->type) {
- case ESCKEY:
- if (screen)
- screen->scrubbing = false;
-
- WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
- return OPERATOR_FINISHED;
-
- case MOUSEMOVE:
- /* set the new values */
- graphview_cursor_setprops(C, op, event);
- graphview_cursor_apply(C, op);
- break;
-
- case LEFTMOUSE:
- case RIGHTMOUSE:
- case MIDDLEMOUSE:
- /* We check for either mouse-button to end, to work with all user keymaps. */
- if (event->val == KM_RELEASE) {
- if (screen)
- screen->scrubbing = false;
-
- WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
- return OPERATOR_FINISHED;
- }
- break;
- }
-
- return OPERATOR_RUNNING_MODAL;
+ bScreen *screen = CTX_wm_screen(C);
+ Scene *scene = CTX_data_scene(C);
+
+ /* execute the events */
+ switch (event->type) {
+ case ESCKEY:
+ if (screen)
+ screen->scrubbing = false;
+
+ WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
+ return OPERATOR_FINISHED;
+
+ case MOUSEMOVE:
+ /* set the new values */
+ graphview_cursor_setprops(C, op, event);
+ graphview_cursor_apply(C, op);
+ break;
+
+ case LEFTMOUSE:
+ case RIGHTMOUSE:
+ case MIDDLEMOUSE:
+ /* We check for either mouse-button to end, to work with all user keymaps. */
+ if (event->val == KM_RELEASE) {
+ if (screen)
+ screen->scrubbing = false;
+
+ WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
+ return OPERATOR_FINISHED;
+ }
+ break;
+ }
+
+ return OPERATOR_RUNNING_MODAL;
}
static void GRAPH_OT_cursor_set(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Set Cursor";
- ot->idname = "GRAPH_OT_cursor_set";
- ot->description = "Interactively set the current frame and value cursor";
-
- /* api callbacks */
- ot->exec = graphview_cursor_exec;
- ot->invoke = graphview_cursor_invoke;
- ot->modal = graphview_cursor_modal;
- ot->poll = graphview_cursor_poll;
-
- /* flags */
- ot->flag = OPTYPE_BLOCKING | OPTYPE_UNDO;
-
- /* rna */
- RNA_def_float(ot->srna, "frame", 0, MINAFRAMEF, MAXFRAMEF, "Frame", "", MINAFRAMEF, MAXFRAMEF);
- RNA_def_float(ot->srna, "value", 0, -FLT_MAX, FLT_MAX, "Value", "", -100.0f, 100.0f);
+ /* identifiers */
+ ot->name = "Set Cursor";
+ ot->idname = "GRAPH_OT_cursor_set";
+ ot->description = "Interactively set the current frame and value cursor";
+
+ /* api callbacks */
+ ot->exec = graphview_cursor_exec;
+ ot->invoke = graphview_cursor_invoke;
+ ot->modal = graphview_cursor_modal;
+ ot->poll = graphview_cursor_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_BLOCKING | OPTYPE_UNDO;
+
+ /* rna */
+ RNA_def_float(ot->srna, "frame", 0, MINAFRAMEF, MAXFRAMEF, "Frame", "", MINAFRAMEF, MAXFRAMEF);
+ RNA_def_float(ot->srna, "value", 0, -FLT_MAX, FLT_MAX, "Value", "", -100.0f, 100.0f);
}
/* Hide/Reveal ------------------------------------------------------------ */
static int graphview_curves_hide_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- ListBase anim_data = {NULL, NULL};
- ListBase all_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
- const bool unselected = RNA_boolean_get(op->ptr, "unselected");
-
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
-
- /* get list of all channels that selection may need to be flushed to
- * - hierarchy must not affect what we have access to here...
- */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(&ac, &all_data, filter, ac.data, ac.datatype);
-
- /* filter data
- * - of the remaining visible curves, we want to hide the ones that are
- * selected/unselected (depending on "unselected" prop)
- */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
- if (unselected)
- filter |= ANIMFILTER_UNSEL;
- else
- filter |= ANIMFILTER_SEL;
-
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
- for (ale = anim_data.first; ale; ale = ale->next) {
- /* hack: skip object channels for now, since flushing those will always flush everything,
- * but they are always included */
- /* TODO: find out why this is the case, and fix that */
- if (ale->type == ANIMTYPE_OBJECT)
- continue;
-
- /* change the hide setting, and unselect it... */
- ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_VISIBLE, ACHANNEL_SETFLAG_CLEAR);
- ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_SELECT, ACHANNEL_SETFLAG_CLEAR);
-
- /* now, also flush selection status up/down as appropriate */
- ANIM_flush_setting_anim_channels(&ac, &all_data, ale, ACHANNEL_SETTING_VISIBLE, ACHANNEL_SETFLAG_CLEAR);
- }
-
- /* cleanup */
- ANIM_animdata_freelist(&anim_data);
- BLI_freelistN(&all_data);
-
- /* unhide selected */
- if (unselected) {
- /* turn off requirement for visible */
- filter = ANIMFILTER_SEL | ANIMFILTER_NODUPLIS | ANIMFILTER_LIST_CHANNELS;
-
- /* flushing has been done */
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
- for (ale = anim_data.first; ale; ale = ale->next) {
- /* hack: skip object channels for now, since flushing those
- * will always flush everything, but they are always included */
-
- /* TODO: find out why this is the case, and fix that */
- if (ale->type == ANIMTYPE_OBJECT)
- continue;
-
- /* change the hide setting, and unselect it... */
- ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_VISIBLE, ACHANNEL_SETFLAG_ADD);
- ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_SELECT, ACHANNEL_SETFLAG_ADD);
-
- /* now, also flush selection status up/down as appropriate */
- ANIM_flush_setting_anim_channels(&ac, &anim_data, ale, ACHANNEL_SETTING_VISIBLE, ACHANNEL_SETFLAG_ADD);
- }
- ANIM_animdata_freelist(&anim_data);
- }
-
-
- /* send notifier that things have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
- return OPERATOR_FINISHED;
+ bAnimContext ac;
+ ListBase anim_data = {NULL, NULL};
+ ListBase all_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+ const bool unselected = RNA_boolean_get(op->ptr, "unselected");
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* get list of all channels that selection may need to be flushed to
+ * - hierarchy must not affect what we have access to here...
+ */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(&ac, &all_data, filter, ac.data, ac.datatype);
+
+ /* filter data
+ * - of the remaining visible curves, we want to hide the ones that are
+ * selected/unselected (depending on "unselected" prop)
+ */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
+ if (unselected)
+ filter |= ANIMFILTER_UNSEL;
+ else
+ filter |= ANIMFILTER_SEL;
+
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ /* hack: skip object channels for now, since flushing those will always flush everything,
+ * but they are always included */
+ /* TODO: find out why this is the case, and fix that */
+ if (ale->type == ANIMTYPE_OBJECT)
+ continue;
+
+ /* change the hide setting, and unselect it... */
+ ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_VISIBLE, ACHANNEL_SETFLAG_CLEAR);
+ ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_SELECT, ACHANNEL_SETFLAG_CLEAR);
+
+ /* now, also flush selection status up/down as appropriate */
+ ANIM_flush_setting_anim_channels(
+ &ac, &all_data, ale, ACHANNEL_SETTING_VISIBLE, ACHANNEL_SETFLAG_CLEAR);
+ }
+
+ /* cleanup */
+ ANIM_animdata_freelist(&anim_data);
+ BLI_freelistN(&all_data);
+
+ /* unhide selected */
+ if (unselected) {
+ /* turn off requirement for visible */
+ filter = ANIMFILTER_SEL | ANIMFILTER_NODUPLIS | ANIMFILTER_LIST_CHANNELS;
+
+ /* flushing has been done */
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ /* hack: skip object channels for now, since flushing those
+ * will always flush everything, but they are always included */
+
+ /* TODO: find out why this is the case, and fix that */
+ if (ale->type == ANIMTYPE_OBJECT)
+ continue;
+
+ /* change the hide setting, and unselect it... */
+ ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_VISIBLE, ACHANNEL_SETFLAG_ADD);
+ ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_SELECT, ACHANNEL_SETFLAG_ADD);
+
+ /* now, also flush selection status up/down as appropriate */
+ ANIM_flush_setting_anim_channels(
+ &ac, &anim_data, ale, ACHANNEL_SETTING_VISIBLE, ACHANNEL_SETFLAG_ADD);
+ }
+ ANIM_animdata_freelist(&anim_data);
+ }
+
+ /* send notifier that things have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+
+ return OPERATOR_FINISHED;
}
static void GRAPH_OT_hide(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Hide Curves";
- ot->idname = "GRAPH_OT_hide";
- ot->description = "Hide selected curves from Graph Editor view";
+ /* identifiers */
+ ot->name = "Hide Curves";
+ ot->idname = "GRAPH_OT_hide";
+ ot->description = "Hide selected curves from Graph Editor view";
- /* api callbacks */
- ot->exec = graphview_curves_hide_exec;
- ot->poll = ED_operator_graphedit_active;
+ /* api callbacks */
+ ot->exec = graphview_curves_hide_exec;
+ ot->poll = ED_operator_graphedit_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* props */
- RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected curves");
+ /* props */
+ RNA_def_boolean(
+ ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected curves");
}
/* ........ */
static int graphview_curves_reveal_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- ListBase anim_data = {NULL, NULL};
- ListBase all_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
- const bool select = RNA_boolean_get(op->ptr, "select");
-
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
-
- /* get list of all channels that selection may need to be flushed to
- * - hierarchy must not affect what we have access to here...
- */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(&ac, &all_data, filter, ac.data, ac.datatype);
-
- /* filter data
- * - just go through all visible channels, ensuring that everything is set to be curve-visible
- */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
- for (ale = anim_data.first; ale; ale = ale->next) {
- /* hack: skip object channels for now, since flushing those will always flush everything,
- * but they are always included. */
- /* TODO: find out why this is the case, and fix that */
- if (ale->type == ANIMTYPE_OBJECT)
- continue;
-
- /* select if it is not visible */
- if (ANIM_channel_setting_get(&ac, ale, ACHANNEL_SETTING_VISIBLE) == 0) {
- ANIM_channel_setting_set(
- &ac, ale, ACHANNEL_SETTING_SELECT,
- select ? ACHANNEL_SETFLAG_ADD : ACHANNEL_SETFLAG_CLEAR);
- }
-
- /* change the visibility setting */
- ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_VISIBLE, ACHANNEL_SETFLAG_ADD);
-
- /* now, also flush selection status up/down as appropriate */
- ANIM_flush_setting_anim_channels(&ac, &all_data, ale, ACHANNEL_SETTING_VISIBLE, true);
- }
-
- /* cleanup */
- ANIM_animdata_freelist(&anim_data);
- BLI_freelistN(&all_data);
-
- /* send notifier that things have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
- return OPERATOR_FINISHED;
+ bAnimContext ac;
+ ListBase anim_data = {NULL, NULL};
+ ListBase all_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+ const bool select = RNA_boolean_get(op->ptr, "select");
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* get list of all channels that selection may need to be flushed to
+ * - hierarchy must not affect what we have access to here...
+ */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(&ac, &all_data, filter, ac.data, ac.datatype);
+
+ /* filter data
+ * - just go through all visible channels, ensuring that everything is set to be curve-visible
+ */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ /* hack: skip object channels for now, since flushing those will always flush everything,
+ * but they are always included. */
+ /* TODO: find out why this is the case, and fix that */
+ if (ale->type == ANIMTYPE_OBJECT)
+ continue;
+
+ /* select if it is not visible */
+ if (ANIM_channel_setting_get(&ac, ale, ACHANNEL_SETTING_VISIBLE) == 0) {
+ ANIM_channel_setting_set(&ac,
+ ale,
+ ACHANNEL_SETTING_SELECT,
+ select ? ACHANNEL_SETFLAG_ADD : ACHANNEL_SETFLAG_CLEAR);
+ }
+
+ /* change the visibility setting */
+ ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_VISIBLE, ACHANNEL_SETFLAG_ADD);
+
+ /* now, also flush selection status up/down as appropriate */
+ ANIM_flush_setting_anim_channels(&ac, &all_data, ale, ACHANNEL_SETTING_VISIBLE, true);
+ }
+
+ /* cleanup */
+ ANIM_animdata_freelist(&anim_data);
+ BLI_freelistN(&all_data);
+
+ /* send notifier that things have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+
+ return OPERATOR_FINISHED;
}
static void GRAPH_OT_reveal(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Reveal Curves";
- ot->idname = "GRAPH_OT_reveal";
- ot->description = "Make previously hidden curves visible again in Graph Editor view";
+ /* identifiers */
+ ot->name = "Reveal Curves";
+ ot->idname = "GRAPH_OT_reveal";
+ ot->description = "Make previously hidden curves visible again in Graph Editor view";
- /* api callbacks */
- ot->exec = graphview_curves_reveal_exec;
- ot->poll = ED_operator_graphedit_active;
+ /* api callbacks */
+ ot->exec = graphview_curves_reveal_exec;
+ ot->poll = ED_operator_graphedit_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- RNA_def_boolean(ot->srna, "select", true, "Select", "");
+ RNA_def_boolean(ot->srna, "select", true, "Select", "");
}
/* ************************** registration - operator types **********************************/
void graphedit_operatortypes(void)
{
- /* view */
- WM_operatortype_append(GRAPH_OT_cursor_set);
-
- WM_operatortype_append(GRAPH_OT_previewrange_set);
- WM_operatortype_append(GRAPH_OT_view_all);
- WM_operatortype_append(GRAPH_OT_view_selected);
- WM_operatortype_append(GRAPH_OT_properties);
- WM_operatortype_append(GRAPH_OT_view_frame);
-
- WM_operatortype_append(GRAPH_OT_ghost_curves_create);
- WM_operatortype_append(GRAPH_OT_ghost_curves_clear);
-
- WM_operatortype_append(GRAPH_OT_hide);
- WM_operatortype_append(GRAPH_OT_reveal);
-
- /* keyframes */
- /* selection */
- WM_operatortype_append(GRAPH_OT_clickselect);
- WM_operatortype_append(GRAPH_OT_select_all);
- WM_operatortype_append(GRAPH_OT_select_box);
- WM_operatortype_append(GRAPH_OT_select_lasso);
- WM_operatortype_append(GRAPH_OT_select_circle);
- WM_operatortype_append(GRAPH_OT_select_column);
- WM_operatortype_append(GRAPH_OT_select_linked);
- WM_operatortype_append(GRAPH_OT_select_more);
- WM_operatortype_append(GRAPH_OT_select_less);
- WM_operatortype_append(GRAPH_OT_select_leftright);
-
- /* editing */
- WM_operatortype_append(GRAPH_OT_snap);
- WM_operatortype_append(GRAPH_OT_mirror);
- WM_operatortype_append(GRAPH_OT_frame_jump);
- WM_operatortype_append(GRAPH_OT_handle_type);
- WM_operatortype_append(GRAPH_OT_interpolation_type);
- WM_operatortype_append(GRAPH_OT_extrapolation_type);
- WM_operatortype_append(GRAPH_OT_easing_type);
- WM_operatortype_append(GRAPH_OT_sample);
- WM_operatortype_append(GRAPH_OT_bake);
- WM_operatortype_append(GRAPH_OT_sound_bake);
- WM_operatortype_append(GRAPH_OT_smooth);
- WM_operatortype_append(GRAPH_OT_clean);
- WM_operatortype_append(GRAPH_OT_euler_filter);
- WM_operatortype_append(GRAPH_OT_delete);
- WM_operatortype_append(GRAPH_OT_duplicate);
-
- WM_operatortype_append(GRAPH_OT_copy);
- WM_operatortype_append(GRAPH_OT_paste);
-
- WM_operatortype_append(GRAPH_OT_keyframe_insert);
- WM_operatortype_append(GRAPH_OT_click_insert);
-
- /* F-Curve Modifiers */
- WM_operatortype_append(GRAPH_OT_fmodifier_add);
- WM_operatortype_append(GRAPH_OT_fmodifier_copy);
- WM_operatortype_append(GRAPH_OT_fmodifier_paste);
-
- /* Drivers */
- WM_operatortype_append(GRAPH_OT_driver_variables_copy);
- WM_operatortype_append(GRAPH_OT_driver_variables_paste);
- WM_operatortype_append(GRAPH_OT_driver_delete_invalid);
+ /* view */
+ WM_operatortype_append(GRAPH_OT_cursor_set);
+
+ WM_operatortype_append(GRAPH_OT_previewrange_set);
+ WM_operatortype_append(GRAPH_OT_view_all);
+ WM_operatortype_append(GRAPH_OT_view_selected);
+ WM_operatortype_append(GRAPH_OT_properties);
+ WM_operatortype_append(GRAPH_OT_view_frame);
+
+ WM_operatortype_append(GRAPH_OT_ghost_curves_create);
+ WM_operatortype_append(GRAPH_OT_ghost_curves_clear);
+
+ WM_operatortype_append(GRAPH_OT_hide);
+ WM_operatortype_append(GRAPH_OT_reveal);
+
+ /* keyframes */
+ /* selection */
+ WM_operatortype_append(GRAPH_OT_clickselect);
+ WM_operatortype_append(GRAPH_OT_select_all);
+ WM_operatortype_append(GRAPH_OT_select_box);
+ WM_operatortype_append(GRAPH_OT_select_lasso);
+ WM_operatortype_append(GRAPH_OT_select_circle);
+ WM_operatortype_append(GRAPH_OT_select_column);
+ WM_operatortype_append(GRAPH_OT_select_linked);
+ WM_operatortype_append(GRAPH_OT_select_more);
+ WM_operatortype_append(GRAPH_OT_select_less);
+ WM_operatortype_append(GRAPH_OT_select_leftright);
+
+ /* editing */
+ WM_operatortype_append(GRAPH_OT_snap);
+ WM_operatortype_append(GRAPH_OT_mirror);
+ WM_operatortype_append(GRAPH_OT_frame_jump);
+ WM_operatortype_append(GRAPH_OT_handle_type);
+ WM_operatortype_append(GRAPH_OT_interpolation_type);
+ WM_operatortype_append(GRAPH_OT_extrapolation_type);
+ WM_operatortype_append(GRAPH_OT_easing_type);
+ WM_operatortype_append(GRAPH_OT_sample);
+ WM_operatortype_append(GRAPH_OT_bake);
+ WM_operatortype_append(GRAPH_OT_sound_bake);
+ WM_operatortype_append(GRAPH_OT_smooth);
+ WM_operatortype_append(GRAPH_OT_clean);
+ WM_operatortype_append(GRAPH_OT_euler_filter);
+ WM_operatortype_append(GRAPH_OT_delete);
+ WM_operatortype_append(GRAPH_OT_duplicate);
+
+ WM_operatortype_append(GRAPH_OT_copy);
+ WM_operatortype_append(GRAPH_OT_paste);
+
+ WM_operatortype_append(GRAPH_OT_keyframe_insert);
+ WM_operatortype_append(GRAPH_OT_click_insert);
+
+ /* F-Curve Modifiers */
+ WM_operatortype_append(GRAPH_OT_fmodifier_add);
+ WM_operatortype_append(GRAPH_OT_fmodifier_copy);
+ WM_operatortype_append(GRAPH_OT_fmodifier_paste);
+
+ /* Drivers */
+ WM_operatortype_append(GRAPH_OT_driver_variables_copy);
+ WM_operatortype_append(GRAPH_OT_driver_variables_paste);
+ WM_operatortype_append(GRAPH_OT_driver_delete_invalid);
}
void ED_operatormacros_graph(void)
{
- wmOperatorType *ot;
- wmOperatorTypeMacro *otmacro;
-
- ot = WM_operatortype_append_macro("GRAPH_OT_duplicate_move", "Duplicate",
- "Make a copy of all selected keyframes and move them",
- OPTYPE_UNDO | OPTYPE_REGISTER);
- WM_operatortype_macro_define(ot, "GRAPH_OT_duplicate");
- otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_transform");
- RNA_enum_set(otmacro->ptr, "mode", TFM_TIME_DUPLICATE);
- RNA_enum_set(otmacro->ptr, "proportional", PROP_EDIT_OFF);
+ wmOperatorType *ot;
+ wmOperatorTypeMacro *otmacro;
+
+ ot = WM_operatortype_append_macro("GRAPH_OT_duplicate_move",
+ "Duplicate",
+ "Make a copy of all selected keyframes and move them",
+ OPTYPE_UNDO | OPTYPE_REGISTER);
+ WM_operatortype_macro_define(ot, "GRAPH_OT_duplicate");
+ otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_transform");
+ RNA_enum_set(otmacro->ptr, "mode", TFM_TIME_DUPLICATE);
+ RNA_enum_set(otmacro->ptr, "proportional", PROP_EDIT_OFF);
}
-
/* ************************** registration - keymaps **********************************/
void graphedit_keymap(wmKeyConfig *keyconf)
{
- /* keymap for all regions */
- WM_keymap_ensure(keyconf, "Graph Editor Generic", SPACE_GRAPH, 0);
+ /* keymap for all regions */
+ WM_keymap_ensure(keyconf, "Graph Editor Generic", SPACE_GRAPH, 0);
- /* channels */
- /* Channels are not directly handled by the Graph Editor module, but are inherited from the Animation module.
- * All the relevant operations, keymaps, drawing, etc. can therefore all be found in that module instead, as these
- * are all used for the Graph Editor too.
- */
+ /* channels */
+ /* Channels are not directly handled by the Graph Editor module, but are inherited from the Animation module.
+ * All the relevant operations, keymaps, drawing, etc. can therefore all be found in that module instead, as these
+ * are all used for the Graph Editor too.
+ */
- /* keyframes */
- WM_keymap_ensure(keyconf, "Graph Editor", SPACE_GRAPH, 0);
+ /* keyframes */
+ WM_keymap_ensure(keyconf, "Graph Editor", SPACE_GRAPH, 0);
}
diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c
index 6c6c0d451cc..a109282978c 100644
--- a/source/blender/editors/space_graph/graph_select.c
+++ b/source/blender/editors/space_graph/graph_select.c
@@ -20,7 +20,6 @@
* \ingroup spgraph
*/
-
#include <math.h>
#include <stdlib.h>
#include <string.h>
@@ -57,7 +56,6 @@
#include "graph_intern.h"
-
/* ************************************************************************** */
/* KEYFRAMES STUFF */
@@ -80,137 +78,137 @@
*/
void deselect_graph_keys(bAnimContext *ac, bool test, short sel, bool do_channels)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- SpaceGraph *sipo = (SpaceGraph *)ac->sl;
- KeyframeEditData ked = {{NULL}};
- KeyframeEditFunc test_cb, sel_cb;
-
- /* determine type-based settings */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
-
- /* filter data */
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* init BezTriple looping data */
- test_cb = ANIM_editkeyframes_ok(BEZT_OK_SELECTED);
-
- /* See if we should be selecting or deselecting */
- if (test) {
- for (ale = anim_data.first; ale; ale = ale->next) {
- if (ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, test_cb, NULL)) {
- sel = SELECT_SUBTRACT;
- break;
- }
- }
- }
-
- /* convert sel to selectmode, and use that to get editor */
- sel_cb = ANIM_editkeyframes_select(sel);
-
- /* Now set the flags */
- for (ale = anim_data.first; ale; ale = ale->next) {
- FCurve *fcu = (FCurve *)ale->key_data;
-
- /* Keyframes First */
- ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, sel_cb, NULL);
-
- /* affect channel selection status? */
- if (do_channels) {
- /* only change selection of channel when the visibility of keyframes doesn't depend on this */
- if ((sipo->flag & SIPO_SELCUVERTSONLY) == 0) {
- /* deactivate the F-Curve, and deselect if deselecting keyframes.
- * otherwise select the F-Curve too since we've selected all the keyframes
- */
- if (sel == SELECT_SUBTRACT)
- fcu->flag &= ~FCURVE_SELECTED;
- else
- fcu->flag |= FCURVE_SELECTED;
- }
-
- /* always deactivate all F-Curves if we perform batch ops for selection */
- fcu->flag &= ~FCURVE_ACTIVE;
- }
- }
-
- /* Cleanup */
- ANIM_animdata_freelist(&anim_data);
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ SpaceGraph *sipo = (SpaceGraph *)ac->sl;
+ KeyframeEditData ked = {{NULL}};
+ KeyframeEditFunc test_cb, sel_cb;
+
+ /* determine type-based settings */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
+
+ /* filter data */
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* init BezTriple looping data */
+ test_cb = ANIM_editkeyframes_ok(BEZT_OK_SELECTED);
+
+ /* See if we should be selecting or deselecting */
+ if (test) {
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ if (ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, test_cb, NULL)) {
+ sel = SELECT_SUBTRACT;
+ break;
+ }
+ }
+ }
+
+ /* convert sel to selectmode, and use that to get editor */
+ sel_cb = ANIM_editkeyframes_select(sel);
+
+ /* Now set the flags */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ FCurve *fcu = (FCurve *)ale->key_data;
+
+ /* Keyframes First */
+ ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, sel_cb, NULL);
+
+ /* affect channel selection status? */
+ if (do_channels) {
+ /* only change selection of channel when the visibility of keyframes doesn't depend on this */
+ if ((sipo->flag & SIPO_SELCUVERTSONLY) == 0) {
+ /* deactivate the F-Curve, and deselect if deselecting keyframes.
+ * otherwise select the F-Curve too since we've selected all the keyframes
+ */
+ if (sel == SELECT_SUBTRACT)
+ fcu->flag &= ~FCURVE_SELECTED;
+ else
+ fcu->flag |= FCURVE_SELECTED;
+ }
+
+ /* always deactivate all F-Curves if we perform batch ops for selection */
+ fcu->flag &= ~FCURVE_ACTIVE;
+ }
+ }
+
+ /* Cleanup */
+ ANIM_animdata_freelist(&anim_data);
}
/* ------------------- */
static int graphkeys_deselectall_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- bAnimListElem *ale_active = NULL;
-
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
-
- /* find active F-Curve, and preserve this for later
- * or else it becomes annoying with the current active
- * curve keeps fading out even while you're editing it
- */
- ale_active = get_active_fcurve_channel(&ac);
-
- /* 'standard' behavior - check if selected, then apply relevant selection */
- const int action = RNA_enum_get(op->ptr, "action");
- switch (action) {
- case SEL_TOGGLE:
- deselect_graph_keys(&ac, 1, SELECT_ADD, true);
- break;
- case SEL_SELECT:
- deselect_graph_keys(&ac, 0, SELECT_ADD, true);
- break;
- case SEL_DESELECT:
- deselect_graph_keys(&ac, 0, SELECT_SUBTRACT, true);
- break;
- case SEL_INVERT:
- deselect_graph_keys(&ac, 0, SELECT_INVERT, true);
- break;
- default:
- BLI_assert(0);
- break;
- }
-
- /* restore active F-Curve... */
- if (ale_active) {
- FCurve *fcu = (FCurve *)ale_active->data;
-
- /* all others should not be disabled, so we should be able to just set this directly...
- * - selection needs to be set too, or else this won't work...
- */
- fcu->flag |= (FCURVE_SELECTED | FCURVE_ACTIVE);
-
- MEM_freeN(ale_active);
- ale_active = NULL;
- }
-
- /* set notifier that things have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
-
- return OPERATOR_FINISHED;
+ bAnimContext ac;
+ bAnimListElem *ale_active = NULL;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* find active F-Curve, and preserve this for later
+ * or else it becomes annoying with the current active
+ * curve keeps fading out even while you're editing it
+ */
+ ale_active = get_active_fcurve_channel(&ac);
+
+ /* 'standard' behavior - check if selected, then apply relevant selection */
+ const int action = RNA_enum_get(op->ptr, "action");
+ switch (action) {
+ case SEL_TOGGLE:
+ deselect_graph_keys(&ac, 1, SELECT_ADD, true);
+ break;
+ case SEL_SELECT:
+ deselect_graph_keys(&ac, 0, SELECT_ADD, true);
+ break;
+ case SEL_DESELECT:
+ deselect_graph_keys(&ac, 0, SELECT_SUBTRACT, true);
+ break;
+ case SEL_INVERT:
+ deselect_graph_keys(&ac, 0, SELECT_INVERT, true);
+ break;
+ default:
+ BLI_assert(0);
+ break;
+ }
+
+ /* restore active F-Curve... */
+ if (ale_active) {
+ FCurve *fcu = (FCurve *)ale_active->data;
+
+ /* all others should not be disabled, so we should be able to just set this directly...
+ * - selection needs to be set too, or else this won't work...
+ */
+ fcu->flag |= (FCURVE_SELECTED | FCURVE_ACTIVE);
+
+ MEM_freeN(ale_active);
+ ale_active = NULL;
+ }
+
+ /* set notifier that things have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
+
+ return OPERATOR_FINISHED;
}
void GRAPH_OT_select_all(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Select All";
- ot->idname = "GRAPH_OT_select_all";
- ot->description = "Toggle selection of all keyframes";
+ /* identifiers */
+ ot->name = "Select All";
+ ot->idname = "GRAPH_OT_select_all";
+ ot->description = "Toggle selection of all keyframes";
- /* api callbacks */
- ot->exec = graphkeys_deselectall_exec;
- ot->poll = graphop_visible_keyframes_poll;
+ /* api callbacks */
+ ot->exec = graphkeys_deselectall_exec;
+ ot->poll = graphop_visible_keyframes_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* properties */
- WM_operator_properties_select_all(ot);
+ /* properties */
+ WM_operator_properties_select_all(ot);
}
/* ******************** Box Select Operator **************************** */
@@ -228,336 +226,341 @@ void GRAPH_OT_select_all(wmOperatorType *ot)
* this, and allow handles to be considered independently too.
* Also, for convenience, handles should get same status as keyframe (if it was within bounds).
*/
-static void box_select_graphkeys(
- bAnimContext *ac, const rctf *rectf_view, short mode, short selectmode, bool incl_handles,
- void *data)
+static void box_select_graphkeys(bAnimContext *ac,
+ const rctf *rectf_view,
+ short mode,
+ short selectmode,
+ bool incl_handles,
+ void *data)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter, mapping_flag;
-
- SpaceGraph *sipo = (SpaceGraph *)ac->sl;
- KeyframeEditData ked;
- KeyframeEditFunc ok_cb, select_cb;
- View2D *v2d = &ac->ar->v2d;
- rctf rectf, scaled_rectf;
-
- /* convert mouse coordinates to frame ranges and channel coordinates corrected for view pan/zoom */
- UI_view2d_region_to_view_rctf(v2d, rectf_view, &rectf);
-
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* get beztriple editing/validation funcs */
- select_cb = ANIM_editkeyframes_select(selectmode);
- ok_cb = ANIM_editkeyframes_ok(mode);
-
- /* init editing data */
- memset(&ked, 0, sizeof(KeyframeEditData));
- if (mode == BEZT_OK_REGION_LASSO) {
- KeyframeEdit_LassoData *data_lasso = data;
- data_lasso->rectf_scaled = &scaled_rectf;
- ked.data = data_lasso;
- }
- else if (mode == BEZT_OK_REGION_CIRCLE) {
- KeyframeEdit_CircleData *data_circle = data;
- data_circle->rectf_scaled = &scaled_rectf;
- ked.data = data;
- }
- else {
- ked.data = &scaled_rectf;
- }
-
- /* treat handles separately? */
- if (incl_handles) {
- ked.iterflags |= KEYFRAME_ITER_INCL_HANDLES;
- mapping_flag = 0;
- }
- else
- mapping_flag = ANIM_UNITCONV_ONLYKEYS;
-
- mapping_flag |= ANIM_get_normalization_flags(ac);
-
- /* loop over data, doing box select */
- for (ale = anim_data.first; ale; ale = ale->next) {
- AnimData *adt = ANIM_nla_mapping_get(ac, ale);
- FCurve *fcu = (FCurve *)ale->key_data;
- float offset;
- float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag, &offset);
-
- /* apply NLA mapping to all the keyframes, since it's easier than trying to
- * guess when a callback might use something different
- */
- if (adt)
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, incl_handles == 0);
-
- scaled_rectf.xmin = rectf.xmin;
- scaled_rectf.xmax = rectf.xmax;
- scaled_rectf.ymin = rectf.ymin / unit_scale - offset;
- scaled_rectf.ymax = rectf.ymax / unit_scale - offset;
-
- /* set horizontal range (if applicable)
- * NOTE: these values are only used for x-range and y-range but not region
- * (which uses ked.data, i.e. rectf)
- */
- if (mode != BEZT_OK_VALUERANGE) {
- ked.f1 = rectf.xmin;
- ked.f2 = rectf.xmax;
- }
- else {
- ked.f1 = rectf.ymin;
- ked.f2 = rectf.ymax;
- }
-
- /* firstly, check if any keyframes will be hit by this */
- if (ANIM_fcurve_keyframes_loop(&ked, fcu, NULL, ok_cb, NULL)) {
- /* select keyframes that are in the appropriate places */
- ANIM_fcurve_keyframes_loop(&ked, fcu, ok_cb, select_cb, NULL);
-
- /* only change selection of channel when the visibility of keyframes doesn't depend on this */
- if ((sipo->flag & SIPO_SELCUVERTSONLY) == 0) {
- /* select the curve too now that curve will be touched */
- if (selectmode == SELECT_ADD)
- fcu->flag |= FCURVE_SELECTED;
- }
- }
-
- /* un-apply NLA mapping from all the keyframes */
- if (adt)
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, incl_handles == 0);
- }
-
- /* cleanup */
- ANIM_animdata_freelist(&anim_data);
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter, mapping_flag;
+
+ SpaceGraph *sipo = (SpaceGraph *)ac->sl;
+ KeyframeEditData ked;
+ KeyframeEditFunc ok_cb, select_cb;
+ View2D *v2d = &ac->ar->v2d;
+ rctf rectf, scaled_rectf;
+
+ /* convert mouse coordinates to frame ranges and channel coordinates corrected for view pan/zoom */
+ UI_view2d_region_to_view_rctf(v2d, rectf_view, &rectf);
+
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* get beztriple editing/validation funcs */
+ select_cb = ANIM_editkeyframes_select(selectmode);
+ ok_cb = ANIM_editkeyframes_ok(mode);
+
+ /* init editing data */
+ memset(&ked, 0, sizeof(KeyframeEditData));
+ if (mode == BEZT_OK_REGION_LASSO) {
+ KeyframeEdit_LassoData *data_lasso = data;
+ data_lasso->rectf_scaled = &scaled_rectf;
+ ked.data = data_lasso;
+ }
+ else if (mode == BEZT_OK_REGION_CIRCLE) {
+ KeyframeEdit_CircleData *data_circle = data;
+ data_circle->rectf_scaled = &scaled_rectf;
+ ked.data = data;
+ }
+ else {
+ ked.data = &scaled_rectf;
+ }
+
+ /* treat handles separately? */
+ if (incl_handles) {
+ ked.iterflags |= KEYFRAME_ITER_INCL_HANDLES;
+ mapping_flag = 0;
+ }
+ else
+ mapping_flag = ANIM_UNITCONV_ONLYKEYS;
+
+ mapping_flag |= ANIM_get_normalization_flags(ac);
+
+ /* loop over data, doing box select */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ AnimData *adt = ANIM_nla_mapping_get(ac, ale);
+ FCurve *fcu = (FCurve *)ale->key_data;
+ float offset;
+ float unit_scale = ANIM_unit_mapping_get_factor(
+ ac->scene, ale->id, fcu, mapping_flag, &offset);
+
+ /* apply NLA mapping to all the keyframes, since it's easier than trying to
+ * guess when a callback might use something different
+ */
+ if (adt)
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, incl_handles == 0);
+
+ scaled_rectf.xmin = rectf.xmin;
+ scaled_rectf.xmax = rectf.xmax;
+ scaled_rectf.ymin = rectf.ymin / unit_scale - offset;
+ scaled_rectf.ymax = rectf.ymax / unit_scale - offset;
+
+ /* set horizontal range (if applicable)
+ * NOTE: these values are only used for x-range and y-range but not region
+ * (which uses ked.data, i.e. rectf)
+ */
+ if (mode != BEZT_OK_VALUERANGE) {
+ ked.f1 = rectf.xmin;
+ ked.f2 = rectf.xmax;
+ }
+ else {
+ ked.f1 = rectf.ymin;
+ ked.f2 = rectf.ymax;
+ }
+
+ /* firstly, check if any keyframes will be hit by this */
+ if (ANIM_fcurve_keyframes_loop(&ked, fcu, NULL, ok_cb, NULL)) {
+ /* select keyframes that are in the appropriate places */
+ ANIM_fcurve_keyframes_loop(&ked, fcu, ok_cb, select_cb, NULL);
+
+ /* only change selection of channel when the visibility of keyframes doesn't depend on this */
+ if ((sipo->flag & SIPO_SELCUVERTSONLY) == 0) {
+ /* select the curve too now that curve will be touched */
+ if (selectmode == SELECT_ADD)
+ fcu->flag |= FCURVE_SELECTED;
+ }
+ }
+
+ /* un-apply NLA mapping from all the keyframes */
+ if (adt)
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, incl_handles == 0);
+ }
+
+ /* cleanup */
+ ANIM_animdata_freelist(&anim_data);
}
/* ------------------- */
static int graphkeys_box_select_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- rcti rect;
- rctf rect_fl;
- short mode = 0;
-
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
-
- const eSelectOp sel_op = RNA_enum_get(op->ptr, "mode");
- const int selectmode = (sel_op != SEL_OP_SUB) ? SELECT_ADD : SELECT_SUBTRACT;
- if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
- deselect_graph_keys(&ac, 1, SELECT_SUBTRACT, true);
- }
-
- /* 'include_handles' from the operator specifies whether to include handles in the selection. */
- const bool incl_handles = RNA_boolean_get(op->ptr, "include_handles");
-
- /* get settings from operator */
- WM_operator_properties_border_to_rcti(op, &rect);
-
- /* selection 'mode' depends on whether box_select region only matters on one axis */
- if (RNA_boolean_get(op->ptr, "axis_range")) {
- /* mode depends on which axis of the range is larger to determine which axis to use
- * - checking this in region-space is fine, as it's fundamentally still going to be a different rect size
- * - the frame-range select option is favored over the channel one (x over y), as frame-range one is often
- * used for tweaking timing when "blocking", while channels is not that useful...
- */
- if ((BLI_rcti_size_x(&rect)) >= (BLI_rcti_size_y(&rect)))
- mode = BEZT_OK_FRAMERANGE;
- else
- mode = BEZT_OK_VALUERANGE;
- }
- else
- mode = BEZT_OK_REGION;
-
- BLI_rctf_rcti_copy(&rect_fl, &rect);
-
- /* apply box_select action */
- box_select_graphkeys(&ac, &rect_fl, mode, selectmode, incl_handles, NULL);
-
- /* send notifier that keyframe selection has changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
-
- return OPERATOR_FINISHED;
+ bAnimContext ac;
+ rcti rect;
+ rctf rect_fl;
+ short mode = 0;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ const eSelectOp sel_op = RNA_enum_get(op->ptr, "mode");
+ const int selectmode = (sel_op != SEL_OP_SUB) ? SELECT_ADD : SELECT_SUBTRACT;
+ if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
+ deselect_graph_keys(&ac, 1, SELECT_SUBTRACT, true);
+ }
+
+ /* 'include_handles' from the operator specifies whether to include handles in the selection. */
+ const bool incl_handles = RNA_boolean_get(op->ptr, "include_handles");
+
+ /* get settings from operator */
+ WM_operator_properties_border_to_rcti(op, &rect);
+
+ /* selection 'mode' depends on whether box_select region only matters on one axis */
+ if (RNA_boolean_get(op->ptr, "axis_range")) {
+ /* mode depends on which axis of the range is larger to determine which axis to use
+ * - checking this in region-space is fine, as it's fundamentally still going to be a different rect size
+ * - the frame-range select option is favored over the channel one (x over y), as frame-range one is often
+ * used for tweaking timing when "blocking", while channels is not that useful...
+ */
+ if ((BLI_rcti_size_x(&rect)) >= (BLI_rcti_size_y(&rect)))
+ mode = BEZT_OK_FRAMERANGE;
+ else
+ mode = BEZT_OK_VALUERANGE;
+ }
+ else
+ mode = BEZT_OK_REGION;
+
+ BLI_rctf_rcti_copy(&rect_fl, &rect);
+
+ /* apply box_select action */
+ box_select_graphkeys(&ac, &rect_fl, mode, selectmode, incl_handles, NULL);
+
+ /* send notifier that keyframe selection has changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
+
+ return OPERATOR_FINISHED;
}
void GRAPH_OT_select_box(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Box Select";
- ot->idname = "GRAPH_OT_select_box";
- ot->description = "Select all keyframes within the specified region";
-
- /* api callbacks */
- ot->invoke = WM_gesture_box_invoke;
- ot->exec = graphkeys_box_select_exec;
- ot->modal = WM_gesture_box_modal;
- ot->cancel = WM_gesture_box_cancel;
-
- ot->poll = graphop_visible_keyframes_poll;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* properties */
- ot->prop = RNA_def_boolean(ot->srna, "axis_range", 0, "Axis Range", "");
- RNA_def_boolean(ot->srna, "include_handles", 0, "Include Handles", "Are handles tested individually against the selection criteria");
-
- WM_operator_properties_gesture_box(ot);
- WM_operator_properties_select_operation_simple(ot);
+ /* identifiers */
+ ot->name = "Box Select";
+ ot->idname = "GRAPH_OT_select_box";
+ ot->description = "Select all keyframes within the specified region";
+
+ /* api callbacks */
+ ot->invoke = WM_gesture_box_invoke;
+ ot->exec = graphkeys_box_select_exec;
+ ot->modal = WM_gesture_box_modal;
+ ot->cancel = WM_gesture_box_cancel;
+
+ ot->poll = graphop_visible_keyframes_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ ot->prop = RNA_def_boolean(ot->srna, "axis_range", 0, "Axis Range", "");
+ RNA_def_boolean(ot->srna,
+ "include_handles",
+ 0,
+ "Include Handles",
+ "Are handles tested individually against the selection criteria");
+
+ WM_operator_properties_gesture_box(ot);
+ WM_operator_properties_select_operation_simple(ot);
}
-
/* ------------------- */
static int graphkeys_lassoselect_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
+ bAnimContext ac;
- KeyframeEdit_LassoData data_lasso = {0};
- rcti rect;
- rctf rect_fl;
+ KeyframeEdit_LassoData data_lasso = {0};
+ rcti rect;
+ rctf rect_fl;
- bool incl_handles;
+ bool incl_handles;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- data_lasso.rectf_view = &rect_fl;
- data_lasso.mcords = WM_gesture_lasso_path_to_array(C, op, &data_lasso.mcords_tot);
- if (data_lasso.mcords == NULL)
- return OPERATOR_CANCELLED;
+ data_lasso.rectf_view = &rect_fl;
+ data_lasso.mcords = WM_gesture_lasso_path_to_array(C, op, &data_lasso.mcords_tot);
+ if (data_lasso.mcords == NULL)
+ return OPERATOR_CANCELLED;
- const eSelectOp sel_op = RNA_enum_get(op->ptr, "mode");
- const short selectmode = (sel_op != SEL_OP_SUB) ? SELECT_ADD : SELECT_SUBTRACT;
- if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
- deselect_graph_keys(&ac, 0, SELECT_SUBTRACT, true);
- }
+ const eSelectOp sel_op = RNA_enum_get(op->ptr, "mode");
+ const short selectmode = (sel_op != SEL_OP_SUB) ? SELECT_ADD : SELECT_SUBTRACT;
+ if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
+ deselect_graph_keys(&ac, 0, SELECT_SUBTRACT, true);
+ }
- {
- SpaceGraph *sipo = (SpaceGraph *)ac.sl;
- if (selectmode == SELECT_ADD) {
- incl_handles = ((sipo->flag & SIPO_SELVHANDLESONLY) ||
- (sipo->flag & SIPO_NOHANDLES)) == 0;
- }
- else {
- incl_handles = (sipo->flag & SIPO_NOHANDLES) == 0;
- }
- }
+ {
+ SpaceGraph *sipo = (SpaceGraph *)ac.sl;
+ if (selectmode == SELECT_ADD) {
+ incl_handles = ((sipo->flag & SIPO_SELVHANDLESONLY) || (sipo->flag & SIPO_NOHANDLES)) == 0;
+ }
+ else {
+ incl_handles = (sipo->flag & SIPO_NOHANDLES) == 0;
+ }
+ }
- /* get settings from operator */
- BLI_lasso_boundbox(&rect, data_lasso.mcords, data_lasso.mcords_tot);
- BLI_rctf_rcti_copy(&rect_fl, &rect);
+ /* get settings from operator */
+ BLI_lasso_boundbox(&rect, data_lasso.mcords, data_lasso.mcords_tot);
+ BLI_rctf_rcti_copy(&rect_fl, &rect);
- /* apply box_select action */
- box_select_graphkeys(&ac, &rect_fl, BEZT_OK_REGION_LASSO, selectmode, incl_handles, &data_lasso);
+ /* apply box_select action */
+ box_select_graphkeys(&ac, &rect_fl, BEZT_OK_REGION_LASSO, selectmode, incl_handles, &data_lasso);
- MEM_freeN((void *)data_lasso.mcords);
+ MEM_freeN((void *)data_lasso.mcords);
- /* send notifier that keyframe selection has changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
+ /* send notifier that keyframe selection has changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void GRAPH_OT_select_lasso(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Lasso Select";
- ot->description = "Select keyframe points using lasso selection";
- ot->idname = "GRAPH_OT_select_lasso";
-
- /* api callbacks */
- ot->invoke = WM_gesture_lasso_invoke;
- ot->modal = WM_gesture_lasso_modal;
- ot->exec = graphkeys_lassoselect_exec;
- ot->poll = graphop_visible_keyframes_poll;
- ot->cancel = WM_gesture_lasso_cancel;
-
- /* flags */
- ot->flag = OPTYPE_UNDO;
-
- /* properties */
- WM_operator_properties_gesture_lasso(ot);
- WM_operator_properties_select_operation_simple(ot);
+ /* identifiers */
+ ot->name = "Lasso Select";
+ ot->description = "Select keyframe points using lasso selection";
+ ot->idname = "GRAPH_OT_select_lasso";
+
+ /* api callbacks */
+ ot->invoke = WM_gesture_lasso_invoke;
+ ot->modal = WM_gesture_lasso_modal;
+ ot->exec = graphkeys_lassoselect_exec;
+ ot->poll = graphop_visible_keyframes_poll;
+ ot->cancel = WM_gesture_lasso_cancel;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
+
+ /* properties */
+ WM_operator_properties_gesture_lasso(ot);
+ WM_operator_properties_select_operation_simple(ot);
}
/* ------------------- */
static int graph_circle_select_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- bool incl_handles = false;
-
- KeyframeEdit_CircleData data = {0};
- rctf rect_fl;
-
- float x = RNA_int_get(op->ptr, "x");
- float y = RNA_int_get(op->ptr, "y");
- float radius = RNA_int_get(op->ptr, "radius");
-
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
-
- const eSelectOp sel_op = ED_select_op_modal(
- RNA_enum_get(op->ptr, "mode"), WM_gesture_is_modal_first(op->customdata));
- const short selectmode = (sel_op != SEL_OP_SUB) ? SELECT_ADD : SELECT_SUBTRACT;
- if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
- deselect_graph_keys(&ac, 0, SELECT_SUBTRACT, true);
- }
-
- data.mval[0] = x;
- data.mval[1] = y;
- data.radius_squared = radius * radius;
- data.rectf_view = &rect_fl;
-
- rect_fl.xmin = x - radius;
- rect_fl.xmax = x + radius;
- rect_fl.ymin = y - radius;
- rect_fl.ymax = y + radius;
-
- {
- SpaceGraph *sipo = (SpaceGraph *)ac.sl;
- if (selectmode == SELECT_ADD) {
- incl_handles = ((sipo->flag & SIPO_SELVHANDLESONLY) ||
- (sipo->flag & SIPO_NOHANDLES)) == 0;
- }
- else {
- incl_handles = (sipo->flag & SIPO_NOHANDLES) == 0;
- }
- }
-
- /* apply box_select action */
- box_select_graphkeys(&ac, &rect_fl, BEZT_OK_REGION_CIRCLE, selectmode, incl_handles, &data);
-
- /* send notifier that keyframe selection has changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
-
- return OPERATOR_FINISHED;
+ bAnimContext ac;
+ bool incl_handles = false;
+
+ KeyframeEdit_CircleData data = {0};
+ rctf rect_fl;
+
+ float x = RNA_int_get(op->ptr, "x");
+ float y = RNA_int_get(op->ptr, "y");
+ float radius = RNA_int_get(op->ptr, "radius");
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ const eSelectOp sel_op = ED_select_op_modal(RNA_enum_get(op->ptr, "mode"),
+ WM_gesture_is_modal_first(op->customdata));
+ const short selectmode = (sel_op != SEL_OP_SUB) ? SELECT_ADD : SELECT_SUBTRACT;
+ if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
+ deselect_graph_keys(&ac, 0, SELECT_SUBTRACT, true);
+ }
+
+ data.mval[0] = x;
+ data.mval[1] = y;
+ data.radius_squared = radius * radius;
+ data.rectf_view = &rect_fl;
+
+ rect_fl.xmin = x - radius;
+ rect_fl.xmax = x + radius;
+ rect_fl.ymin = y - radius;
+ rect_fl.ymax = y + radius;
+
+ {
+ SpaceGraph *sipo = (SpaceGraph *)ac.sl;
+ if (selectmode == SELECT_ADD) {
+ incl_handles = ((sipo->flag & SIPO_SELVHANDLESONLY) || (sipo->flag & SIPO_NOHANDLES)) == 0;
+ }
+ else {
+ incl_handles = (sipo->flag & SIPO_NOHANDLES) == 0;
+ }
+ }
+
+ /* apply box_select action */
+ box_select_graphkeys(&ac, &rect_fl, BEZT_OK_REGION_CIRCLE, selectmode, incl_handles, &data);
+
+ /* send notifier that keyframe selection has changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
+
+ return OPERATOR_FINISHED;
}
void GRAPH_OT_select_circle(wmOperatorType *ot)
{
- ot->name = "Circle Select";
- ot->description = "Select keyframe points using circle selection";
- ot->idname = "GRAPH_OT_select_circle";
-
- ot->invoke = WM_gesture_circle_invoke;
- ot->modal = WM_gesture_circle_modal;
- ot->exec = graph_circle_select_exec;
- ot->poll = graphop_visible_keyframes_poll;
- ot->cancel = WM_gesture_circle_cancel;
-
- /* flags */
- ot->flag = OPTYPE_UNDO;
-
- /* properties */
- WM_operator_properties_gesture_circle(ot);
- WM_operator_properties_select_operation_simple(ot);
+ ot->name = "Circle Select";
+ ot->description = "Select keyframe points using circle selection";
+ ot->idname = "GRAPH_OT_select_circle";
+
+ ot->invoke = WM_gesture_circle_invoke;
+ ot->modal = WM_gesture_circle_modal;
+ ot->exec = graph_circle_select_exec;
+ ot->poll = graphop_visible_keyframes_poll;
+ ot->cancel = WM_gesture_circle_cancel;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
+
+ /* properties */
+ WM_operator_properties_gesture_circle(ot);
+ WM_operator_properties_select_operation_simple(ot);
}
/* ******************** Column Select Operator **************************** */
@@ -570,11 +573,15 @@ void GRAPH_OT_select_circle(wmOperatorType *ot)
/* defines for column-select mode */
static const EnumPropertyItem prop_column_select_types[] = {
- {GRAPHKEYS_COLUMNSEL_KEYS, "KEYS", 0, "On Selected Keyframes", ""},
- {GRAPHKEYS_COLUMNSEL_CFRA, "CFRA", 0, "On Current Frame", ""},
- {GRAPHKEYS_COLUMNSEL_MARKERS_COLUMN, "MARKERS_COLUMN", 0, "On Selected Markers", ""},
- {GRAPHKEYS_COLUMNSEL_MARKERS_BETWEEN, "MARKERS_BETWEEN", 0, "Between Min/Max Selected Markers", ""},
- {0, NULL, 0, NULL, NULL},
+ {GRAPHKEYS_COLUMNSEL_KEYS, "KEYS", 0, "On Selected Keyframes", ""},
+ {GRAPHKEYS_COLUMNSEL_CFRA, "CFRA", 0, "On Current Frame", ""},
+ {GRAPHKEYS_COLUMNSEL_MARKERS_COLUMN, "MARKERS_COLUMN", 0, "On Selected Markers", ""},
+ {GRAPHKEYS_COLUMNSEL_MARKERS_BETWEEN,
+ "MARKERS_BETWEEN",
+ 0,
+ "Between Min/Max Selected Markers",
+ ""},
+ {0, NULL, 0, NULL, NULL},
};
/* ------------------- */
@@ -584,218 +591,217 @@ static const EnumPropertyItem prop_column_select_types[] = {
* should de-duplicate - campbell */
static void markers_selectkeys_between(bAnimContext *ac)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- KeyframeEditFunc ok_cb, select_cb;
- KeyframeEditData ked = {{NULL}};
- float min, max;
-
- /* get extreme markers */
- ED_markers_get_minmax(ac->markers, 1, &min, &max);
- min -= 0.5f;
- max += 0.5f;
-
- /* get editing funcs + data */
- ok_cb = ANIM_editkeyframes_ok(BEZT_OK_FRAMERANGE);
- select_cb = ANIM_editkeyframes_select(SELECT_ADD);
-
- ked.f1 = min;
- ked.f2 = max;
-
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* select keys in-between */
- for (ale = anim_data.first; ale; ale = ale->next) {
- AnimData *adt = ANIM_nla_mapping_get(ac, ale);
-
- if (adt) {
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
- ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1);
- }
- else {
- ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
- }
- }
-
- /* Cleanup */
- ANIM_animdata_freelist(&anim_data);
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ KeyframeEditFunc ok_cb, select_cb;
+ KeyframeEditData ked = {{NULL}};
+ float min, max;
+
+ /* get extreme markers */
+ ED_markers_get_minmax(ac->markers, 1, &min, &max);
+ min -= 0.5f;
+ max += 0.5f;
+
+ /* get editing funcs + data */
+ ok_cb = ANIM_editkeyframes_ok(BEZT_OK_FRAMERANGE);
+ select_cb = ANIM_editkeyframes_select(SELECT_ADD);
+
+ ked.f1 = min;
+ ked.f2 = max;
+
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* select keys in-between */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ AnimData *adt = ANIM_nla_mapping_get(ac, ale);
+
+ if (adt) {
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
+ ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1);
+ }
+ else {
+ ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
+ }
+ }
+
+ /* Cleanup */
+ ANIM_animdata_freelist(&anim_data);
}
-
/* Selects all visible keyframes in the same frames as the specified elements */
static void columnselect_graph_keys(bAnimContext *ac, short mode)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- Scene *scene = ac->scene;
- CfraElem *ce;
- KeyframeEditFunc select_cb, ok_cb;
- KeyframeEditData ked;
-
- /* initialize keyframe editing data */
- memset(&ked, 0, sizeof(KeyframeEditData));
-
- /* build list of columns */
- switch (mode) {
- case GRAPHKEYS_COLUMNSEL_KEYS: /* list of selected keys */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- for (ale = anim_data.first; ale; ale = ale->next)
- ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, bezt_to_cfraelem, NULL);
-
- ANIM_animdata_freelist(&anim_data);
- break;
-
- case GRAPHKEYS_COLUMNSEL_CFRA: /* current frame */
- /* make a single CfraElem for storing this */
- ce = MEM_callocN(sizeof(CfraElem), "cfraElem");
- BLI_addtail(&ked.list, ce);
-
- ce->cfra = (float)CFRA;
- break;
-
- case GRAPHKEYS_COLUMNSEL_MARKERS_COLUMN: /* list of selected markers */
- ED_markers_make_cfra_list(ac->markers, &ked.list, SELECT);
- break;
-
- default: /* invalid option */
- return;
- }
-
- /* set up BezTriple edit callbacks */
- select_cb = ANIM_editkeyframes_select(SELECT_ADD);
- ok_cb = ANIM_editkeyframes_ok(BEZT_OK_FRAME);
-
- /* loop through all of the keys and select additional keyframes
- * based on the keys found to be selected above
- */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- for (ale = anim_data.first; ale; ale = ale->next) {
- AnimData *adt = ANIM_nla_mapping_get(ac, ale);
-
- /* loop over cfraelems (stored in the KeyframeEditData->list)
- * - we need to do this here, as we can apply fewer NLA-mapping conversions
- */
- for (ce = ked.list.first; ce; ce = ce->next) {
- /* set frame for validation callback to refer to */
- ked.f1 = BKE_nla_tweakedit_remap(adt, ce->cfra, NLATIME_CONVERT_UNMAP);
-
- /* select elements with frame number matching cfraelem */
- ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
- }
- }
-
- /* free elements */
- BLI_freelistN(&ked.list);
- ANIM_animdata_freelist(&anim_data);
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ Scene *scene = ac->scene;
+ CfraElem *ce;
+ KeyframeEditFunc select_cb, ok_cb;
+ KeyframeEditData ked;
+
+ /* initialize keyframe editing data */
+ memset(&ked, 0, sizeof(KeyframeEditData));
+
+ /* build list of columns */
+ switch (mode) {
+ case GRAPHKEYS_COLUMNSEL_KEYS: /* list of selected keys */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ for (ale = anim_data.first; ale; ale = ale->next)
+ ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, bezt_to_cfraelem, NULL);
+
+ ANIM_animdata_freelist(&anim_data);
+ break;
+
+ case GRAPHKEYS_COLUMNSEL_CFRA: /* current frame */
+ /* make a single CfraElem for storing this */
+ ce = MEM_callocN(sizeof(CfraElem), "cfraElem");
+ BLI_addtail(&ked.list, ce);
+
+ ce->cfra = (float)CFRA;
+ break;
+
+ case GRAPHKEYS_COLUMNSEL_MARKERS_COLUMN: /* list of selected markers */
+ ED_markers_make_cfra_list(ac->markers, &ked.list, SELECT);
+ break;
+
+ default: /* invalid option */
+ return;
+ }
+
+ /* set up BezTriple edit callbacks */
+ select_cb = ANIM_editkeyframes_select(SELECT_ADD);
+ ok_cb = ANIM_editkeyframes_ok(BEZT_OK_FRAME);
+
+ /* loop through all of the keys and select additional keyframes
+ * based on the keys found to be selected above
+ */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ AnimData *adt = ANIM_nla_mapping_get(ac, ale);
+
+ /* loop over cfraelems (stored in the KeyframeEditData->list)
+ * - we need to do this here, as we can apply fewer NLA-mapping conversions
+ */
+ for (ce = ked.list.first; ce; ce = ce->next) {
+ /* set frame for validation callback to refer to */
+ ked.f1 = BKE_nla_tweakedit_remap(adt, ce->cfra, NLATIME_CONVERT_UNMAP);
+
+ /* select elements with frame number matching cfraelem */
+ ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
+ }
+ }
+
+ /* free elements */
+ BLI_freelistN(&ked.list);
+ ANIM_animdata_freelist(&anim_data);
}
/* ------------------- */
static int graphkeys_columnselect_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- short mode;
+ bAnimContext ac;
+ short mode;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* action to take depends on the mode */
- mode = RNA_enum_get(op->ptr, "mode");
+ /* action to take depends on the mode */
+ mode = RNA_enum_get(op->ptr, "mode");
- if (mode == GRAPHKEYS_COLUMNSEL_MARKERS_BETWEEN)
- markers_selectkeys_between(&ac);
- else
- columnselect_graph_keys(&ac, mode);
+ if (mode == GRAPHKEYS_COLUMNSEL_MARKERS_BETWEEN)
+ markers_selectkeys_between(&ac);
+ else
+ columnselect_graph_keys(&ac, mode);
- /* set notifier that keyframe selection has changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
+ /* set notifier that keyframe selection has changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void GRAPH_OT_select_column(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Select All";
- ot->idname = "GRAPH_OT_select_column";
- ot->description = "Select all keyframes on the specified frame(s)";
+ /* identifiers */
+ ot->name = "Select All";
+ ot->idname = "GRAPH_OT_select_column";
+ ot->description = "Select all keyframes on the specified frame(s)";
- /* api callbacks */
- ot->exec = graphkeys_columnselect_exec;
- ot->poll = graphop_visible_keyframes_poll;
+ /* api callbacks */
+ ot->exec = graphkeys_columnselect_exec;
+ ot->poll = graphop_visible_keyframes_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* props */
- ot->prop = RNA_def_enum(ot->srna, "mode", prop_column_select_types, 0, "Mode", "");
+ /* props */
+ ot->prop = RNA_def_enum(ot->srna, "mode", prop_column_select_types, 0, "Mode", "");
}
/* ******************** Select Linked Operator *********************** */
static int graphkeys_select_linked_exec(bContext *C, wmOperator *UNUSED(op))
{
- bAnimContext ac;
+ bAnimContext ac;
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
- KeyframeEditFunc ok_cb = ANIM_editkeyframes_ok(BEZT_OK_SELECTED);
- KeyframeEditFunc sel_cb = ANIM_editkeyframes_select(SELECT_ADD);
+ KeyframeEditFunc ok_cb = ANIM_editkeyframes_ok(BEZT_OK_SELECTED);
+ KeyframeEditFunc sel_cb = ANIM_editkeyframes_select(SELECT_ADD);
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* loop through all of the keys and select additional keyframes based on these */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+ /* loop through all of the keys and select additional keyframes based on these */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
- for (ale = anim_data.first; ale; ale = ale->next) {
- FCurve *fcu = (FCurve *)ale->key_data;
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ FCurve *fcu = (FCurve *)ale->key_data;
- /* check if anything selected? */
- if (ANIM_fcurve_keyframes_loop(NULL, fcu, NULL, ok_cb, NULL)) {
- /* select every keyframe in this curve then */
- ANIM_fcurve_keyframes_loop(NULL, fcu, NULL, sel_cb, NULL);
- }
- }
+ /* check if anything selected? */
+ if (ANIM_fcurve_keyframes_loop(NULL, fcu, NULL, ok_cb, NULL)) {
+ /* select every keyframe in this curve then */
+ ANIM_fcurve_keyframes_loop(NULL, fcu, NULL, sel_cb, NULL);
+ }
+ }
- /* Cleanup */
- ANIM_animdata_freelist(&anim_data);
+ /* Cleanup */
+ ANIM_animdata_freelist(&anim_data);
- /* set notifier that keyframe selection has changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
+ /* set notifier that keyframe selection has changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void GRAPH_OT_select_linked(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Select Linked";
- ot->idname = "GRAPH_OT_select_linked";
- ot->description = "Select keyframes occurring in the same F-Curves as selected ones";
+ /* identifiers */
+ ot->name = "Select Linked";
+ ot->idname = "GRAPH_OT_select_linked";
+ ot->description = "Select keyframes occurring in the same F-Curves as selected ones";
- /* api callbacks */
- ot->exec = graphkeys_select_linked_exec;
- ot->poll = graphop_visible_keyframes_poll;
+ /* api callbacks */
+ ot->exec = graphkeys_select_linked_exec;
+ ot->poll = graphop_visible_keyframes_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ******************** Select More/Less Operators *********************** */
@@ -803,111 +809,110 @@ void GRAPH_OT_select_linked(wmOperatorType *ot)
/* Common code to perform selection */
static void select_moreless_graph_keys(bAnimContext *ac, short mode)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- KeyframeEditData ked;
- KeyframeEditFunc build_cb;
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+ KeyframeEditData ked;
+ KeyframeEditFunc build_cb;
- /* init selmap building data */
- build_cb = ANIM_editkeyframes_buildselmap(mode);
- memset(&ked, 0, sizeof(KeyframeEditData));
+ /* init selmap building data */
+ build_cb = ANIM_editkeyframes_buildselmap(mode);
+ memset(&ked, 0, sizeof(KeyframeEditData));
- /* loop through all of the keys and select additional keyframes based on these */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+ /* loop through all of the keys and select additional keyframes based on these */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
- for (ale = anim_data.first; ale; ale = ale->next) {
- FCurve *fcu = (FCurve *)ale->key_data;
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ FCurve *fcu = (FCurve *)ale->key_data;
- /* only continue if F-Curve has keyframes */
- if (fcu->bezt == NULL)
- continue;
+ /* only continue if F-Curve has keyframes */
+ if (fcu->bezt == NULL)
+ continue;
- /* build up map of whether F-Curve's keyframes should be selected or not */
- ked.data = MEM_callocN(fcu->totvert, "selmap graphEdit");
- ANIM_fcurve_keyframes_loop(&ked, fcu, NULL, build_cb, NULL);
+ /* build up map of whether F-Curve's keyframes should be selected or not */
+ ked.data = MEM_callocN(fcu->totvert, "selmap graphEdit");
+ ANIM_fcurve_keyframes_loop(&ked, fcu, NULL, build_cb, NULL);
- /* based on this map, adjust the selection status of the keyframes */
- ANIM_fcurve_keyframes_loop(&ked, fcu, NULL, bezt_selmap_flush, NULL);
+ /* based on this map, adjust the selection status of the keyframes */
+ ANIM_fcurve_keyframes_loop(&ked, fcu, NULL, bezt_selmap_flush, NULL);
- /* free the selmap used here */
- MEM_freeN(ked.data);
- ked.data = NULL;
- }
+ /* free the selmap used here */
+ MEM_freeN(ked.data);
+ ked.data = NULL;
+ }
- /* Cleanup */
- ANIM_animdata_freelist(&anim_data);
+ /* Cleanup */
+ ANIM_animdata_freelist(&anim_data);
}
/* ----------------- */
static int graphkeys_select_more_exec(bContext *C, wmOperator *UNUSED(op))
{
- bAnimContext ac;
+ bAnimContext ac;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* perform select changes */
- select_moreless_graph_keys(&ac, SELMAP_MORE);
+ /* perform select changes */
+ select_moreless_graph_keys(&ac, SELMAP_MORE);
- /* set notifier that keyframe selection has changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
+ /* set notifier that keyframe selection has changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void GRAPH_OT_select_more(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Select More";
- ot->idname = "GRAPH_OT_select_more";
- ot->description = "Select keyframes beside already selected ones";
+ /* identifiers */
+ ot->name = "Select More";
+ ot->idname = "GRAPH_OT_select_more";
+ ot->description = "Select keyframes beside already selected ones";
- /* api callbacks */
- ot->exec = graphkeys_select_more_exec;
- ot->poll = graphop_visible_keyframes_poll;
+ /* api callbacks */
+ ot->exec = graphkeys_select_more_exec;
+ ot->poll = graphop_visible_keyframes_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ----------------- */
static int graphkeys_select_less_exec(bContext *C, wmOperator *UNUSED(op))
{
- bAnimContext ac;
+ bAnimContext ac;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* perform select changes */
- select_moreless_graph_keys(&ac, SELMAP_LESS);
+ /* perform select changes */
+ select_moreless_graph_keys(&ac, SELMAP_LESS);
- /* set notifier that keyframe selection has changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
+ /* set notifier that keyframe selection has changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void GRAPH_OT_select_less(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Select Less";
- ot->idname = "GRAPH_OT_select_less";
- ot->description = "Deselect keyframes on ends of selection islands";
+ /* identifiers */
+ ot->name = "Select Less";
+ ot->idname = "GRAPH_OT_select_less";
+ ot->description = "Deselect keyframes on ends of selection islands";
- /* api callbacks */
- ot->exec = graphkeys_select_less_exec;
- ot->poll = graphop_visible_keyframes_poll;
+ /* api callbacks */
+ ot->exec = graphkeys_select_less_exec;
+ ot->poll = graphop_visible_keyframes_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ******************** Select Left/Right Operator ************************* */
@@ -915,151 +920,152 @@ void GRAPH_OT_select_less(wmOperatorType *ot)
/* defines for left-right select tool */
static const EnumPropertyItem prop_graphkeys_leftright_select_types[] = {
- {GRAPHKEYS_LRSEL_TEST, "CHECK", 0, "Check if Select Left or Right", ""},
- {GRAPHKEYS_LRSEL_LEFT, "LEFT", 0, "Before current frame", ""},
- {GRAPHKEYS_LRSEL_RIGHT, "RIGHT", 0, "After current frame", ""},
- {0, NULL, 0, NULL, NULL},
+ {GRAPHKEYS_LRSEL_TEST, "CHECK", 0, "Check if Select Left or Right", ""},
+ {GRAPHKEYS_LRSEL_LEFT, "LEFT", 0, "Before current frame", ""},
+ {GRAPHKEYS_LRSEL_RIGHT, "RIGHT", 0, "After current frame", ""},
+ {0, NULL, 0, NULL, NULL},
};
/* --------------------------------- */
static void graphkeys_select_leftright(bAnimContext *ac, short leftright, short select_mode)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- KeyframeEditFunc ok_cb, select_cb;
- KeyframeEditData ked = {{NULL}};
- Scene *scene = ac->scene;
-
- /* if select mode is replace, deselect all keyframes (and channels) first */
- if (select_mode == SELECT_REPLACE) {
- select_mode = SELECT_ADD;
-
- /* - deselect all other keyframes, so that just the newly selected remain
- * - channels aren't deselected, since we don't re-select any as a consequence
- */
- deselect_graph_keys(ac, 0, SELECT_SUBTRACT, false);
- }
-
- /* set callbacks and editing data */
- ok_cb = ANIM_editkeyframes_ok(BEZT_OK_FRAMERANGE);
- select_cb = ANIM_editkeyframes_select(select_mode);
-
- if (leftright == GRAPHKEYS_LRSEL_LEFT) {
- ked.f1 = MINAFRAMEF;
- ked.f2 = (float)(CFRA + 0.1f);
- }
- else {
- ked.f1 = (float)(CFRA - 0.1f);
- ked.f2 = MAXFRAMEF;
- }
-
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* select keys */
- for (ale = anim_data.first; ale; ale = ale->next) {
- AnimData *adt = ANIM_nla_mapping_get(ac, ale);
-
- if (adt) {
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
- ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1);
- }
- else
- ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
- }
-
- /* Cleanup */
- ANIM_animdata_freelist(&anim_data);
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ KeyframeEditFunc ok_cb, select_cb;
+ KeyframeEditData ked = {{NULL}};
+ Scene *scene = ac->scene;
+
+ /* if select mode is replace, deselect all keyframes (and channels) first */
+ if (select_mode == SELECT_REPLACE) {
+ select_mode = SELECT_ADD;
+
+ /* - deselect all other keyframes, so that just the newly selected remain
+ * - channels aren't deselected, since we don't re-select any as a consequence
+ */
+ deselect_graph_keys(ac, 0, SELECT_SUBTRACT, false);
+ }
+
+ /* set callbacks and editing data */
+ ok_cb = ANIM_editkeyframes_ok(BEZT_OK_FRAMERANGE);
+ select_cb = ANIM_editkeyframes_select(select_mode);
+
+ if (leftright == GRAPHKEYS_LRSEL_LEFT) {
+ ked.f1 = MINAFRAMEF;
+ ked.f2 = (float)(CFRA + 0.1f);
+ }
+ else {
+ ked.f1 = (float)(CFRA - 0.1f);
+ ked.f2 = MAXFRAMEF;
+ }
+
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* select keys */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ AnimData *adt = ANIM_nla_mapping_get(ac, ale);
+
+ if (adt) {
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
+ ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1);
+ }
+ else
+ ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
+ }
+
+ /* Cleanup */
+ ANIM_animdata_freelist(&anim_data);
}
/* ----------------- */
static int graphkeys_select_leftright_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- short leftright = RNA_enum_get(op->ptr, "mode");
- short selectmode;
+ bAnimContext ac;
+ short leftright = RNA_enum_get(op->ptr, "mode");
+ short selectmode;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* select mode is either replace (deselect all, then add) or add/extend */
- if (RNA_boolean_get(op->ptr, "extend"))
- selectmode = SELECT_INVERT;
- else
- selectmode = SELECT_REPLACE;
+ /* select mode is either replace (deselect all, then add) or add/extend */
+ if (RNA_boolean_get(op->ptr, "extend"))
+ selectmode = SELECT_INVERT;
+ else
+ selectmode = SELECT_REPLACE;
- /* if "test" mode is set, we don't have any info to set this with */
- if (leftright == GRAPHKEYS_LRSEL_TEST)
- return OPERATOR_CANCELLED;
+ /* if "test" mode is set, we don't have any info to set this with */
+ if (leftright == GRAPHKEYS_LRSEL_TEST)
+ return OPERATOR_CANCELLED;
- /* do the selecting now */
- graphkeys_select_leftright(&ac, leftright, selectmode);
+ /* do the selecting now */
+ graphkeys_select_leftright(&ac, leftright, selectmode);
- /* set notifier that keyframe selection (and channels too) have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_SELECTED, NULL);
+ /* set notifier that keyframe selection (and channels too) have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_SELECTED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
static int graphkeys_select_leftright_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- bAnimContext ac;
- short leftright = RNA_enum_get(op->ptr, "mode");
-
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
-
- /* handle mode-based testing */
- if (leftright == GRAPHKEYS_LRSEL_TEST) {
- Scene *scene = ac.scene;
- ARegion *ar = ac.ar;
- View2D *v2d = &ar->v2d;
- float x;
-
- /* determine which side of the current frame mouse is on */
- x = UI_view2d_region_to_view_x(v2d, event->mval[0]);
- if (x < CFRA)
- RNA_enum_set(op->ptr, "mode", GRAPHKEYS_LRSEL_LEFT);
- else
- RNA_enum_set(op->ptr, "mode", GRAPHKEYS_LRSEL_RIGHT);
- }
-
- /* perform selection */
- return graphkeys_select_leftright_exec(C, op);
+ bAnimContext ac;
+ short leftright = RNA_enum_get(op->ptr, "mode");
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* handle mode-based testing */
+ if (leftright == GRAPHKEYS_LRSEL_TEST) {
+ Scene *scene = ac.scene;
+ ARegion *ar = ac.ar;
+ View2D *v2d = &ar->v2d;
+ float x;
+
+ /* determine which side of the current frame mouse is on */
+ x = UI_view2d_region_to_view_x(v2d, event->mval[0]);
+ if (x < CFRA)
+ RNA_enum_set(op->ptr, "mode", GRAPHKEYS_LRSEL_LEFT);
+ else
+ RNA_enum_set(op->ptr, "mode", GRAPHKEYS_LRSEL_RIGHT);
+ }
+
+ /* perform selection */
+ return graphkeys_select_leftright_exec(C, op);
}
void GRAPH_OT_select_leftright(wmOperatorType *ot)
{
- PropertyRNA *prop;
+ PropertyRNA *prop;
- /* identifiers */
- ot->name = "Select Left/Right";
- ot->idname = "GRAPH_OT_select_leftright";
- ot->description = "Select keyframes to the left or the right of the current frame";
+ /* identifiers */
+ ot->name = "Select Left/Right";
+ ot->idname = "GRAPH_OT_select_leftright";
+ ot->description = "Select keyframes to the left or the right of the current frame";
- /* api callbacks */
- ot->invoke = graphkeys_select_leftright_invoke;
- ot->exec = graphkeys_select_leftright_exec;
- ot->poll = graphop_visible_keyframes_poll;
+ /* api callbacks */
+ ot->invoke = graphkeys_select_leftright_invoke;
+ ot->exec = graphkeys_select_leftright_exec;
+ ot->poll = graphop_visible_keyframes_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* id-props */
- ot->prop = RNA_def_enum(ot->srna, "mode", prop_graphkeys_leftright_select_types, GRAPHKEYS_LRSEL_TEST, "Mode", "");
- RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
+ /* id-props */
+ ot->prop = RNA_def_enum(
+ ot->srna, "mode", prop_graphkeys_leftright_select_types, GRAPHKEYS_LRSEL_TEST, "Mode", "");
+ RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
- prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", "");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", "");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
/* ******************** Mouse-Click Select Operator *********************** */
@@ -1074,32 +1080,32 @@ void GRAPH_OT_select_leftright(wmOperatorType *ot)
/* temp info for caching handle vertices close */
typedef struct tNearestVertInfo {
- struct tNearestVertInfo *next, *prev;
+ struct tNearestVertInfo *next, *prev;
- FCurve *fcu; /* F-Curve that keyframe comes from */
+ FCurve *fcu; /* F-Curve that keyframe comes from */
- BezTriple *bezt; /* keyframe to consider */
- FPoint *fpt; /* sample point to consider */
+ BezTriple *bezt; /* keyframe to consider */
+ FPoint *fpt; /* sample point to consider */
- short hpoint; /* the handle index that we hit (eHandleIndex) */
- short sel; /* whether the handle is selected or not */
- int dist; /* distance from mouse to vert */
+ short hpoint; /* the handle index that we hit (eHandleIndex) */
+ short sel; /* whether the handle is selected or not */
+ int dist; /* distance from mouse to vert */
- eAnim_ChannelType ctype; /* type of animation channel this FCurve comes from */
+ eAnim_ChannelType ctype; /* type of animation channel this FCurve comes from */
- float frame; /* frame that point was on when it matched (global time) */
+ float frame; /* frame that point was on when it matched (global time) */
} tNearestVertInfo;
/* Tags for the type of graph vert that we have */
typedef enum eGraphVertIndex {
- NEAREST_HANDLE_LEFT = -1,
- NEAREST_HANDLE_KEY,
- NEAREST_HANDLE_RIGHT,
+ NEAREST_HANDLE_LEFT = -1,
+ NEAREST_HANDLE_KEY,
+ NEAREST_HANDLE_RIGHT,
} eGraphVertIndex;
/* Tolerance for absolute radius (in pixels) of the vert from the cursor to use */
// TODO: perhaps this should depend a bit on the size that the user set the vertices to be?
-#define GVERTSEL_TOL 10
+#define GVERTSEL_TOL 10
/* ....... */
@@ -1107,171 +1113,210 @@ typedef enum eGraphVertIndex {
// XXX also need to check for int-values only?
static bool fcurve_handle_sel_check(SpaceGraph *sipo, BezTriple *bezt)
{
- if (sipo->flag & SIPO_NOHANDLES) return 0;
- if ((sipo->flag & SIPO_SELVHANDLESONLY) && BEZT_ISSEL_ANY(bezt) == 0) return 0;
- return 1;
+ if (sipo->flag & SIPO_NOHANDLES)
+ return 0;
+ if ((sipo->flag & SIPO_SELVHANDLESONLY) && BEZT_ISSEL_ANY(bezt) == 0)
+ return 0;
+ return 1;
}
/* check if the given vertex is within bounds or not */
// TODO: should we return if we hit something?
-static void nearest_fcurve_vert_store(
- ListBase *matches, View2D *v2d, FCurve *fcu, eAnim_ChannelType ctype,
- BezTriple *bezt, FPoint *fpt, short hpoint, const int mval[2], float unit_scale, float offset)
+static void nearest_fcurve_vert_store(ListBase *matches,
+ View2D *v2d,
+ FCurve *fcu,
+ eAnim_ChannelType ctype,
+ BezTriple *bezt,
+ FPoint *fpt,
+ short hpoint,
+ const int mval[2],
+ float unit_scale,
+ float offset)
{
- /* Keyframes or Samples? */
- if (bezt) {
- int screen_co[2], dist;
-
- /* convert from data-space to screen coordinates
- * NOTE: hpoint+1 gives us 0,1,2 respectively for each handle,
- * needed to access the relevant vertex coordinates in the 3x3
- * 'vec' matrix
- */
- if (UI_view2d_view_to_region_clip(v2d,
- bezt->vec[hpoint + 1][0], (bezt->vec[hpoint + 1][1] + offset) * unit_scale,
- &screen_co[0], &screen_co[1]) &&
- /* check if distance from mouse cursor to vert in screen space is within tolerance */
- ((dist = len_v2v2_int(mval, screen_co)) <= GVERTSEL_TOL))
- {
- tNearestVertInfo *nvi = (tNearestVertInfo *)matches->last;
- bool replace = false;
-
- /* if there is already a point for the F-Curve, check if this point is closer than that was */
- if ((nvi) && (nvi->fcu == fcu)) {
- /* replace if we are closer, or if equal and that one wasn't selected but we are... */
- if ((nvi->dist > dist) || ((nvi->sel == 0) && BEZT_ISSEL_ANY(bezt)))
- replace = 1;
- }
- /* add new if not replacing... */
- if (replace == 0)
- nvi = MEM_callocN(sizeof(tNearestVertInfo), "Nearest Graph Vert Info - Bezt");
-
- /* store values */
- nvi->fcu = fcu;
- nvi->ctype = ctype;
-
- nvi->bezt = bezt;
- nvi->hpoint = hpoint;
- nvi->dist = dist;
-
- nvi->frame = bezt->vec[1][0]; /* currently in global time... */
-
- nvi->sel = BEZT_ISSEL_ANY(bezt); // XXX... should this use the individual verts instead?
-
- /* add to list of matches if appropriate... */
- if (replace == 0)
- BLI_addtail(matches, nvi);
- }
- }
- else if (fpt) {
- /* TODO... */
- }
+ /* Keyframes or Samples? */
+ if (bezt) {
+ int screen_co[2], dist;
+
+ /* convert from data-space to screen coordinates
+ * NOTE: hpoint+1 gives us 0,1,2 respectively for each handle,
+ * needed to access the relevant vertex coordinates in the 3x3
+ * 'vec' matrix
+ */
+ if (UI_view2d_view_to_region_clip(v2d,
+ bezt->vec[hpoint + 1][0],
+ (bezt->vec[hpoint + 1][1] + offset) * unit_scale,
+ &screen_co[0],
+ &screen_co[1]) &&
+ /* check if distance from mouse cursor to vert in screen space is within tolerance */
+ ((dist = len_v2v2_int(mval, screen_co)) <= GVERTSEL_TOL)) {
+ tNearestVertInfo *nvi = (tNearestVertInfo *)matches->last;
+ bool replace = false;
+
+ /* if there is already a point for the F-Curve, check if this point is closer than that was */
+ if ((nvi) && (nvi->fcu == fcu)) {
+ /* replace if we are closer, or if equal and that one wasn't selected but we are... */
+ if ((nvi->dist > dist) || ((nvi->sel == 0) && BEZT_ISSEL_ANY(bezt)))
+ replace = 1;
+ }
+ /* add new if not replacing... */
+ if (replace == 0)
+ nvi = MEM_callocN(sizeof(tNearestVertInfo), "Nearest Graph Vert Info - Bezt");
+
+ /* store values */
+ nvi->fcu = fcu;
+ nvi->ctype = ctype;
+
+ nvi->bezt = bezt;
+ nvi->hpoint = hpoint;
+ nvi->dist = dist;
+
+ nvi->frame = bezt->vec[1][0]; /* currently in global time... */
+
+ nvi->sel = BEZT_ISSEL_ANY(bezt); // XXX... should this use the individual verts instead?
+
+ /* add to list of matches if appropriate... */
+ if (replace == 0)
+ BLI_addtail(matches, nvi);
+ }
+ }
+ else if (fpt) {
+ /* TODO... */
+ }
}
/* helper for find_nearest_fcurve_vert() - build the list of nearest matches */
static void get_nearest_fcurve_verts_list(bAnimContext *ac, const int mval[2], ListBase *matches)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- SpaceGraph *sipo = (SpaceGraph *)ac->sl;
- View2D *v2d = &ac->ar->v2d;
- short mapping_flag = 0;
-
- /* get curves to search through
- * - if the option to only show keyframes that belong to selected F-Curves is enabled,
- * include the 'only selected' flag...
- */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
- if (sipo->flag & SIPO_SELCUVERTSONLY) // FIXME: this should really be check for by the filtering code...
- filter |= ANIMFILTER_SEL;
- mapping_flag |= ANIM_get_normalization_flags(ac);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- for (ale = anim_data.first; ale; ale = ale->next) {
- FCurve *fcu = (FCurve *)ale->key_data;
- AnimData *adt = ANIM_nla_mapping_get(ac, ale);
- float offset;
- float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag, &offset);
-
- /* apply NLA mapping to all the keyframes */
- if (adt)
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0);
-
- if (fcu->bezt) {
- BezTriple *bezt1 = fcu->bezt, *prevbezt = NULL;
- int i;
-
- for (i = 0; i < fcu->totvert; i++, prevbezt = bezt1, bezt1++) {
- /* keyframe */
- nearest_fcurve_vert_store(matches, v2d, fcu, ale->type, bezt1, NULL, NEAREST_HANDLE_KEY, mval, unit_scale, offset);
-
- /* handles - only do them if they're visible */
- if (fcurve_handle_sel_check(sipo, bezt1) && (fcu->totvert > 1)) {
- /* first handle only visible if previous segment had handles */
- if ((!prevbezt && (bezt1->ipo == BEZT_IPO_BEZ)) || (prevbezt && (prevbezt->ipo == BEZT_IPO_BEZ))) {
- nearest_fcurve_vert_store(matches, v2d, fcu, ale->type, bezt1, NULL, NEAREST_HANDLE_LEFT, mval, unit_scale, offset);
- }
-
- /* second handle only visible if this segment is bezier */
- if (bezt1->ipo == BEZT_IPO_BEZ) {
- nearest_fcurve_vert_store(matches, v2d, fcu, ale->type, bezt1, NULL, NEAREST_HANDLE_RIGHT, mval, unit_scale, offset);
- }
- }
- }
- }
- else if (fcu->fpt) {
- // TODO; do this for samples too
-
- }
-
- /* un-apply NLA mapping from all the keyframes */
- if (adt)
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 0);
- }
-
- /* free channels */
- ANIM_animdata_freelist(&anim_data);
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ SpaceGraph *sipo = (SpaceGraph *)ac->sl;
+ View2D *v2d = &ac->ar->v2d;
+ short mapping_flag = 0;
+
+ /* get curves to search through
+ * - if the option to only show keyframes that belong to selected F-Curves is enabled,
+ * include the 'only selected' flag...
+ */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
+ if (sipo->flag &
+ SIPO_SELCUVERTSONLY) // FIXME: this should really be check for by the filtering code...
+ filter |= ANIMFILTER_SEL;
+ mapping_flag |= ANIM_get_normalization_flags(ac);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ FCurve *fcu = (FCurve *)ale->key_data;
+ AnimData *adt = ANIM_nla_mapping_get(ac, ale);
+ float offset;
+ float unit_scale = ANIM_unit_mapping_get_factor(
+ ac->scene, ale->id, fcu, mapping_flag, &offset);
+
+ /* apply NLA mapping to all the keyframes */
+ if (adt)
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0);
+
+ if (fcu->bezt) {
+ BezTriple *bezt1 = fcu->bezt, *prevbezt = NULL;
+ int i;
+
+ for (i = 0; i < fcu->totvert; i++, prevbezt = bezt1, bezt1++) {
+ /* keyframe */
+ nearest_fcurve_vert_store(matches,
+ v2d,
+ fcu,
+ ale->type,
+ bezt1,
+ NULL,
+ NEAREST_HANDLE_KEY,
+ mval,
+ unit_scale,
+ offset);
+
+ /* handles - only do them if they're visible */
+ if (fcurve_handle_sel_check(sipo, bezt1) && (fcu->totvert > 1)) {
+ /* first handle only visible if previous segment had handles */
+ if ((!prevbezt && (bezt1->ipo == BEZT_IPO_BEZ)) ||
+ (prevbezt && (prevbezt->ipo == BEZT_IPO_BEZ))) {
+ nearest_fcurve_vert_store(matches,
+ v2d,
+ fcu,
+ ale->type,
+ bezt1,
+ NULL,
+ NEAREST_HANDLE_LEFT,
+ mval,
+ unit_scale,
+ offset);
+ }
+
+ /* second handle only visible if this segment is bezier */
+ if (bezt1->ipo == BEZT_IPO_BEZ) {
+ nearest_fcurve_vert_store(matches,
+ v2d,
+ fcu,
+ ale->type,
+ bezt1,
+ NULL,
+ NEAREST_HANDLE_RIGHT,
+ mval,
+ unit_scale,
+ offset);
+ }
+ }
+ }
+ }
+ else if (fcu->fpt) {
+ // TODO; do this for samples too
+ }
+
+ /* un-apply NLA mapping from all the keyframes */
+ if (adt)
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 0);
+ }
+
+ /* free channels */
+ ANIM_animdata_freelist(&anim_data);
}
/* helper for find_nearest_fcurve_vert() - get the best match to use */
static tNearestVertInfo *get_best_nearest_fcurve_vert(ListBase *matches)
{
- tNearestVertInfo *nvi = NULL;
- short found = 0;
-
- /* abort if list is empty */
- if (BLI_listbase_is_empty(matches))
- return NULL;
-
- /* if list only has 1 item, remove it from the list and return */
- if (BLI_listbase_is_single(matches)) {
- /* need to remove from the list, otherwise it gets freed and then we can't return it */
- return BLI_pophead(matches);
- }
-
- /* try to find the first selected F-Curve vert, then take the one after it */
- for (nvi = matches->first; nvi; nvi = nvi->next) {
- /* which mode of search are we in: find first selected, or find vert? */
- if (found) {
- /* just take this vert now that we've found the selected one
- * - we'll need to remove this from the list so that it can be returned to the original caller
- */
- BLI_remlink(matches, nvi);
- return nvi;
- }
- else {
- /* if vert is selected, we've got what we want... */
- if (nvi->sel)
- found = 1;
- }
- }
-
- /* if we're still here, this means that we failed to find anything appropriate in the first pass,
- * so just take the first item now...
- */
- return BLI_pophead(matches);
+ tNearestVertInfo *nvi = NULL;
+ short found = 0;
+
+ /* abort if list is empty */
+ if (BLI_listbase_is_empty(matches))
+ return NULL;
+
+ /* if list only has 1 item, remove it from the list and return */
+ if (BLI_listbase_is_single(matches)) {
+ /* need to remove from the list, otherwise it gets freed and then we can't return it */
+ return BLI_pophead(matches);
+ }
+
+ /* try to find the first selected F-Curve vert, then take the one after it */
+ for (nvi = matches->first; nvi; nvi = nvi->next) {
+ /* which mode of search are we in: find first selected, or find vert? */
+ if (found) {
+ /* just take this vert now that we've found the selected one
+ * - we'll need to remove this from the list so that it can be returned to the original caller
+ */
+ BLI_remlink(matches, nvi);
+ return nvi;
+ }
+ else {
+ /* if vert is selected, we've got what we want... */
+ if (nvi->sel)
+ found = 1;
+ }
+ }
+
+ /* if we're still here, this means that we failed to find anything appropriate in the first pass,
+ * so just take the first item now...
+ */
+ return BLI_pophead(matches);
}
/* Find the nearest vertices (either a handle or the keyframe) that are nearest to the mouse cursor (in area coordinates)
@@ -1279,142 +1324,145 @@ static tNearestVertInfo *get_best_nearest_fcurve_vert(ListBase *matches)
*/
static tNearestVertInfo *find_nearest_fcurve_vert(bAnimContext *ac, const int mval[2])
{
- ListBase matches = {NULL, NULL};
- tNearestVertInfo *nvi;
+ ListBase matches = {NULL, NULL};
+ tNearestVertInfo *nvi;
- /* step 1: get the nearest verts */
- get_nearest_fcurve_verts_list(ac, mval, &matches);
+ /* step 1: get the nearest verts */
+ get_nearest_fcurve_verts_list(ac, mval, &matches);
- /* step 2: find the best vert */
- nvi = get_best_nearest_fcurve_vert(&matches);
+ /* step 2: find the best vert */
+ nvi = get_best_nearest_fcurve_vert(&matches);
- BLI_freelistN(&matches);
+ BLI_freelistN(&matches);
- /* return the best vert found */
- return nvi;
+ /* return the best vert found */
+ return nvi;
}
/* ------------------- */
/* option 1) select keyframe directly under mouse */
-static void mouse_graph_keys(bAnimContext *ac, const int mval[2], short select_mode, short curves_only)
+static void mouse_graph_keys(bAnimContext *ac,
+ const int mval[2],
+ short select_mode,
+ short curves_only)
{
- SpaceGraph *sipo = (SpaceGraph *)ac->sl;
- tNearestVertInfo *nvi;
- BezTriple *bezt = NULL;
-
- /* find the beztriple that we're selecting, and the handle that was clicked on */
- nvi = find_nearest_fcurve_vert(ac, mval);
-
- /* check if anything to select */
- if (nvi == NULL)
- return;
-
- /* deselect all other curves? */
- if (select_mode == SELECT_REPLACE) {
- /* reset selection mode */
- select_mode = SELECT_ADD;
-
- /* deselect all other keyframes (+ F-Curves too) */
- deselect_graph_keys(ac, 0, SELECT_SUBTRACT, true);
-
- /* deselect other channels too, but only only do this if
- * selection of channel when the visibility of keyframes
- * doesn't depend on this
- */
- if ((sipo->flag & SIPO_SELCUVERTSONLY) == 0)
- ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
- }
-
- /* if points can be selected on this F-Curve */
- // TODO: what about those with no keyframes?
- if ((curves_only == 0) && ((nvi->fcu->flag & FCURVE_PROTECTED) == 0)) {
- /* only if there's keyframe */
- if (nvi->bezt) {
- bezt = nvi->bezt; /* used to check bezt seletion is set */
- /* depends on selection mode */
- if (select_mode == SELECT_INVERT) {
- /* keyframe - invert select of all */
- if (nvi->hpoint == NEAREST_HANDLE_KEY) {
- if (BEZT_ISSEL_ANY(bezt)) {
- BEZT_DESEL_ALL(bezt);
- }
- else {
- BEZT_SEL_ALL(bezt);
- }
- }
-
- /* handles - toggle selection of relevant handle */
- else if (nvi->hpoint == NEAREST_HANDLE_LEFT) {
- /* toggle selection */
- bezt->f1 ^= SELECT;
- }
- else {
- /* toggle selection */
- bezt->f3 ^= SELECT;
- }
- }
- else {
- /* if the keyframe was clicked on, select all verts of given beztriple */
- if (nvi->hpoint == NEAREST_HANDLE_KEY) {
- BEZT_SEL_ALL(bezt);
- }
- /* otherwise, select the handle that applied */
- else if (nvi->hpoint == NEAREST_HANDLE_LEFT)
- bezt->f1 |= SELECT;
- else
- bezt->f3 |= SELECT;
- }
- }
- else if (nvi->fpt) {
- // TODO: need to handle sample points
- }
- }
- else {
- KeyframeEditFunc select_cb;
- KeyframeEditData ked;
-
- /* initialize keyframe editing data */
- memset(&ked, 0, sizeof(KeyframeEditData));
-
- /* set up BezTriple edit callbacks */
- select_cb = ANIM_editkeyframes_select(select_mode);
-
- /* select all keyframes */
- ANIM_fcurve_keyframes_loop(&ked, nvi->fcu, NULL, select_cb, NULL);
- }
-
- /* only change selection of channel when the visibility of keyframes doesn't depend on this */
- if ((sipo->flag & SIPO_SELCUVERTSONLY) == 0) {
- /* select or deselect curve? */
- if (bezt) {
- /* take selection status from item that got hit, to prevent flip/flop on channel
- * selection status when shift-selecting (i.e. "SELECT_INVERT") points
- */
- if (BEZT_ISSEL_ANY(bezt))
- nvi->fcu->flag |= FCURVE_SELECTED;
- else
- nvi->fcu->flag &= ~FCURVE_SELECTED;
- }
- else {
- /* didn't hit any channel, so just apply that selection mode to the curve's selection status */
- if (select_mode == SELECT_INVERT)
- nvi->fcu->flag ^= FCURVE_SELECTED;
- else if (select_mode == SELECT_ADD)
- nvi->fcu->flag |= FCURVE_SELECTED;
- }
- }
-
- /* set active F-Curve (NOTE: sync the filter flags with findnearest_fcurve_vert) */
- /* needs to be called with (sipo->flag & SIPO_SELCUVERTSONLY)
- * otherwise the active flag won't be set T26452. */
- if (nvi->fcu->flag & FCURVE_SELECTED) {
- int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
- ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, nvi->fcu, nvi->ctype);
- }
-
- /* free temp sample data for filtering */
- MEM_freeN(nvi);
+ SpaceGraph *sipo = (SpaceGraph *)ac->sl;
+ tNearestVertInfo *nvi;
+ BezTriple *bezt = NULL;
+
+ /* find the beztriple that we're selecting, and the handle that was clicked on */
+ nvi = find_nearest_fcurve_vert(ac, mval);
+
+ /* check if anything to select */
+ if (nvi == NULL)
+ return;
+
+ /* deselect all other curves? */
+ if (select_mode == SELECT_REPLACE) {
+ /* reset selection mode */
+ select_mode = SELECT_ADD;
+
+ /* deselect all other keyframes (+ F-Curves too) */
+ deselect_graph_keys(ac, 0, SELECT_SUBTRACT, true);
+
+ /* deselect other channels too, but only only do this if
+ * selection of channel when the visibility of keyframes
+ * doesn't depend on this
+ */
+ if ((sipo->flag & SIPO_SELCUVERTSONLY) == 0)
+ ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
+ }
+
+ /* if points can be selected on this F-Curve */
+ // TODO: what about those with no keyframes?
+ if ((curves_only == 0) && ((nvi->fcu->flag & FCURVE_PROTECTED) == 0)) {
+ /* only if there's keyframe */
+ if (nvi->bezt) {
+ bezt = nvi->bezt; /* used to check bezt seletion is set */
+ /* depends on selection mode */
+ if (select_mode == SELECT_INVERT) {
+ /* keyframe - invert select of all */
+ if (nvi->hpoint == NEAREST_HANDLE_KEY) {
+ if (BEZT_ISSEL_ANY(bezt)) {
+ BEZT_DESEL_ALL(bezt);
+ }
+ else {
+ BEZT_SEL_ALL(bezt);
+ }
+ }
+
+ /* handles - toggle selection of relevant handle */
+ else if (nvi->hpoint == NEAREST_HANDLE_LEFT) {
+ /* toggle selection */
+ bezt->f1 ^= SELECT;
+ }
+ else {
+ /* toggle selection */
+ bezt->f3 ^= SELECT;
+ }
+ }
+ else {
+ /* if the keyframe was clicked on, select all verts of given beztriple */
+ if (nvi->hpoint == NEAREST_HANDLE_KEY) {
+ BEZT_SEL_ALL(bezt);
+ }
+ /* otherwise, select the handle that applied */
+ else if (nvi->hpoint == NEAREST_HANDLE_LEFT)
+ bezt->f1 |= SELECT;
+ else
+ bezt->f3 |= SELECT;
+ }
+ }
+ else if (nvi->fpt) {
+ // TODO: need to handle sample points
+ }
+ }
+ else {
+ KeyframeEditFunc select_cb;
+ KeyframeEditData ked;
+
+ /* initialize keyframe editing data */
+ memset(&ked, 0, sizeof(KeyframeEditData));
+
+ /* set up BezTriple edit callbacks */
+ select_cb = ANIM_editkeyframes_select(select_mode);
+
+ /* select all keyframes */
+ ANIM_fcurve_keyframes_loop(&ked, nvi->fcu, NULL, select_cb, NULL);
+ }
+
+ /* only change selection of channel when the visibility of keyframes doesn't depend on this */
+ if ((sipo->flag & SIPO_SELCUVERTSONLY) == 0) {
+ /* select or deselect curve? */
+ if (bezt) {
+ /* take selection status from item that got hit, to prevent flip/flop on channel
+ * selection status when shift-selecting (i.e. "SELECT_INVERT") points
+ */
+ if (BEZT_ISSEL_ANY(bezt))
+ nvi->fcu->flag |= FCURVE_SELECTED;
+ else
+ nvi->fcu->flag &= ~FCURVE_SELECTED;
+ }
+ else {
+ /* didn't hit any channel, so just apply that selection mode to the curve's selection status */
+ if (select_mode == SELECT_INVERT)
+ nvi->fcu->flag ^= FCURVE_SELECTED;
+ else if (select_mode == SELECT_ADD)
+ nvi->fcu->flag |= FCURVE_SELECTED;
+ }
+ }
+
+ /* set active F-Curve (NOTE: sync the filter flags with findnearest_fcurve_vert) */
+ /* needs to be called with (sipo->flag & SIPO_SELCUVERTSONLY)
+ * otherwise the active flag won't be set T26452. */
+ if (nvi->fcu->flag & FCURVE_SELECTED) {
+ int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
+ ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, nvi->fcu, nvi->ctype);
+ }
+
+ /* free temp sample data for filtering */
+ MEM_freeN(nvi);
}
/* Option 2) Selects all the keyframes on either side of the current frame
@@ -1424,67 +1472,67 @@ static void mouse_graph_keys(bAnimContext *ac, const int mval[2], short select_m
/* Option 3) Selects all visible keyframes in the same frame as the mouse click */
static void graphkeys_mselect_column(bAnimContext *ac, const int mval[2], short select_mode)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- KeyframeEditFunc select_cb, ok_cb;
- KeyframeEditData ked;
- tNearestVertInfo *nvi;
- float selx = (float)ac->scene->r.cfra;
-
- /* find the beztriple that we're selecting, and the handle that was clicked on */
- nvi = find_nearest_fcurve_vert(ac, mval);
-
- /* check if anything to select */
- if (nvi == NULL)
- return;
-
- /* get frame number on which elements should be selected */
- // TODO: should we restrict to integer frames only?
- selx = nvi->frame;
-
- /* if select mode is replace, deselect all keyframes first */
- if (select_mode == SELECT_REPLACE) {
- /* reset selection mode to add to selection */
- select_mode = SELECT_ADD;
-
- /* - deselect all other keyframes, so that just the newly selected remain
- * - channels aren't deselected, since we don't re-select any as a consequence
- */
- deselect_graph_keys(ac, 0, SELECT_SUBTRACT, false);
- }
-
- /* initialize keyframe editing data */
- memset(&ked, 0, sizeof(KeyframeEditData));
-
- /* set up BezTriple edit callbacks */
- select_cb = ANIM_editkeyframes_select(select_mode);
- ok_cb = ANIM_editkeyframes_ok(BEZT_OK_FRAME);
-
- /* loop through all of the keys and select additional keyframes
- * based on the keys found to be selected above
- */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- for (ale = anim_data.first; ale; ale = ale->next) {
- AnimData *adt = ANIM_nla_mapping_get(ac, ale);
-
- /* set frame for validation callback to refer to */
- if (adt)
- ked.f1 = BKE_nla_tweakedit_remap(adt, selx, NLATIME_CONVERT_UNMAP);
- else
- ked.f1 = selx;
-
- /* select elements with frame number matching cfra */
- ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
- }
-
- /* free elements */
- MEM_freeN(nvi);
- BLI_freelistN(&ked.list);
- ANIM_animdata_freelist(&anim_data);
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ KeyframeEditFunc select_cb, ok_cb;
+ KeyframeEditData ked;
+ tNearestVertInfo *nvi;
+ float selx = (float)ac->scene->r.cfra;
+
+ /* find the beztriple that we're selecting, and the handle that was clicked on */
+ nvi = find_nearest_fcurve_vert(ac, mval);
+
+ /* check if anything to select */
+ if (nvi == NULL)
+ return;
+
+ /* get frame number on which elements should be selected */
+ // TODO: should we restrict to integer frames only?
+ selx = nvi->frame;
+
+ /* if select mode is replace, deselect all keyframes first */
+ if (select_mode == SELECT_REPLACE) {
+ /* reset selection mode to add to selection */
+ select_mode = SELECT_ADD;
+
+ /* - deselect all other keyframes, so that just the newly selected remain
+ * - channels aren't deselected, since we don't re-select any as a consequence
+ */
+ deselect_graph_keys(ac, 0, SELECT_SUBTRACT, false);
+ }
+
+ /* initialize keyframe editing data */
+ memset(&ked, 0, sizeof(KeyframeEditData));
+
+ /* set up BezTriple edit callbacks */
+ select_cb = ANIM_editkeyframes_select(select_mode);
+ ok_cb = ANIM_editkeyframes_ok(BEZT_OK_FRAME);
+
+ /* loop through all of the keys and select additional keyframes
+ * based on the keys found to be selected above
+ */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ AnimData *adt = ANIM_nla_mapping_get(ac, ale);
+
+ /* set frame for validation callback to refer to */
+ if (adt)
+ ked.f1 = BKE_nla_tweakedit_remap(adt, selx, NLATIME_CONVERT_UNMAP);
+ else
+ ked.f1 = selx;
+
+ /* select elements with frame number matching cfra */
+ ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
+ }
+
+ /* free elements */
+ MEM_freeN(nvi);
+ BLI_freelistN(&ked.list);
+ ANIM_animdata_freelist(&anim_data);
}
/* ------------------- */
@@ -1492,69 +1540,80 @@ static void graphkeys_mselect_column(bAnimContext *ac, const int mval[2], short
/* handle clicking */
static int graphkeys_clickselect_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- bAnimContext ac;
- short selectmode;
-
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
-
- /* select mode is either replace (deselect all, then add) or add/extend */
- if (RNA_boolean_get(op->ptr, "extend"))
- selectmode = SELECT_INVERT;
- else
- selectmode = SELECT_REPLACE;
-
- /* figure out action to take */
- if (RNA_boolean_get(op->ptr, "column")) {
- /* select all keyframes in the same frame as the one that was under the mouse */
- graphkeys_mselect_column(&ac, event->mval, selectmode);
- }
- else if (RNA_boolean_get(op->ptr, "curves")) {
- /* select all keyframes in the same F-Curve as the one under the mouse */
- mouse_graph_keys(&ac, event->mval, selectmode, 1);
- }
- else {
- /* select keyframe under mouse */
- mouse_graph_keys(&ac, event->mval, selectmode, 0);
- }
-
- /* set notifier that keyframe selection (and also channel selection in some cases) has changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_SELECTED, NULL);
-
- /* for tweak grab to work */
- return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
+ bAnimContext ac;
+ short selectmode;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* select mode is either replace (deselect all, then add) or add/extend */
+ if (RNA_boolean_get(op->ptr, "extend"))
+ selectmode = SELECT_INVERT;
+ else
+ selectmode = SELECT_REPLACE;
+
+ /* figure out action to take */
+ if (RNA_boolean_get(op->ptr, "column")) {
+ /* select all keyframes in the same frame as the one that was under the mouse */
+ graphkeys_mselect_column(&ac, event->mval, selectmode);
+ }
+ else if (RNA_boolean_get(op->ptr, "curves")) {
+ /* select all keyframes in the same F-Curve as the one under the mouse */
+ mouse_graph_keys(&ac, event->mval, selectmode, 1);
+ }
+ else {
+ /* select keyframe under mouse */
+ mouse_graph_keys(&ac, event->mval, selectmode, 0);
+ }
+
+ /* set notifier that keyframe selection (and also channel selection in some cases) has changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_SELECTED, NULL);
+
+ /* for tweak grab to work */
+ return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
}
void GRAPH_OT_clickselect(wmOperatorType *ot)
{
- PropertyRNA *prop;
-
- /* identifiers */
- ot->name = "Select Keyframes";
- ot->idname = "GRAPH_OT_clickselect";
- ot->description = "Select keyframes by clicking on them";
-
- /* callbacks */
- ot->invoke = graphkeys_clickselect_invoke;
- ot->poll = graphop_visible_keyframes_poll;
-
- /* flags */
- ot->flag = OPTYPE_UNDO;
-
- /* properties */
- prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend Select",
- "Toggle keyframe selection instead of leaving newly selected keyframes only"); // SHIFTKEY
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
-
- prop = RNA_def_boolean(ot->srna, "column", 0, "Column Select",
- "Select all keyframes that occur on the same frame as the one under the mouse"); // ALTKEY
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
-
- prop = RNA_def_boolean(ot->srna, "curves", 0, "Only Curves",
- "Select all the keyframes in the curve"); // CTRLKEY + ALTKEY
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Select Keyframes";
+ ot->idname = "GRAPH_OT_clickselect";
+ ot->description = "Select keyframes by clicking on them";
+
+ /* callbacks */
+ ot->invoke = graphkeys_clickselect_invoke;
+ ot->poll = graphop_visible_keyframes_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
+
+ /* properties */
+ prop = RNA_def_boolean(
+ ot->srna,
+ "extend",
+ 0,
+ "Extend Select",
+ "Toggle keyframe selection instead of leaving newly selected keyframes only"); // SHIFTKEY
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+
+ prop = RNA_def_boolean(
+ ot->srna,
+ "column",
+ 0,
+ "Column Select",
+ "Select all keyframes that occur on the same frame as the one under the mouse"); // ALTKEY
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+
+ prop = RNA_def_boolean(ot->srna,
+ "curves",
+ 0,
+ "Only Curves",
+ "Select all the keyframes in the curve"); // CTRLKEY + ALTKEY
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
/* ************************************************************************** */
diff --git a/source/blender/editors/space_graph/graph_utils.c b/source/blender/editors/space_graph/graph_utils.c
index 6bef5072a78..1c3b4f1377b 100644
--- a/source/blender/editors/space_graph/graph_utils.c
+++ b/source/blender/editors/space_graph/graph_utils.c
@@ -21,7 +21,6 @@
* \ingroup spgraph
*/
-
#include <string.h>
#include <stdio.h>
#include <math.h>
@@ -39,16 +38,13 @@
#include "BKE_fcurve.h"
#include "BKE_screen.h"
-
#include "WM_api.h"
-
#include "ED_anim_api.h"
#include "ED_screen.h"
#include "UI_interface.h"
-
-#include "graph_intern.h" // own include
+#include "graph_intern.h" // own include
/* ************************************************************** */
/* Set Up Drivers Editor */
@@ -57,39 +53,39 @@
/* NOTE: Currently called from windowmanager (new drivers editor window) and RNA (mode switching) */
void ED_drivers_editor_init(bContext *C, ScrArea *sa)
{
- SpaceGraph *sipo = (SpaceGraph *)sa->spacedata.first;
-
- /* Set mode */
- sipo->mode = SIPO_MODE_DRIVERS;
-
- /* Show Properties Region (or else the settings can't be edited) */
- ARegion *ar_props = BKE_area_find_region_type(sa, RGN_TYPE_UI);
- if (ar_props) {
- UI_panel_category_active_set(ar_props, "Drivers");
-
- ar_props->flag &= ~RGN_FLAG_HIDDEN;
- /* XXX: Adjust width of this too? */
-
- ED_region_visibility_change_update(C, ar_props);
- }
- else {
- printf("%s: Couldn't find properties region for Drivers Editor - %p\n", __func__, sa);
- }
-
- /* Adjust framing in graph region */
- /* TODO: Have a way of not resetting this every time?
- * (e.g. So that switching back and forth between editors doesn't keep jumping?)
- */
- ARegion *ar_main = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
- if (ar_main) {
- /* XXX: Ideally we recenter based on the range instead... */
- ar_main->v2d.tot.xmin = -2.0f;
- ar_main->v2d.tot.ymin = -2.0f;
- ar_main->v2d.tot.xmax = 2.0f;
- ar_main->v2d.tot.ymax = 2.0f;
-
- ar_main->v2d.cur = ar_main->v2d.tot;
- }
+ SpaceGraph *sipo = (SpaceGraph *)sa->spacedata.first;
+
+ /* Set mode */
+ sipo->mode = SIPO_MODE_DRIVERS;
+
+ /* Show Properties Region (or else the settings can't be edited) */
+ ARegion *ar_props = BKE_area_find_region_type(sa, RGN_TYPE_UI);
+ if (ar_props) {
+ UI_panel_category_active_set(ar_props, "Drivers");
+
+ ar_props->flag &= ~RGN_FLAG_HIDDEN;
+ /* XXX: Adjust width of this too? */
+
+ ED_region_visibility_change_update(C, ar_props);
+ }
+ else {
+ printf("%s: Couldn't find properties region for Drivers Editor - %p\n", __func__, sa);
+ }
+
+ /* Adjust framing in graph region */
+ /* TODO: Have a way of not resetting this every time?
+ * (e.g. So that switching back and forth between editors doesn't keep jumping?)
+ */
+ ARegion *ar_main = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
+ if (ar_main) {
+ /* XXX: Ideally we recenter based on the range instead... */
+ ar_main->v2d.tot.xmin = -2.0f;
+ ar_main->v2d.tot.ymin = -2.0f;
+ ar_main->v2d.tot.xmax = 2.0f;
+ ar_main->v2d.tot.ymax = 2.0f;
+
+ ar_main->v2d.cur = ar_main->v2d.tot;
+ }
}
/* ************************************************************** */
@@ -103,25 +99,25 @@ void ED_drivers_editor_init(bContext *C, ScrArea *sa)
*/
bAnimListElem *get_active_fcurve_channel(bAnimContext *ac)
{
- ListBase anim_data = {NULL, NULL};
- int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_ACTIVE);
- size_t items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+ ListBase anim_data = {NULL, NULL};
+ int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_ACTIVE);
+ size_t items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
- /* We take the first F-Curve only, since some other ones may have had 'active' flag set
- * if they were from linked data.
- */
- if (items) {
- bAnimListElem *ale = (bAnimListElem *)anim_data.first;
+ /* We take the first F-Curve only, since some other ones may have had 'active' flag set
+ * if they were from linked data.
+ */
+ if (items) {
+ bAnimListElem *ale = (bAnimListElem *)anim_data.first;
- /* remove first item from list, then free the rest of the list and return the stored one */
- BLI_remlink(&anim_data, ale);
- ANIM_animdata_freelist(&anim_data);
+ /* remove first item from list, then free the rest of the list and return the stored one */
+ BLI_remlink(&anim_data, ale);
+ ANIM_animdata_freelist(&anim_data);
- return ale;
- }
+ return ale;
+ }
- /* no active F-Curve */
- return NULL;
+ /* no active F-Curve */
+ return NULL;
}
/* ************************************************************** */
@@ -130,171 +126,171 @@ bAnimListElem *get_active_fcurve_channel(bAnimContext *ac)
/* Check if there are any visible keyframes (for selection tools) */
bool graphop_visible_keyframes_poll(bContext *C)
{
- bAnimContext ac;
- bAnimListElem *ale;
- ListBase anim_data = {NULL, NULL};
- ScrArea *sa = CTX_wm_area(C);
- size_t items;
- int filter;
- short found = 0;
-
- /* firstly, check if in Graph Editor */
- // TODO: also check for region?
- if ((sa == NULL) || (sa->spacetype != SPACE_GRAPH))
- return 0;
-
- /* try to init Anim-Context stuff ourselves and check */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return 0;
-
- /* loop over the visible (selection doesn't matter) F-Curves, and see if they're suitable
- * stopping on the first successful match
- */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE);
- items = ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
- if (items == 0)
- return 0;
-
- for (ale = anim_data.first; ale; ale = ale->next) {
- FCurve *fcu = (FCurve *)ale->data;
-
- /* visible curves for selection must fulfill the following criteria:
- * - it has bezier keyframes
- * - F-Curve modifiers do not interfere with the result too much
- * (i.e. the modifier-control drawing check returns false)
- */
- if (fcu->bezt == NULL)
- continue;
- if (fcurve_are_keyframes_usable(fcu)) {
- found = 1;
- break;
- }
- }
-
- /* cleanup and return findings */
- ANIM_animdata_freelist(&anim_data);
- return found;
+ bAnimContext ac;
+ bAnimListElem *ale;
+ ListBase anim_data = {NULL, NULL};
+ ScrArea *sa = CTX_wm_area(C);
+ size_t items;
+ int filter;
+ short found = 0;
+
+ /* firstly, check if in Graph Editor */
+ // TODO: also check for region?
+ if ((sa == NULL) || (sa->spacetype != SPACE_GRAPH))
+ return 0;
+
+ /* try to init Anim-Context stuff ourselves and check */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return 0;
+
+ /* loop over the visible (selection doesn't matter) F-Curves, and see if they're suitable
+ * stopping on the first successful match
+ */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE);
+ items = ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+ if (items == 0)
+ return 0;
+
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ FCurve *fcu = (FCurve *)ale->data;
+
+ /* visible curves for selection must fulfill the following criteria:
+ * - it has bezier keyframes
+ * - F-Curve modifiers do not interfere with the result too much
+ * (i.e. the modifier-control drawing check returns false)
+ */
+ if (fcu->bezt == NULL)
+ continue;
+ if (fcurve_are_keyframes_usable(fcu)) {
+ found = 1;
+ break;
+ }
+ }
+
+ /* cleanup and return findings */
+ ANIM_animdata_freelist(&anim_data);
+ return found;
}
/* Check if there are any visible + editable keyframes (for editing tools) */
bool graphop_editable_keyframes_poll(bContext *C)
{
- bAnimContext ac;
- bAnimListElem *ale;
- ListBase anim_data = {NULL, NULL};
- ScrArea *sa = CTX_wm_area(C);
- size_t items;
- int filter;
- short found = 0;
-
- /* firstly, check if in Graph Editor */
- // TODO: also check for region?
- if ((sa == NULL) || (sa->spacetype != SPACE_GRAPH))
- return 0;
-
- /* try to init Anim-Context stuff ourselves and check */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return 0;
-
- /* loop over the editable F-Curves, and see if they're suitable
- * stopping on the first successful match
- */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVE_VISIBLE);
- items = ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
- if (items == 0)
- return 0;
-
- for (ale = anim_data.first; ale; ale = ale->next) {
- FCurve *fcu = (FCurve *)ale->data;
-
- /* editable curves must fulfill the following criteria:
- * - it has bezier keyframes
- * - it must not be protected from editing (this is already checked for with the edit flag
- * - F-Curve modifiers do not interfere with the result too much
- * (i.e. the modifier-control drawing check returns false)
- */
- if (fcu->bezt == NULL)
- continue;
- if (fcurve_is_keyframable(fcu)) {
- found = 1;
- break;
- }
- }
-
- /* cleanup and return findings */
- ANIM_animdata_freelist(&anim_data);
- return found;
+ bAnimContext ac;
+ bAnimListElem *ale;
+ ListBase anim_data = {NULL, NULL};
+ ScrArea *sa = CTX_wm_area(C);
+ size_t items;
+ int filter;
+ short found = 0;
+
+ /* firstly, check if in Graph Editor */
+ // TODO: also check for region?
+ if ((sa == NULL) || (sa->spacetype != SPACE_GRAPH))
+ return 0;
+
+ /* try to init Anim-Context stuff ourselves and check */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return 0;
+
+ /* loop over the editable F-Curves, and see if they're suitable
+ * stopping on the first successful match
+ */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVE_VISIBLE);
+ items = ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+ if (items == 0)
+ return 0;
+
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ FCurve *fcu = (FCurve *)ale->data;
+
+ /* editable curves must fulfill the following criteria:
+ * - it has bezier keyframes
+ * - it must not be protected from editing (this is already checked for with the edit flag
+ * - F-Curve modifiers do not interfere with the result too much
+ * (i.e. the modifier-control drawing check returns false)
+ */
+ if (fcu->bezt == NULL)
+ continue;
+ if (fcurve_is_keyframable(fcu)) {
+ found = 1;
+ break;
+ }
+ }
+
+ /* cleanup and return findings */
+ ANIM_animdata_freelist(&anim_data);
+ return found;
}
/* has active F-Curve that's editable */
bool graphop_active_fcurve_poll(bContext *C)
{
- bAnimContext ac;
- bAnimListElem *ale;
- ScrArea *sa = CTX_wm_area(C);
- bool has_fcurve = 0;
-
- /* firstly, check if in Graph Editor */
- // TODO: also check for region?
- if ((sa == NULL) || (sa->spacetype != SPACE_GRAPH))
- return 0;
-
- /* try to init Anim-Context stuff ourselves and check */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return 0;
-
- /* try to get the Active F-Curve */
- ale = get_active_fcurve_channel(&ac);
- if (ale == NULL)
- return 0;
-
- /* do we have a suitable F-Curves?
- * - For most cases, NLA Control Curves are sufficiently similar to NLA curves to serve this role too.
- * Under the hood, they are F-Curves too. The only problems which will arise here are if these need to be
- * in an Action too (but drivers would then also be affected!)
- */
- has_fcurve = ((ale->data) && ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE));
- if (has_fcurve) {
- FCurve *fcu = (FCurve *)ale->data;
- has_fcurve = (fcu->flag & FCURVE_VISIBLE) != 0;
- }
-
- /* free temp data... */
- MEM_freeN(ale);
-
- /* return success */
- return has_fcurve;
+ bAnimContext ac;
+ bAnimListElem *ale;
+ ScrArea *sa = CTX_wm_area(C);
+ bool has_fcurve = 0;
+
+ /* firstly, check if in Graph Editor */
+ // TODO: also check for region?
+ if ((sa == NULL) || (sa->spacetype != SPACE_GRAPH))
+ return 0;
+
+ /* try to init Anim-Context stuff ourselves and check */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return 0;
+
+ /* try to get the Active F-Curve */
+ ale = get_active_fcurve_channel(&ac);
+ if (ale == NULL)
+ return 0;
+
+ /* do we have a suitable F-Curves?
+ * - For most cases, NLA Control Curves are sufficiently similar to NLA curves to serve this role too.
+ * Under the hood, they are F-Curves too. The only problems which will arise here are if these need to be
+ * in an Action too (but drivers would then also be affected!)
+ */
+ has_fcurve = ((ale->data) && ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE));
+ if (has_fcurve) {
+ FCurve *fcu = (FCurve *)ale->data;
+ has_fcurve = (fcu->flag & FCURVE_VISIBLE) != 0;
+ }
+
+ /* free temp data... */
+ MEM_freeN(ale);
+
+ /* return success */
+ return has_fcurve;
}
/* has selected F-Curve that's editable */
bool graphop_selected_fcurve_poll(bContext *C)
{
- bAnimContext ac;
- ListBase anim_data = {NULL, NULL};
- ScrArea *sa = CTX_wm_area(C);
- size_t items;
- int filter;
-
- /* firstly, check if in Graph Editor */
- // TODO: also check for region?
- if ((sa == NULL) || (sa->spacetype != SPACE_GRAPH))
- return 0;
-
- /* try to init Anim-Context stuff ourselves and check */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return 0;
-
- /* get the editable + selected F-Curves, and as long as we got some, we can return
- * NOTE: curve-visible flag isn't included, otherwise selecting a curve via list to edit is too cumbersome
- */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT);
- items = ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
- if (items == 0)
- return 0;
-
- /* cleanup and return findings */
- ANIM_animdata_freelist(&anim_data);
- return 1;
+ bAnimContext ac;
+ ListBase anim_data = {NULL, NULL};
+ ScrArea *sa = CTX_wm_area(C);
+ size_t items;
+ int filter;
+
+ /* firstly, check if in Graph Editor */
+ // TODO: also check for region?
+ if ((sa == NULL) || (sa->spacetype != SPACE_GRAPH))
+ return 0;
+
+ /* try to init Anim-Context stuff ourselves and check */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return 0;
+
+ /* get the editable + selected F-Curves, and as long as we got some, we can return
+ * NOTE: curve-visible flag isn't included, otherwise selecting a curve via list to edit is too cumbersome
+ */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT);
+ items = ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+ if (items == 0)
+ return 0;
+
+ /* cleanup and return findings */
+ ANIM_animdata_freelist(&anim_data);
+ return 1;
}
/* ************************************************************** */
diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c
index 9892660c59c..d03431468d8 100644
--- a/source/blender/editors/space_graph/space_graph.c
+++ b/source/blender/editors/space_graph/space_graph.c
@@ -21,7 +21,6 @@
* \ingroup spgraph
*/
-
#include <string.h>
#include <stdio.h>
@@ -59,848 +58,865 @@
#include "UI_resources.h"
#include "UI_view2d.h"
-#include "graph_intern.h" // own include
+#include "graph_intern.h" // own include
/* ******************** manage regions ********************* */
ARegion *graph_has_buttons_region(ScrArea *sa)
{
- ARegion *ar, *arnew;
+ ARegion *ar, *arnew;
- ar = BKE_area_find_region_type(sa, RGN_TYPE_UI);
- if (ar) return ar;
+ ar = BKE_area_find_region_type(sa, RGN_TYPE_UI);
+ if (ar)
+ return ar;
- /* add subdiv level; after main */
- ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
+ /* add subdiv level; after main */
+ ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
- /* is error! */
- if (ar == NULL) return NULL;
+ /* is error! */
+ if (ar == NULL)
+ return NULL;
- arnew = MEM_callocN(sizeof(ARegion), "buttons for graph");
+ arnew = MEM_callocN(sizeof(ARegion), "buttons for graph");
- BLI_insertlinkafter(&sa->regionbase, ar, arnew);
- arnew->regiontype = RGN_TYPE_UI;
- arnew->alignment = RGN_ALIGN_RIGHT;
+ BLI_insertlinkafter(&sa->regionbase, ar, arnew);
+ arnew->regiontype = RGN_TYPE_UI;
+ arnew->alignment = RGN_ALIGN_RIGHT;
- arnew->flag = RGN_FLAG_HIDDEN;
+ arnew->flag = RGN_FLAG_HIDDEN;
- return arnew;
+ return arnew;
}
-
/* ******************** default callbacks for ipo space ***************** */
static SpaceLink *graph_new(const ScrArea *UNUSED(sa), const Scene *scene)
{
- ARegion *ar;
- SpaceGraph *sipo;
+ ARegion *ar;
+ SpaceGraph *sipo;
- /* Graph Editor - general stuff */
- sipo = MEM_callocN(sizeof(SpaceGraph), "init graphedit");
- sipo->spacetype = SPACE_GRAPH;
+ /* Graph Editor - general stuff */
+ sipo = MEM_callocN(sizeof(SpaceGraph), "init graphedit");
+ sipo->spacetype = SPACE_GRAPH;
- sipo->autosnap = SACTSNAP_FRAME;
+ sipo->autosnap = SACTSNAP_FRAME;
- /* allocate DopeSheet data for Graph Editor */
- sipo->ads = MEM_callocN(sizeof(bDopeSheet), "GraphEdit DopeSheet");
- sipo->ads->source = (ID *)scene;
+ /* allocate DopeSheet data for Graph Editor */
+ sipo->ads = MEM_callocN(sizeof(bDopeSheet), "GraphEdit DopeSheet");
+ sipo->ads->source = (ID *)scene;
- /* settings for making it easier by default to just see what you're interested in tweaking */
- sipo->ads->filterflag |= ADS_FILTER_ONLYSEL;
- sipo->flag |= SIPO_SELVHANDLESONLY;
+ /* settings for making it easier by default to just see what you're interested in tweaking */
+ sipo->ads->filterflag |= ADS_FILTER_ONLYSEL;
+ sipo->flag |= SIPO_SELVHANDLESONLY;
- /* header */
- ar = MEM_callocN(sizeof(ARegion), "header for graphedit");
+ /* header */
+ ar = MEM_callocN(sizeof(ARegion), "header for graphedit");
- BLI_addtail(&sipo->regionbase, ar);
- ar->regiontype = RGN_TYPE_HEADER;
- ar->alignment = (U.uiflag & USER_HEADER_BOTTOM) ? RGN_ALIGN_BOTTOM : RGN_ALIGN_TOP;
+ BLI_addtail(&sipo->regionbase, ar);
+ ar->regiontype = RGN_TYPE_HEADER;
+ ar->alignment = (U.uiflag & USER_HEADER_BOTTOM) ? RGN_ALIGN_BOTTOM : RGN_ALIGN_TOP;
- /* channels */
- ar = MEM_callocN(sizeof(ARegion), "channels region for graphedit");
+ /* channels */
+ ar = MEM_callocN(sizeof(ARegion), "channels region for graphedit");
- BLI_addtail(&sipo->regionbase, ar);
- ar->regiontype = RGN_TYPE_CHANNELS;
- ar->alignment = RGN_ALIGN_LEFT;
+ BLI_addtail(&sipo->regionbase, ar);
+ ar->regiontype = RGN_TYPE_CHANNELS;
+ ar->alignment = RGN_ALIGN_LEFT;
- ar->v2d.scroll = (V2D_SCROLL_RIGHT | V2D_SCROLL_BOTTOM);
+ ar->v2d.scroll = (V2D_SCROLL_RIGHT | V2D_SCROLL_BOTTOM);
- /* ui buttons */
- ar = MEM_callocN(sizeof(ARegion), "buttons region for graphedit");
+ /* ui buttons */
+ ar = MEM_callocN(sizeof(ARegion), "buttons region for graphedit");
- BLI_addtail(&sipo->regionbase, ar);
- ar->regiontype = RGN_TYPE_UI;
- ar->alignment = RGN_ALIGN_RIGHT;
- ar->flag = RGN_FLAG_HIDDEN;
+ BLI_addtail(&sipo->regionbase, ar);
+ ar->regiontype = RGN_TYPE_UI;
+ ar->alignment = RGN_ALIGN_RIGHT;
+ ar->flag = RGN_FLAG_HIDDEN;
- /* main region */
- ar = MEM_callocN(sizeof(ARegion), "main region for graphedit");
+ /* main region */
+ ar = MEM_callocN(sizeof(ARegion), "main region for graphedit");
- BLI_addtail(&sipo->regionbase, ar);
- ar->regiontype = RGN_TYPE_WINDOW;
+ BLI_addtail(&sipo->regionbase, ar);
+ ar->regiontype = RGN_TYPE_WINDOW;
- ar->v2d.tot.xmin = 0.0f;
- ar->v2d.tot.ymin = (float)scene->r.sfra - 10.0f;
- ar->v2d.tot.xmax = (float)scene->r.efra;
- ar->v2d.tot.ymax = 10.0f;
+ ar->v2d.tot.xmin = 0.0f;
+ ar->v2d.tot.ymin = (float)scene->r.sfra - 10.0f;
+ ar->v2d.tot.xmax = (float)scene->r.efra;
+ ar->v2d.tot.ymax = 10.0f;
- ar->v2d.cur = ar->v2d.tot;
+ ar->v2d.cur = ar->v2d.tot;
- ar->v2d.min[0] = FLT_MIN;
- ar->v2d.min[1] = FLT_MIN;
+ ar->v2d.min[0] = FLT_MIN;
+ ar->v2d.min[1] = FLT_MIN;
- ar->v2d.max[0] = MAXFRAMEF;
- ar->v2d.max[1] = FLT_MAX;
+ ar->v2d.max[0] = MAXFRAMEF;
+ ar->v2d.max[1] = FLT_MAX;
- ar->v2d.scroll = (V2D_SCROLL_BOTTOM | V2D_SCROLL_SCALE_HORIZONTAL);
- ar->v2d.scroll |= (V2D_SCROLL_LEFT | V2D_SCROLL_SCALE_VERTICAL);
+ ar->v2d.scroll = (V2D_SCROLL_BOTTOM | V2D_SCROLL_SCALE_HORIZONTAL);
+ ar->v2d.scroll |= (V2D_SCROLL_LEFT | V2D_SCROLL_SCALE_VERTICAL);
- ar->v2d.keeptot = 0;
+ ar->v2d.keeptot = 0;
- return (SpaceLink *)sipo;
+ return (SpaceLink *)sipo;
}
/* not spacelink itself */
static void graph_free(SpaceLink *sl)
{
- SpaceGraph *si = (SpaceGraph *)sl;
+ SpaceGraph *si = (SpaceGraph *)sl;
- if (si->ads) {
- BLI_freelistN(&si->ads->chanbase);
- MEM_freeN(si->ads);
- }
+ if (si->ads) {
+ BLI_freelistN(&si->ads->chanbase);
+ MEM_freeN(si->ads);
+ }
- if (si->runtime.ghost_curves.first) {
- free_fcurves(&si->runtime.ghost_curves);
- }
+ if (si->runtime.ghost_curves.first) {
+ free_fcurves(&si->runtime.ghost_curves);
+ }
}
-
/* spacetype; init callback */
static void graph_init(struct wmWindowManager *wm, ScrArea *sa)
{
- SpaceGraph *sipo = (SpaceGraph *)sa->spacedata.first;
-
- /* init dopesheet data if non-existent (i.e. for old files) */
- if (sipo->ads == NULL) {
- sipo->ads = MEM_callocN(sizeof(bDopeSheet), "GraphEdit DopeSheet");
- sipo->ads->source = (ID *)WM_window_get_active_scene(wm->winactive);
- }
-
- /* force immediate init of any invalid F-Curve colors */
- /* XXX: but, don't do SIPO_TEMP_NEEDCHANSYNC (i.e. channel select state sync)
- * as this is run on each region resize; setting this here will cause selection
- * state to be lost on area/region resizing. [#35744]
- */
- ED_area_tag_refresh(sa);
+ SpaceGraph *sipo = (SpaceGraph *)sa->spacedata.first;
+
+ /* init dopesheet data if non-existent (i.e. for old files) */
+ if (sipo->ads == NULL) {
+ sipo->ads = MEM_callocN(sizeof(bDopeSheet), "GraphEdit DopeSheet");
+ sipo->ads->source = (ID *)WM_window_get_active_scene(wm->winactive);
+ }
+
+ /* force immediate init of any invalid F-Curve colors */
+ /* XXX: but, don't do SIPO_TEMP_NEEDCHANSYNC (i.e. channel select state sync)
+ * as this is run on each region resize; setting this here will cause selection
+ * state to be lost on area/region resizing. [#35744]
+ */
+ ED_area_tag_refresh(sa);
}
static SpaceLink *graph_duplicate(SpaceLink *sl)
{
- SpaceGraph *sipon = MEM_dupallocN(sl);
+ SpaceGraph *sipon = MEM_dupallocN(sl);
- /* clear or remove stuff from old */
- BLI_duplicatelist(&sipon->runtime.ghost_curves, &((SpaceGraph *)sl)->runtime.ghost_curves);
- sipon->ads = MEM_dupallocN(sipon->ads);
+ /* clear or remove stuff from old */
+ BLI_duplicatelist(&sipon->runtime.ghost_curves, &((SpaceGraph *)sl)->runtime.ghost_curves);
+ sipon->ads = MEM_dupallocN(sipon->ads);
- return (SpaceLink *)sipon;
+ return (SpaceLink *)sipon;
}
/* add handlers, stuff you only do once or on area/region changes */
static void graph_main_region_init(wmWindowManager *wm, ARegion *ar)
{
- wmKeyMap *keymap;
+ wmKeyMap *keymap;
- UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy);
+ UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy);
- /* own keymap */
- keymap = WM_keymap_ensure(wm->defaultconf, "Graph Editor", SPACE_GRAPH, 0);
- WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
- keymap = WM_keymap_ensure(wm->defaultconf, "Graph Editor Generic", SPACE_GRAPH, 0);
- WM_event_add_keymap_handler(&ar->handlers, keymap);
+ /* own keymap */
+ keymap = WM_keymap_ensure(wm->defaultconf, "Graph Editor", SPACE_GRAPH, 0);
+ WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
+ keymap = WM_keymap_ensure(wm->defaultconf, "Graph Editor Generic", SPACE_GRAPH, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
}
static void graph_main_region_draw(const bContext *C, ARegion *ar)
{
- /* draw entirely, view changes should be handled here */
- SpaceGraph *sipo = CTX_wm_space_graph(C);
- Scene *scene = CTX_data_scene(C);
- bAnimContext ac;
- View2D *v2d = &ar->v2d;
- View2DGrid *grid;
- View2DScrollers *scrollers;
- float col[3];
- short unitx = 0, unity = V2D_UNIT_VALUES, cfra_flag = 0;
-
- /* clear and setup matrix */
- UI_GetThemeColor3fv(TH_BACK, col);
- GPU_clear_color(col[0], col[1], col[2], 0.0);
- GPU_clear(GPU_COLOR_BIT);
-
- UI_view2d_view_ortho(v2d);
-
- /* grid */
- unitx = ((sipo->mode == SIPO_MODE_ANIMATION) && (sipo->flag & SIPO_DRAWTIME)) ? V2D_UNIT_SECONDS : V2D_UNIT_FRAMESCALE;
- grid = UI_view2d_grid_calc(CTX_data_scene(C), v2d, unitx, V2D_GRID_NOCLAMP, unity, V2D_GRID_NOCLAMP, ar->winx, ar->winy);
- UI_view2d_grid_draw(v2d, grid, V2D_GRIDLINES_ALL);
-
- ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW);
-
- /* start and end frame (in F-Curve mode only) */
- if (sipo->mode != SIPO_MODE_DRIVERS) {
- ANIM_draw_framerange(scene, v2d);
- }
-
- /* draw data */
- if (ANIM_animdata_get_context(C, &ac)) {
- /* draw ghost curves */
- graph_draw_ghost_curves(&ac, sipo, ar);
-
- /* draw curves twice - unselected, then selected, so that the are fewer occlusion problems */
- graph_draw_curves(&ac, sipo, ar, grid, 0);
- graph_draw_curves(&ac, sipo, ar, grid, 1);
-
- /* XXX the slow way to set tot rect... but for nice sliders needed (ton) */
- get_graph_keyframe_extents(&ac, &v2d->tot.xmin, &v2d->tot.xmax, &v2d->tot.ymin, &v2d->tot.ymax, false, true);
- /* extra offset so that these items are visible */
- v2d->tot.xmin -= 10.0f;
- v2d->tot.xmax += 10.0f;
- }
-
- /* only free grid after drawing data, as we need to use it to determine sampling rate */
- UI_view2d_grid_free(grid);
-
- if (((sipo->flag & SIPO_NODRAWCURSOR) == 0) || (sipo->mode == SIPO_MODE_DRIVERS)) {
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
-
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
-
- /* horizontal component of value-cursor (value line before the current frame line) */
- if ((sipo->flag & SIPO_NODRAWCURSOR) == 0) {
- float y = sipo->cursorVal;
-
- /* Draw a green line to indicate the cursor value */
- immUniformThemeColorShadeAlpha(TH_CFRAME, -10, -50);
- GPU_blend(true);
- GPU_line_width(2.0);
-
- immBegin(GPU_PRIM_LINES, 2);
- immVertex2f(pos, v2d->cur.xmin, y);
- immVertex2f(pos, v2d->cur.xmax, y);
- immEnd();
-
- GPU_blend(false);
- }
-
- /* current frame or vertical component of vertical component of the cursor */
- if (sipo->mode == SIPO_MODE_DRIVERS) {
- /* cursor x-value */
- float x = sipo->cursorTime;
-
- /* to help differentiate this from the current frame,
- * draw slightly darker like the horizontal one */
- immUniformThemeColorShadeAlpha(TH_CFRAME, -40, -50);
- GPU_blend(true);
- GPU_line_width(2.0);
-
- immBegin(GPU_PRIM_LINES, 2);
- immVertex2f(pos, x, v2d->cur.ymin);
- immVertex2f(pos, x, v2d->cur.ymax);
- immEnd();
-
- GPU_blend(false);
- }
-
- immUnbindProgram();
- }
-
- if (sipo->mode != SIPO_MODE_DRIVERS) {
- /* current frame */
- if (sipo->flag & SIPO_DRAWTIME) cfra_flag |= DRAWCFRA_UNIT_SECONDS;
- ANIM_draw_cfra(C, v2d, cfra_flag);
- }
-
- /* markers */
- UI_view2d_view_orthoSpecial(ar, v2d, 1);
- int marker_draw_flag = DRAW_MARKERS_MARGIN;
- if (sipo->flag & SIPO_MARKER_LINES) {
- marker_draw_flag |= DRAW_MARKERS_LINES;
- }
- ED_markers_draw(C, marker_draw_flag);
-
- /* preview range */
- UI_view2d_view_ortho(v2d);
- ANIM_draw_previewrange(C, v2d, 0);
-
- /* callback */
- UI_view2d_view_ortho(v2d);
- ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
-
- /* reset view matrix */
- UI_view2d_view_restore(C);
-
- /* scrollers */
- // FIXME: args for scrollers depend on the type of data being shown...
- scrollers = UI_view2d_scrollers_calc(C, v2d, NULL, unitx, V2D_GRID_NOCLAMP, unity, V2D_GRID_NOCLAMP);
- UI_view2d_scrollers_draw(C, v2d, scrollers);
- UI_view2d_scrollers_free(scrollers);
-
- /* draw current frame number-indicator on top of scrollers */
- if ((sipo->mode != SIPO_MODE_DRIVERS) && ((sipo->flag & SIPO_NODRAWCFRANUM) == 0)) {
- UI_view2d_view_orthoSpecial(ar, v2d, 1);
- ANIM_draw_cfra_number(C, v2d, cfra_flag);
- }
+ /* draw entirely, view changes should be handled here */
+ SpaceGraph *sipo = CTX_wm_space_graph(C);
+ Scene *scene = CTX_data_scene(C);
+ bAnimContext ac;
+ View2D *v2d = &ar->v2d;
+ View2DGrid *grid;
+ View2DScrollers *scrollers;
+ float col[3];
+ short unitx = 0, unity = V2D_UNIT_VALUES, cfra_flag = 0;
+
+ /* clear and setup matrix */
+ UI_GetThemeColor3fv(TH_BACK, col);
+ GPU_clear_color(col[0], col[1], col[2], 0.0);
+ GPU_clear(GPU_COLOR_BIT);
+
+ UI_view2d_view_ortho(v2d);
+
+ /* grid */
+ unitx = ((sipo->mode == SIPO_MODE_ANIMATION) && (sipo->flag & SIPO_DRAWTIME)) ?
+ V2D_UNIT_SECONDS :
+ V2D_UNIT_FRAMESCALE;
+ grid = UI_view2d_grid_calc(CTX_data_scene(C),
+ v2d,
+ unitx,
+ V2D_GRID_NOCLAMP,
+ unity,
+ V2D_GRID_NOCLAMP,
+ ar->winx,
+ ar->winy);
+ UI_view2d_grid_draw(v2d, grid, V2D_GRIDLINES_ALL);
+
+ ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW);
+
+ /* start and end frame (in F-Curve mode only) */
+ if (sipo->mode != SIPO_MODE_DRIVERS) {
+ ANIM_draw_framerange(scene, v2d);
+ }
+
+ /* draw data */
+ if (ANIM_animdata_get_context(C, &ac)) {
+ /* draw ghost curves */
+ graph_draw_ghost_curves(&ac, sipo, ar);
+
+ /* draw curves twice - unselected, then selected, so that the are fewer occlusion problems */
+ graph_draw_curves(&ac, sipo, ar, grid, 0);
+ graph_draw_curves(&ac, sipo, ar, grid, 1);
+
+ /* XXX the slow way to set tot rect... but for nice sliders needed (ton) */
+ get_graph_keyframe_extents(
+ &ac, &v2d->tot.xmin, &v2d->tot.xmax, &v2d->tot.ymin, &v2d->tot.ymax, false, true);
+ /* extra offset so that these items are visible */
+ v2d->tot.xmin -= 10.0f;
+ v2d->tot.xmax += 10.0f;
+ }
+
+ /* only free grid after drawing data, as we need to use it to determine sampling rate */
+ UI_view2d_grid_free(grid);
+
+ if (((sipo->flag & SIPO_NODRAWCURSOR) == 0) || (sipo->mode == SIPO_MODE_DRIVERS)) {
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ /* horizontal component of value-cursor (value line before the current frame line) */
+ if ((sipo->flag & SIPO_NODRAWCURSOR) == 0) {
+ float y = sipo->cursorVal;
+
+ /* Draw a green line to indicate the cursor value */
+ immUniformThemeColorShadeAlpha(TH_CFRAME, -10, -50);
+ GPU_blend(true);
+ GPU_line_width(2.0);
+
+ immBegin(GPU_PRIM_LINES, 2);
+ immVertex2f(pos, v2d->cur.xmin, y);
+ immVertex2f(pos, v2d->cur.xmax, y);
+ immEnd();
+
+ GPU_blend(false);
+ }
+
+ /* current frame or vertical component of vertical component of the cursor */
+ if (sipo->mode == SIPO_MODE_DRIVERS) {
+ /* cursor x-value */
+ float x = sipo->cursorTime;
+
+ /* to help differentiate this from the current frame,
+ * draw slightly darker like the horizontal one */
+ immUniformThemeColorShadeAlpha(TH_CFRAME, -40, -50);
+ GPU_blend(true);
+ GPU_line_width(2.0);
+
+ immBegin(GPU_PRIM_LINES, 2);
+ immVertex2f(pos, x, v2d->cur.ymin);
+ immVertex2f(pos, x, v2d->cur.ymax);
+ immEnd();
+
+ GPU_blend(false);
+ }
+
+ immUnbindProgram();
+ }
+
+ if (sipo->mode != SIPO_MODE_DRIVERS) {
+ /* current frame */
+ if (sipo->flag & SIPO_DRAWTIME)
+ cfra_flag |= DRAWCFRA_UNIT_SECONDS;
+ ANIM_draw_cfra(C, v2d, cfra_flag);
+ }
+
+ /* markers */
+ UI_view2d_view_orthoSpecial(ar, v2d, 1);
+ int marker_draw_flag = DRAW_MARKERS_MARGIN;
+ if (sipo->flag & SIPO_MARKER_LINES) {
+ marker_draw_flag |= DRAW_MARKERS_LINES;
+ }
+ ED_markers_draw(C, marker_draw_flag);
+
+ /* preview range */
+ UI_view2d_view_ortho(v2d);
+ ANIM_draw_previewrange(C, v2d, 0);
+
+ /* callback */
+ UI_view2d_view_ortho(v2d);
+ ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
+
+ /* reset view matrix */
+ UI_view2d_view_restore(C);
+
+ /* scrollers */
+ // FIXME: args for scrollers depend on the type of data being shown...
+ scrollers = UI_view2d_scrollers_calc(
+ C, v2d, NULL, unitx, V2D_GRID_NOCLAMP, unity, V2D_GRID_NOCLAMP);
+ UI_view2d_scrollers_draw(C, v2d, scrollers);
+ UI_view2d_scrollers_free(scrollers);
+
+ /* draw current frame number-indicator on top of scrollers */
+ if ((sipo->mode != SIPO_MODE_DRIVERS) && ((sipo->flag & SIPO_NODRAWCFRANUM) == 0)) {
+ UI_view2d_view_orthoSpecial(ar, v2d, 1);
+ ANIM_draw_cfra_number(C, v2d, cfra_flag);
+ }
}
static void graph_channel_region_init(wmWindowManager *wm, ARegion *ar)
{
- wmKeyMap *keymap;
+ wmKeyMap *keymap;
- /* make sure we keep the hide flags */
- ar->v2d.scroll |= V2D_SCROLL_RIGHT;
+ /* make sure we keep the hide flags */
+ ar->v2d.scroll |= V2D_SCROLL_RIGHT;
- /* prevent any noise of past */
- ar->v2d.scroll &= ~(V2D_SCROLL_LEFT | V2D_SCROLL_TOP | V2D_SCROLL_BOTTOM);
+ /* prevent any noise of past */
+ ar->v2d.scroll &= ~(V2D_SCROLL_LEFT | V2D_SCROLL_TOP | V2D_SCROLL_BOTTOM);
- ar->v2d.scroll |= V2D_SCROLL_HORIZONTAL_HIDE;
- ar->v2d.scroll |= V2D_SCROLL_VERTICAL_HIDE;
+ ar->v2d.scroll |= V2D_SCROLL_HORIZONTAL_HIDE;
+ ar->v2d.scroll |= V2D_SCROLL_VERTICAL_HIDE;
- UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy);
+ UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy);
- /* own keymap */
- keymap = WM_keymap_ensure(wm->defaultconf, "Animation Channels", 0, 0);
- WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
- keymap = WM_keymap_ensure(wm->defaultconf, "Graph Editor Generic", SPACE_GRAPH, 0);
- WM_event_add_keymap_handler(&ar->handlers, keymap);
+ /* own keymap */
+ keymap = WM_keymap_ensure(wm->defaultconf, "Animation Channels", 0, 0);
+ WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
+ keymap = WM_keymap_ensure(wm->defaultconf, "Graph Editor Generic", SPACE_GRAPH, 0);
+ WM_event_add_keymap_handler(&ar->handlers, keymap);
}
static void graph_channel_region_draw(const bContext *C, ARegion *ar)
{
- bAnimContext ac;
- View2D *v2d = &ar->v2d;
- View2DScrollers *scrollers;
- float col[3];
-
- /* clear and setup matrix */
- UI_GetThemeColor3fv(TH_BACK, col);
- GPU_clear_color(col[0], col[1], col[2], 0.0);
- GPU_clear(GPU_COLOR_BIT);
-
- UI_view2d_view_ortho(v2d);
-
- /* draw channels */
- if (ANIM_animdata_get_context(C, &ac)) {
- graph_draw_channel_names((bContext *)C, &ac, ar);
- }
-
- /* reset view matrix */
- UI_view2d_view_restore(C);
-
- /* scrollers */
- scrollers = UI_view2d_scrollers_calc(C, v2d, NULL, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
- UI_view2d_scrollers_draw(C, v2d, scrollers);
- UI_view2d_scrollers_free(scrollers);
+ bAnimContext ac;
+ View2D *v2d = &ar->v2d;
+ View2DScrollers *scrollers;
+ float col[3];
+
+ /* clear and setup matrix */
+ UI_GetThemeColor3fv(TH_BACK, col);
+ GPU_clear_color(col[0], col[1], col[2], 0.0);
+ GPU_clear(GPU_COLOR_BIT);
+
+ UI_view2d_view_ortho(v2d);
+
+ /* draw channels */
+ if (ANIM_animdata_get_context(C, &ac)) {
+ graph_draw_channel_names((bContext *)C, &ac, ar);
+ }
+
+ /* reset view matrix */
+ UI_view2d_view_restore(C);
+
+ /* scrollers */
+ scrollers = UI_view2d_scrollers_calc(
+ C, v2d, NULL, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
+ UI_view2d_scrollers_draw(C, v2d, scrollers);
+ UI_view2d_scrollers_free(scrollers);
}
/* add handlers, stuff you only do once or on area/region changes */
static void graph_header_region_init(wmWindowManager *UNUSED(wm), ARegion *ar)
{
- ED_region_header_init(ar);
+ ED_region_header_init(ar);
}
static void graph_header_region_draw(const bContext *C, ARegion *ar)
{
- ED_region_header(C, ar);
+ ED_region_header(C, ar);
}
/* add handlers, stuff you only do once or on area/region changes */
static void graph_buttons_region_init(wmWindowManager *wm, ARegion *ar)
{
- wmKeyMap *keymap;
+ wmKeyMap *keymap;
- ED_region_panels_init(wm, ar);
+ ED_region_panels_init(wm, ar);
- keymap = WM_keymap_ensure(wm->defaultconf, "Graph Editor Generic", SPACE_GRAPH, 0);
- WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
+ keymap = WM_keymap_ensure(wm->defaultconf, "Graph Editor Generic", SPACE_GRAPH, 0);
+ WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
}
static void graph_buttons_region_draw(const bContext *C, ARegion *ar)
{
- ED_region_panels(C, ar);
+ ED_region_panels(C, ar);
}
-static void graph_region_listener(
- wmWindow *UNUSED(win), ScrArea *UNUSED(sa), ARegion *ar,
- wmNotifier *wmn, const Scene *UNUSED(scene))
+static void graph_region_listener(wmWindow *UNUSED(win),
+ ScrArea *UNUSED(sa),
+ ARegion *ar,
+ wmNotifier *wmn,
+ const Scene *UNUSED(scene))
{
- /* context changes */
- switch (wmn->category) {
- case NC_ANIMATION:
- ED_region_tag_redraw(ar);
- break;
- case NC_SCENE:
- switch (wmn->data) {
- case ND_RENDER_OPTIONS:
- case ND_OB_ACTIVE:
- case ND_FRAME:
- case ND_FRAME_RANGE:
- case ND_MARKERS:
- ED_region_tag_redraw(ar);
- break;
- case ND_SEQUENCER:
- if (wmn->action == NA_SELECTED)
- ED_region_tag_redraw(ar);
- break;
- }
- break;
- case NC_OBJECT:
- switch (wmn->data) {
- case ND_BONE_ACTIVE:
- case ND_BONE_SELECT:
- case ND_KEYS:
- ED_region_tag_redraw(ar);
- break;
- case ND_MODIFIER:
- if (wmn->action == NA_RENAME)
- ED_region_tag_redraw(ar);
- break;
- }
- break;
- case NC_NODE:
- switch (wmn->action) {
- case NA_EDITED:
- case NA_SELECTED:
- ED_region_tag_redraw(ar);
- break;
- }
- break;
- case NC_ID:
- if (wmn->action == NA_RENAME)
- ED_region_tag_redraw(ar);
- break;
- case NC_SCREEN:
- if (ELEM(wmn->data, ND_LAYER)) {
- ED_region_tag_redraw(ar);
- }
- break;
- default:
- if (wmn->data == ND_KEYS)
- ED_region_tag_redraw(ar);
- break;
-
- }
+ /* context changes */
+ switch (wmn->category) {
+ case NC_ANIMATION:
+ ED_region_tag_redraw(ar);
+ break;
+ case NC_SCENE:
+ switch (wmn->data) {
+ case ND_RENDER_OPTIONS:
+ case ND_OB_ACTIVE:
+ case ND_FRAME:
+ case ND_FRAME_RANGE:
+ case ND_MARKERS:
+ ED_region_tag_redraw(ar);
+ break;
+ case ND_SEQUENCER:
+ if (wmn->action == NA_SELECTED)
+ ED_region_tag_redraw(ar);
+ break;
+ }
+ break;
+ case NC_OBJECT:
+ switch (wmn->data) {
+ case ND_BONE_ACTIVE:
+ case ND_BONE_SELECT:
+ case ND_KEYS:
+ ED_region_tag_redraw(ar);
+ break;
+ case ND_MODIFIER:
+ if (wmn->action == NA_RENAME)
+ ED_region_tag_redraw(ar);
+ break;
+ }
+ break;
+ case NC_NODE:
+ switch (wmn->action) {
+ case NA_EDITED:
+ case NA_SELECTED:
+ ED_region_tag_redraw(ar);
+ break;
+ }
+ break;
+ case NC_ID:
+ if (wmn->action == NA_RENAME)
+ ED_region_tag_redraw(ar);
+ break;
+ case NC_SCREEN:
+ if (ELEM(wmn->data, ND_LAYER)) {
+ ED_region_tag_redraw(ar);
+ }
+ break;
+ default:
+ if (wmn->data == ND_KEYS)
+ ED_region_tag_redraw(ar);
+ break;
+ }
}
-static void graph_region_message_subscribe(
- const struct bContext *UNUSED(C),
- struct WorkSpace *UNUSED(workspace), struct Scene *scene,
- struct bScreen *screen, struct ScrArea *sa, struct ARegion *ar,
- struct wmMsgBus *mbus)
+static void graph_region_message_subscribe(const struct bContext *UNUSED(C),
+ struct WorkSpace *UNUSED(workspace),
+ struct Scene *scene,
+ struct bScreen *screen,
+ struct ScrArea *sa,
+ struct ARegion *ar,
+ struct wmMsgBus *mbus)
{
- PointerRNA ptr;
- RNA_pointer_create(&screen->id, &RNA_SpaceGraphEditor, sa->spacedata.first, &ptr);
-
- wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
- .owner = ar,
- .user_data = ar,
- .notify = ED_region_do_msg_notify_tag_redraw,
- };
-
- /* Timeline depends on scene properties. */
- {
- bool use_preview = (scene->r.flag & SCER_PRV_RANGE);
- extern PropertyRNA rna_Scene_frame_start;
- extern PropertyRNA rna_Scene_frame_end;
- extern PropertyRNA rna_Scene_frame_preview_start;
- extern PropertyRNA rna_Scene_frame_preview_end;
- extern PropertyRNA rna_Scene_use_preview_range;
- extern PropertyRNA rna_Scene_frame_current;
- const PropertyRNA *props[] = {
- use_preview ? &rna_Scene_frame_preview_start : &rna_Scene_frame_start,
- use_preview ? &rna_Scene_frame_preview_end : &rna_Scene_frame_end,
- &rna_Scene_use_preview_range,
- &rna_Scene_frame_current,
- };
-
- PointerRNA idptr;
- RNA_id_pointer_create(&scene->id, &idptr);
-
- for (int i = 0; i < ARRAY_SIZE(props); i++) {
- WM_msg_subscribe_rna(mbus, &idptr, props[i], &msg_sub_value_region_tag_redraw, __func__);
- }
- }
-
- /* All dopesheet filter settings, etc. affect the drawing of this editor,
- * also same applies for all animation-related datatypes that may appear here,
- * so just whitelist the entire structs for updates
- */
- {
- wmMsgParams_RNA msg_key_params = {{{0}}};
- StructRNA *type_array[] = {
- &RNA_DopeSheet, /* dopesheet filters */
-
- &RNA_ActionGroup, /* channel groups */
- &RNA_FCurve, /* F-Curve */
- &RNA_Keyframe,
- &RNA_FCurveSample,
-
- &RNA_FModifier, /* F-Modifiers (XXX: Why can't we just do all subclasses too?) */
- &RNA_FModifierCycles,
- &RNA_FModifierEnvelope,
- &RNA_FModifierEnvelopeControlPoint,
- &RNA_FModifierFunctionGenerator,
- &RNA_FModifierGenerator,
- &RNA_FModifierLimits,
- &RNA_FModifierNoise,
- &RNA_FModifierPython,
- &RNA_FModifierStepped,
- };
-
- for (int i = 0; i < ARRAY_SIZE(type_array); i++) {
- msg_key_params.ptr.type = type_array[i];
- WM_msg_subscribe_rna_params(
- mbus,
- &msg_key_params,
- &msg_sub_value_region_tag_redraw,
- __func__);
- }
- }
+ PointerRNA ptr;
+ RNA_pointer_create(&screen->id, &RNA_SpaceGraphEditor, sa->spacedata.first, &ptr);
+
+ wmMsgSubscribeValue msg_sub_value_region_tag_redraw = {
+ .owner = ar,
+ .user_data = ar,
+ .notify = ED_region_do_msg_notify_tag_redraw,
+ };
+
+ /* Timeline depends on scene properties. */
+ {
+ bool use_preview = (scene->r.flag & SCER_PRV_RANGE);
+ extern PropertyRNA rna_Scene_frame_start;
+ extern PropertyRNA rna_Scene_frame_end;
+ extern PropertyRNA rna_Scene_frame_preview_start;
+ extern PropertyRNA rna_Scene_frame_preview_end;
+ extern PropertyRNA rna_Scene_use_preview_range;
+ extern PropertyRNA rna_Scene_frame_current;
+ const PropertyRNA *props[] = {
+ use_preview ? &rna_Scene_frame_preview_start : &rna_Scene_frame_start,
+ use_preview ? &rna_Scene_frame_preview_end : &rna_Scene_frame_end,
+ &rna_Scene_use_preview_range,
+ &rna_Scene_frame_current,
+ };
+
+ PointerRNA idptr;
+ RNA_id_pointer_create(&scene->id, &idptr);
+
+ for (int i = 0; i < ARRAY_SIZE(props); i++) {
+ WM_msg_subscribe_rna(mbus, &idptr, props[i], &msg_sub_value_region_tag_redraw, __func__);
+ }
+ }
+
+ /* All dopesheet filter settings, etc. affect the drawing of this editor,
+ * also same applies for all animation-related datatypes that may appear here,
+ * so just whitelist the entire structs for updates
+ */
+ {
+ wmMsgParams_RNA msg_key_params = {{{0}}};
+ StructRNA *type_array[] = {
+ &RNA_DopeSheet, /* dopesheet filters */
+
+ &RNA_ActionGroup, /* channel groups */
+ &RNA_FCurve, /* F-Curve */
+ &RNA_Keyframe,
+ &RNA_FCurveSample,
+
+ &RNA_FModifier, /* F-Modifiers (XXX: Why can't we just do all subclasses too?) */
+ &RNA_FModifierCycles,
+ &RNA_FModifierEnvelope,
+ &RNA_FModifierEnvelopeControlPoint,
+ &RNA_FModifierFunctionGenerator,
+ &RNA_FModifierGenerator,
+ &RNA_FModifierLimits,
+ &RNA_FModifierNoise,
+ &RNA_FModifierPython,
+ &RNA_FModifierStepped,
+ };
+
+ for (int i = 0; i < ARRAY_SIZE(type_array); i++) {
+ msg_key_params.ptr.type = type_array[i];
+ WM_msg_subscribe_rna_params(
+ mbus, &msg_key_params, &msg_sub_value_region_tag_redraw, __func__);
+ }
+ }
}
/* editor level listener */
-static void graph_listener(wmWindow *UNUSED(win), ScrArea *sa, wmNotifier *wmn, Scene *UNUSED(scene))
+static void graph_listener(wmWindow *UNUSED(win),
+ ScrArea *sa,
+ wmNotifier *wmn,
+ Scene *UNUSED(scene))
{
- SpaceGraph *sipo = (SpaceGraph *)sa->spacedata.first;
-
- /* context changes */
- switch (wmn->category) {
- case NC_ANIMATION:
- /* for selection changes of animation data, we can just redraw...
- * otherwise autocolor might need to be done again */
- if (ELEM(wmn->data, ND_KEYFRAME, ND_ANIMCHAN) && (wmn->action == NA_SELECTED))
- ED_area_tag_redraw(sa);
- else
- ED_area_tag_refresh(sa);
- break;
- case NC_SCENE:
- switch (wmn->data) {
- case ND_OB_ACTIVE: /* selection changed, so force refresh to flush
- * (needs flag set to do syncing) */
- case ND_OB_SELECT:
- sipo->runtime.flag |= SIPO_RUNTIME_FLAG_NEED_CHAN_SYNC;
- ED_area_tag_refresh(sa);
- break;
-
- default: /* just redrawing the view will do */
- ED_area_tag_redraw(sa);
- break;
- }
- break;
- case NC_OBJECT:
- switch (wmn->data) {
- case ND_BONE_SELECT: /* selection changed, so force refresh to flush
- * (needs flag set to do syncing) */
- case ND_BONE_ACTIVE:
- sipo->runtime.flag |= SIPO_RUNTIME_FLAG_NEED_CHAN_SYNC;
- ED_area_tag_refresh(sa);
- break;
- case ND_TRANSFORM:
- break; /*do nothing*/
-
- default: /* just redrawing the view will do */
- ED_area_tag_redraw(sa);
- break;
- }
- break;
- case NC_NODE:
- if (wmn->action == NA_SELECTED) {
- /* selection changed, so force refresh to flush (needs flag set to do syncing) */
- sipo->runtime.flag |= SIPO_RUNTIME_FLAG_NEED_CHAN_SYNC;
- ED_area_tag_refresh(sa);
- }
- break;
- case NC_SPACE:
- if (wmn->data == ND_SPACE_GRAPH)
- ED_area_tag_redraw(sa);
- break;
- case NC_WINDOW:
- if (sipo->runtime.flag & (SIPO_RUNTIME_FLAG_NEED_CHAN_SYNC | SIPO_RUNTIME_FLAG_NEED_CHAN_SYNC_COLOR)) {
- /* force redraw/refresh after undo/redo - prevents "black curve" problem */
- ED_area_tag_refresh(sa);
- }
- break;
-
- // XXX: restore the case below if not enough updates occur...
- //default:
- // if (wmn->data == ND_KEYS)
- // ED_area_tag_redraw(sa);
- }
+ SpaceGraph *sipo = (SpaceGraph *)sa->spacedata.first;
+
+ /* context changes */
+ switch (wmn->category) {
+ case NC_ANIMATION:
+ /* for selection changes of animation data, we can just redraw...
+ * otherwise autocolor might need to be done again */
+ if (ELEM(wmn->data, ND_KEYFRAME, ND_ANIMCHAN) && (wmn->action == NA_SELECTED))
+ ED_area_tag_redraw(sa);
+ else
+ ED_area_tag_refresh(sa);
+ break;
+ case NC_SCENE:
+ switch (wmn->data) {
+ case ND_OB_ACTIVE: /* selection changed, so force refresh to flush
+ * (needs flag set to do syncing) */
+ case ND_OB_SELECT:
+ sipo->runtime.flag |= SIPO_RUNTIME_FLAG_NEED_CHAN_SYNC;
+ ED_area_tag_refresh(sa);
+ break;
+
+ default: /* just redrawing the view will do */
+ ED_area_tag_redraw(sa);
+ break;
+ }
+ break;
+ case NC_OBJECT:
+ switch (wmn->data) {
+ case ND_BONE_SELECT: /* selection changed, so force refresh to flush
+ * (needs flag set to do syncing) */
+ case ND_BONE_ACTIVE:
+ sipo->runtime.flag |= SIPO_RUNTIME_FLAG_NEED_CHAN_SYNC;
+ ED_area_tag_refresh(sa);
+ break;
+ case ND_TRANSFORM:
+ break; /*do nothing*/
+
+ default: /* just redrawing the view will do */
+ ED_area_tag_redraw(sa);
+ break;
+ }
+ break;
+ case NC_NODE:
+ if (wmn->action == NA_SELECTED) {
+ /* selection changed, so force refresh to flush (needs flag set to do syncing) */
+ sipo->runtime.flag |= SIPO_RUNTIME_FLAG_NEED_CHAN_SYNC;
+ ED_area_tag_refresh(sa);
+ }
+ break;
+ case NC_SPACE:
+ if (wmn->data == ND_SPACE_GRAPH)
+ ED_area_tag_redraw(sa);
+ break;
+ case NC_WINDOW:
+ if (sipo->runtime.flag &
+ (SIPO_RUNTIME_FLAG_NEED_CHAN_SYNC | SIPO_RUNTIME_FLAG_NEED_CHAN_SYNC_COLOR)) {
+ /* force redraw/refresh after undo/redo - prevents "black curve" problem */
+ ED_area_tag_refresh(sa);
+ }
+ break;
+
+ // XXX: restore the case below if not enough updates occur...
+ //default:
+ // if (wmn->data == ND_KEYS)
+ // ED_area_tag_redraw(sa);
+ }
}
/* Update F-Curve colors */
static void graph_refresh_fcurve_colors(const bContext *C)
{
- bAnimContext ac;
-
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- size_t items;
- int filter;
- int i;
-
- if (ANIM_animdata_get_context(C, &ac) == false)
- return;
-
- UI_SetTheme(SPACE_GRAPH, RGN_TYPE_WINDOW);
-
- /* build list of F-Curves which will be visible as channels in channel-region
- * - we don't include ANIMFILTER_CURVEVISIBLE filter, as that will result in a
- * mismatch between channel-colors and the drawn curves
- */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_NODUPLIS);
- items = ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
- /* loop over F-Curves, assigning colors */
- for (ale = anim_data.first, i = 0; ale; ale = ale->next, i++) {
- FCurve *fcu = (FCurve *)ale->data;
-
- /* set color of curve here */
- switch (fcu->color_mode) {
- case FCURVE_COLOR_CUSTOM:
- {
- /* User has defined a custom color for this curve already (we assume it's not going to cause clashes with text colors),
- * which should be left alone... Nothing needs to be done here.
- */
- break;
- }
- case FCURVE_COLOR_AUTO_RGB:
- {
- /* F-Curve's array index is automatically mapped to RGB values. This works best of 3-value vectors.
- * TODO: find a way to module the hue so that not all curves have same color...
- */
- float *col = fcu->color;
-
- switch (fcu->array_index) {
- case 0:
- UI_GetThemeColor3fv(TH_AXIS_X, col);
- break;
- case 1:
- UI_GetThemeColor3fv(TH_AXIS_Y, col);
- break;
- case 2:
- UI_GetThemeColor3fv(TH_AXIS_Z, col);
- break;
- default:
- /* 'unknown' color - bluish so as to not conflict with handles */
- col[0] = 0.3f; col[1] = 0.8f; col[2] = 1.0f;
- break;
- }
- break;
- }
- case FCURVE_COLOR_AUTO_YRGB:
- {
- /* Like FCURVE_COLOR_AUTO_RGB, except this is for quaternions... */
- float *col = fcu->color;
-
- switch (fcu->array_index) {
- case 1:
- UI_GetThemeColor3fv(TH_AXIS_X, col);
- break;
- case 2:
- UI_GetThemeColor3fv(TH_AXIS_Y, col);
- break;
- case 3:
- UI_GetThemeColor3fv(TH_AXIS_Z, col);
- break;
-
- case 0:
- {
- /* Special Case: "W" channel should be yellowish, so blend X and Y channel colors... */
- float c1[3], c2[3];
- float h1[3], h2[3];
- float hresult[3];
-
- /* - get colors (rgb) */
- UI_GetThemeColor3fv(TH_AXIS_X, c1);
- UI_GetThemeColor3fv(TH_AXIS_Y, c2);
-
- /* - perform blending in HSV space (to keep brightness similar) */
- rgb_to_hsv_v(c1, h1);
- rgb_to_hsv_v(c2, h2);
-
- interp_v3_v3v3(hresult, h1, h2, 0.5f);
-
- /* - convert back to RGB for display */
- hsv_to_rgb_v(hresult, col);
- break;
- }
-
- default:
- /* 'unknown' color - bluish so as to not conflict with handles */
- col[0] = 0.3f; col[1] = 0.8f; col[2] = 1.0f;
- break;
- }
- break;
- }
- case FCURVE_COLOR_AUTO_RAINBOW:
- default:
- {
- /* determine color 'automatically' using 'magic function' which uses the given args
- * of current item index + total items to determine some RGB color
- */
- getcolor_fcurve_rainbow(i, items, fcu->color);
- break;
- }
- }
- }
-
- /* free temp list */
- ANIM_animdata_freelist(&anim_data);
+ bAnimContext ac;
+
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ size_t items;
+ int filter;
+ int i;
+
+ if (ANIM_animdata_get_context(C, &ac) == false)
+ return;
+
+ UI_SetTheme(SPACE_GRAPH, RGN_TYPE_WINDOW);
+
+ /* build list of F-Curves which will be visible as channels in channel-region
+ * - we don't include ANIMFILTER_CURVEVISIBLE filter, as that will result in a
+ * mismatch between channel-colors and the drawn curves
+ */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_NODUPLIS);
+ items = ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+
+ /* loop over F-Curves, assigning colors */
+ for (ale = anim_data.first, i = 0; ale; ale = ale->next, i++) {
+ FCurve *fcu = (FCurve *)ale->data;
+
+ /* set color of curve here */
+ switch (fcu->color_mode) {
+ case FCURVE_COLOR_CUSTOM: {
+ /* User has defined a custom color for this curve already (we assume it's not going to cause clashes with text colors),
+ * which should be left alone... Nothing needs to be done here.
+ */
+ break;
+ }
+ case FCURVE_COLOR_AUTO_RGB: {
+ /* F-Curve's array index is automatically mapped to RGB values. This works best of 3-value vectors.
+ * TODO: find a way to module the hue so that not all curves have same color...
+ */
+ float *col = fcu->color;
+
+ switch (fcu->array_index) {
+ case 0:
+ UI_GetThemeColor3fv(TH_AXIS_X, col);
+ break;
+ case 1:
+ UI_GetThemeColor3fv(TH_AXIS_Y, col);
+ break;
+ case 2:
+ UI_GetThemeColor3fv(TH_AXIS_Z, col);
+ break;
+ default:
+ /* 'unknown' color - bluish so as to not conflict with handles */
+ col[0] = 0.3f;
+ col[1] = 0.8f;
+ col[2] = 1.0f;
+ break;
+ }
+ break;
+ }
+ case FCURVE_COLOR_AUTO_YRGB: {
+ /* Like FCURVE_COLOR_AUTO_RGB, except this is for quaternions... */
+ float *col = fcu->color;
+
+ switch (fcu->array_index) {
+ case 1:
+ UI_GetThemeColor3fv(TH_AXIS_X, col);
+ break;
+ case 2:
+ UI_GetThemeColor3fv(TH_AXIS_Y, col);
+ break;
+ case 3:
+ UI_GetThemeColor3fv(TH_AXIS_Z, col);
+ break;
+
+ case 0: {
+ /* Special Case: "W" channel should be yellowish, so blend X and Y channel colors... */
+ float c1[3], c2[3];
+ float h1[3], h2[3];
+ float hresult[3];
+
+ /* - get colors (rgb) */
+ UI_GetThemeColor3fv(TH_AXIS_X, c1);
+ UI_GetThemeColor3fv(TH_AXIS_Y, c2);
+
+ /* - perform blending in HSV space (to keep brightness similar) */
+ rgb_to_hsv_v(c1, h1);
+ rgb_to_hsv_v(c2, h2);
+
+ interp_v3_v3v3(hresult, h1, h2, 0.5f);
+
+ /* - convert back to RGB for display */
+ hsv_to_rgb_v(hresult, col);
+ break;
+ }
+
+ default:
+ /* 'unknown' color - bluish so as to not conflict with handles */
+ col[0] = 0.3f;
+ col[1] = 0.8f;
+ col[2] = 1.0f;
+ break;
+ }
+ break;
+ }
+ case FCURVE_COLOR_AUTO_RAINBOW:
+ default: {
+ /* determine color 'automatically' using 'magic function' which uses the given args
+ * of current item index + total items to determine some RGB color
+ */
+ getcolor_fcurve_rainbow(i, items, fcu->color);
+ break;
+ }
+ }
+ }
+
+ /* free temp list */
+ ANIM_animdata_freelist(&anim_data);
}
static void graph_refresh(const bContext *C, ScrArea *sa)
{
- SpaceGraph *sipo = (SpaceGraph *)sa->spacedata.first;
-
- /* updates to data needed depends on Graph Editor mode... */
- switch (sipo->mode) {
- case SIPO_MODE_ANIMATION: /* all animation */
- {
- break;
- }
-
- case SIPO_MODE_DRIVERS: /* drivers only */
- {
- break;
- }
- }
-
- /* region updates? */
- // XXX re-sizing y-extents of tot should go here?
-
- /* update the state of the animchannels in response to changes from the data they represent
- * NOTE: the temp flag is used to indicate when this needs to be done, and will be cleared once handled
- */
- if (sipo->runtime.flag & SIPO_RUNTIME_FLAG_NEED_CHAN_SYNC) {
- ANIM_sync_animchannels_to_data(C);
- sipo->runtime.flag &= ~SIPO_RUNTIME_FLAG_NEED_CHAN_SYNC;
- ED_area_tag_redraw(sa);
- }
-
- /* We could check 'SIPO_RUNTIME_FLAG_NEED_CHAN_SYNC_COLOR', but color is recalculated anyway. */
- if (sipo->runtime.flag & SIPO_RUNTIME_FLAG_NEED_CHAN_SYNC_COLOR) {
- sipo->runtime.flag &= ~SIPO_RUNTIME_FLAG_NEED_CHAN_SYNC_COLOR;
-#if 0 /* Done below. */
- graph_refresh_fcurve_colors(C);
+ SpaceGraph *sipo = (SpaceGraph *)sa->spacedata.first;
+
+ /* updates to data needed depends on Graph Editor mode... */
+ switch (sipo->mode) {
+ case SIPO_MODE_ANIMATION: /* all animation */
+ {
+ break;
+ }
+
+ case SIPO_MODE_DRIVERS: /* drivers only */
+ {
+ break;
+ }
+ }
+
+ /* region updates? */
+ // XXX re-sizing y-extents of tot should go here?
+
+ /* update the state of the animchannels in response to changes from the data they represent
+ * NOTE: the temp flag is used to indicate when this needs to be done, and will be cleared once handled
+ */
+ if (sipo->runtime.flag & SIPO_RUNTIME_FLAG_NEED_CHAN_SYNC) {
+ ANIM_sync_animchannels_to_data(C);
+ sipo->runtime.flag &= ~SIPO_RUNTIME_FLAG_NEED_CHAN_SYNC;
+ ED_area_tag_redraw(sa);
+ }
+
+ /* We could check 'SIPO_RUNTIME_FLAG_NEED_CHAN_SYNC_COLOR', but color is recalculated anyway. */
+ if (sipo->runtime.flag & SIPO_RUNTIME_FLAG_NEED_CHAN_SYNC_COLOR) {
+ sipo->runtime.flag &= ~SIPO_RUNTIME_FLAG_NEED_CHAN_SYNC_COLOR;
+#if 0 /* Done below. */
+ graph_refresh_fcurve_colors(C);
#endif
- ED_area_tag_redraw(sa);
- }
+ ED_area_tag_redraw(sa);
+ }
- /* init/adjust F-Curve colors */
- graph_refresh_fcurve_colors(C);
+ /* init/adjust F-Curve colors */
+ graph_refresh_fcurve_colors(C);
}
static void graph_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id, ID *new_id)
{
- SpaceGraph *sgraph = (SpaceGraph *)slink;
-
- if (sgraph->ads) {
- if ((ID *)sgraph->ads->filter_grp == old_id) {
- sgraph->ads->filter_grp = (Collection *)new_id;
- }
- if ((ID *)sgraph->ads->source == old_id) {
- sgraph->ads->source = new_id;
- }
- }
+ SpaceGraph *sgraph = (SpaceGraph *)slink;
+
+ if (sgraph->ads) {
+ if ((ID *)sgraph->ads->filter_grp == old_id) {
+ sgraph->ads->filter_grp = (Collection *)new_id;
+ }
+ if ((ID *)sgraph->ads->source == old_id) {
+ sgraph->ads->source = new_id;
+ }
+ }
}
static int graph_space_subtype_get(ScrArea *sa)
{
- SpaceGraph *sgraph = sa->spacedata.first;
- return sgraph->mode;
+ SpaceGraph *sgraph = sa->spacedata.first;
+ return sgraph->mode;
}
static void graph_space_subtype_set(ScrArea *sa, int value)
{
- SpaceGraph *sgraph = sa->spacedata.first;
- sgraph->mode = value;
+ SpaceGraph *sgraph = sa->spacedata.first;
+ sgraph->mode = value;
}
-static void graph_space_subtype_item_extend(
- bContext *UNUSED(C), EnumPropertyItem **item, int *totitem)
+static void graph_space_subtype_item_extend(bContext *UNUSED(C),
+ EnumPropertyItem **item,
+ int *totitem)
{
- RNA_enum_items_add(item, totitem, rna_enum_space_graph_mode_items);
+ RNA_enum_items_add(item, totitem, rna_enum_space_graph_mode_items);
}
/* only called once, from space/spacetypes.c */
void ED_spacetype_ipo(void)
{
- SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype ipo");
- ARegionType *art;
-
- st->spaceid = SPACE_GRAPH;
- strncpy(st->name, "Graph", BKE_ST_MAXNAME);
-
- st->new = graph_new;
- st->free = graph_free;
- st->init = graph_init;
- st->duplicate = graph_duplicate;
- st->operatortypes = graphedit_operatortypes;
- st->keymap = graphedit_keymap;
- st->listener = graph_listener;
- st->refresh = graph_refresh;
- st->id_remap = graph_id_remap;
- st->space_subtype_item_extend = graph_space_subtype_item_extend;
- st->space_subtype_get = graph_space_subtype_get;
- st->space_subtype_set = graph_space_subtype_set;
-
- /* regions: main window */
- art = MEM_callocN(sizeof(ARegionType), "spacetype graphedit region");
- art->regionid = RGN_TYPE_WINDOW;
- art->init = graph_main_region_init;
- art->draw = graph_main_region_draw;
- art->listener = graph_region_listener;
- art->message_subscribe = graph_region_message_subscribe;
- art->keymapflag = ED_KEYMAP_VIEW2D | ED_KEYMAP_MARKERS | ED_KEYMAP_ANIMATION | ED_KEYMAP_FRAMES;
-
- BLI_addhead(&st->regiontypes, art);
-
- /* regions: header */
- art = MEM_callocN(sizeof(ARegionType), "spacetype graphedit region");
- art->regionid = RGN_TYPE_HEADER;
- art->prefsizey = HEADERY;
- art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES | ED_KEYMAP_HEADER;
- art->listener = graph_region_listener;
- art->init = graph_header_region_init;
- art->draw = graph_header_region_draw;
-
- BLI_addhead(&st->regiontypes, art);
-
- /* regions: channels */
- art = MEM_callocN(sizeof(ARegionType), "spacetype graphedit region");
- art->regionid = RGN_TYPE_CHANNELS;
- /* 200 is the 'standard', but due to scrollers, we want a bit more to fit the lock icons in */
- art->prefsizex = 200 + V2D_SCROLL_WIDTH;
- art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES;
- art->listener = graph_region_listener;
- art->message_subscribe = graph_region_message_subscribe;
- art->init = graph_channel_region_init;
- art->draw = graph_channel_region_draw;
-
- BLI_addhead(&st->regiontypes, art);
-
- /* regions: UI buttons */
- art = MEM_callocN(sizeof(ARegionType), "spacetype graphedit region");
- art->regionid = RGN_TYPE_UI;
- art->prefsizex = 200;
- art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES;
- art->listener = graph_region_listener;
- art->init = graph_buttons_region_init;
- art->draw = graph_buttons_region_draw;
-
- BLI_addhead(&st->regiontypes, art);
-
- graph_buttons_register(art);
-
- BKE_spacetype_register(st);
+ SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype ipo");
+ ARegionType *art;
+
+ st->spaceid = SPACE_GRAPH;
+ strncpy(st->name, "Graph", BKE_ST_MAXNAME);
+
+ st->new = graph_new;
+ st->free = graph_free;
+ st->init = graph_init;
+ st->duplicate = graph_duplicate;
+ st->operatortypes = graphedit_operatortypes;
+ st->keymap = graphedit_keymap;
+ st->listener = graph_listener;
+ st->refresh = graph_refresh;
+ st->id_remap = graph_id_remap;
+ st->space_subtype_item_extend = graph_space_subtype_item_extend;
+ st->space_subtype_get = graph_space_subtype_get;
+ st->space_subtype_set = graph_space_subtype_set;
+
+ /* regions: main window */
+ art = MEM_callocN(sizeof(ARegionType), "spacetype graphedit region");
+ art->regionid = RGN_TYPE_WINDOW;
+ art->init = graph_main_region_init;
+ art->draw = graph_main_region_draw;
+ art->listener = graph_region_listener;
+ art->message_subscribe = graph_region_message_subscribe;
+ art->keymapflag = ED_KEYMAP_VIEW2D | ED_KEYMAP_MARKERS | ED_KEYMAP_ANIMATION | ED_KEYMAP_FRAMES;
+
+ BLI_addhead(&st->regiontypes, art);
+
+ /* regions: header */
+ art = MEM_callocN(sizeof(ARegionType), "spacetype graphedit region");
+ art->regionid = RGN_TYPE_HEADER;
+ art->prefsizey = HEADERY;
+ art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES | ED_KEYMAP_HEADER;
+ art->listener = graph_region_listener;
+ art->init = graph_header_region_init;
+ art->draw = graph_header_region_draw;
+
+ BLI_addhead(&st->regiontypes, art);
+
+ /* regions: channels */
+ art = MEM_callocN(sizeof(ARegionType), "spacetype graphedit region");
+ art->regionid = RGN_TYPE_CHANNELS;
+ /* 200 is the 'standard', but due to scrollers, we want a bit more to fit the lock icons in */
+ art->prefsizex = 200 + V2D_SCROLL_WIDTH;
+ art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES;
+ art->listener = graph_region_listener;
+ art->message_subscribe = graph_region_message_subscribe;
+ art->init = graph_channel_region_init;
+ art->draw = graph_channel_region_draw;
+
+ BLI_addhead(&st->regiontypes, art);
+
+ /* regions: UI buttons */
+ art = MEM_callocN(sizeof(ARegionType), "spacetype graphedit region");
+ art->regionid = RGN_TYPE_UI;
+ art->prefsizex = 200;
+ art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES;
+ art->listener = graph_region_listener;
+ art->init = graph_buttons_region_init;
+ art->draw = graph_buttons_region_draw;
+
+ BLI_addhead(&st->regiontypes, art);
+
+ graph_buttons_register(art);
+
+ BKE_spacetype_register(st);
}