diff options
Diffstat (limited to 'source/blender/editors/space_graph')
-rw-r--r-- | source/blender/editors/space_graph/graph_buttons.c | 23 | ||||
-rw-r--r-- | source/blender/editors/space_graph/graph_draw.c | 34 | ||||
-rw-r--r-- | source/blender/editors/space_graph/graph_edit.c | 90 | ||||
-rw-r--r-- | source/blender/editors/space_graph/graph_intern.h | 4 | ||||
-rw-r--r-- | source/blender/editors/space_graph/graph_ops.c | 18 | ||||
-rw-r--r-- | source/blender/editors/space_graph/graph_select.c | 32 | ||||
-rw-r--r-- | source/blender/editors/space_graph/graph_utils.c | 9 |
7 files changed, 142 insertions, 68 deletions
diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c index a2b64afdb15..e0b62722d57 100644 --- a/source/blender/editors/space_graph/graph_buttons.c +++ b/source/blender/editors/space_graph/graph_buttons.c @@ -165,9 +165,28 @@ static void graph_panel_properties(const bContext *C, Panel *pa) RNA_pointer_create(ale->id, &RNA_FCurve, fcu, &fcu_ptr); /* user-friendly 'name' for F-Curve */ - /* TODO: only show the path if this is invalid? */ col = uiLayoutColumn(layout, false); - icon = getname_anim_fcurve(name, ale->id, fcu); + 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 */ diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c index a5c04ce2cb4..87e7cab4d15 100644 --- a/source/blender/editors/space_graph/graph_draw.c +++ b/source/blender/editors/space_graph/graph_draw.c @@ -481,7 +481,7 @@ static void draw_fcurve_curve(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d ChannelDriver *driver; float samplefreq; float stime, etime; - float unitFac; + float unitFac, offset; float dx, dy; short mapping_flag = ANIM_get_normalization_flags(ac); int i, n; @@ -498,7 +498,7 @@ static void draw_fcurve_curve(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d fcu->driver = NULL; /* compute unit correction factor */ - unitFac = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag); + unitFac = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag, &offset); /* Note about sampling frequency: * Ideally, this is chosen such that we have 1-2 pixels = 1 segment @@ -550,7 +550,7 @@ static void draw_fcurve_curve(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d n = (etime - stime) / samplefreq + 0.5f; for (i = 0; i <= n; i++) { float ctime = stime + i * samplefreq; - glVertex2f(ctime, evaluate_fcurve(fcu, ctime) * unitFac); + glVertex2f(ctime, (evaluate_fcurve(fcu, ctime) + offset) * unitFac); } glEnd(); @@ -566,13 +566,14 @@ static void draw_fcurve_curve_samples(bAnimContext *ac, ID *id, FCurve *fcu, Vie FPoint *fpt = prevfpt + 1; float fac, v[2]; int b = fcu->totvert - 1; - float unit_scale; + float unit_scale, offset; short mapping_flag = ANIM_get_normalization_flags(ac); /* apply unit mapping */ glPushMatrix(); - unit_scale = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag); + unit_scale = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag, &offset); glScalef(1.0f, unit_scale, 1.0f); + glTranslatef(0.0f, offset, 0.0f); glBegin(GL_LINE_STRIP); @@ -665,14 +666,15 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2 float fac = 0.0f; int b = fcu->totvert - 1; int resol; - float unit_scale; + float unit_scale, offset; short mapping_flag = ANIM_get_normalization_flags(ac); /* apply unit mapping */ glPushMatrix(); - unit_scale = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag); + unit_scale = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag, &offset); glScalef(1.0f, unit_scale, 1.0f); - + glTranslatef(0.0f, offset, 0.0f); + glBegin(GL_LINE_STRIP); /* extrapolate to left? */ @@ -826,7 +828,8 @@ 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 unitfac = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag); + 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) @@ -850,10 +853,10 @@ static void graph_draw_driver_debug(bAnimContext *ac, ID *id, FCurve *fcu) glBegin(GL_LINES); { t = v2d->cur.xmin; - glVertex2f(t, t * unitfac); + glVertex2f(t, (t + offset) * unitfac); t = v2d->cur.xmax; - glVertex2f(t, t * unitfac); + glVertex2f(t, (t + offset) * unitfac); } glEnd(); @@ -1067,10 +1070,12 @@ void graph_draw_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGrid } else if (((fcu->bezt) || (fcu->fpt)) && (fcu->totvert)) { short mapping_flag = ANIM_get_normalization_flags(ac); - float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag); + float offset; + float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag, &offset); glPushMatrix(); glScalef(1.0f, unit_scale, 1.0f); + glTranslatef(0.0f, offset, 0.0f); if (fcu->bezt) { bool do_handles = draw_fcurve_handles_check(sipo, fcu); @@ -1137,6 +1142,8 @@ void graph_draw_channel_names(bContext *C, bAnimContext *ac, ARegion *ar) /* 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; for (ale = anim_data.first, i = 0; ale; ale = ale->next, i++) { @@ -1148,11 +1155,12 @@ void graph_draw_channel_names(bContext *C, bAnimContext *ac, ARegion *ar) IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax) ) { /* draw all channels using standard channel-drawing API */ - ANIM_channel_draw(ac, ale, yminc, ymaxc); + ANIM_channel_draw(ac, ale, yminc, ymaxc, channel_index); } /* adjust y-position for next one */ y -= ACHANNEL_STEP; + channel_index++; } } { /* second pass: widgets */ diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index 2944901663b..3de3ecebc44 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -109,7 +109,7 @@ void get_graph_keyframe_extents(bAnimContext *ac, float *xmin, float *xmax, floa AnimData *adt = ANIM_nla_mapping_get(ac, ale); FCurve *fcu = (FCurve *)ale->key_data; float txmin, txmax, tymin, tymax; - float unitFac; + float unitFac, offset; /* get range */ if (calc_fcurve_bounds(fcu, &txmin, &txmax, &tymin, &tymax, do_sel_only, include_handles)) { @@ -122,7 +122,9 @@ void get_graph_keyframe_extents(bAnimContext *ac, float *xmin, float *xmax, floa } /* apply unit corrections */ - unitFac = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag); + unitFac = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag, &offset); + tymin += offset; + tymax += offset; tymin *= unitFac; tymax *= unitFac; @@ -256,6 +258,14 @@ static int graphkeys_view_selected_exec(bContext *C, wmOperator *op) return graphkeys_viewall(C, true, include_handles, smooth_viewtx); } +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; +} + + void GRAPH_OT_view_all(wmOperatorType *ot) { /* identifiers */ @@ -294,6 +304,21 @@ void GRAPH_OT_view_selected(wmOperatorType *ot) "Include handles of keyframes when calculating extents"); } +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"; + + /* api callbacks */ + ot->exec = graphkeys_view_frame_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; +} + /* ******************** Create Ghost-Curves Operator *********************** */ /* This operator samples the data of the selected F-Curves to F-Points, storing them * as 'ghost curves' in the active Graph Editor @@ -327,7 +352,7 @@ static void create_ghost_curves(bAnimContext *ac, int start, int end) AnimData *adt = ANIM_nla_mapping_get(ac, ale); ChannelDriver *driver = fcu->driver; FPoint *fpt; - float unitFac; + float unitFac, offset; int cfra; SpaceIpo *sipo = (SpaceIpo *) ac->sl; short mapping_flag = ANIM_get_normalization_flags(ac); @@ -336,7 +361,7 @@ static void create_ghost_curves(bAnimContext *ac, int start, int end) fcu->driver = NULL; /* calculate unit-mapping factor */ - unitFac = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag); + 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 @@ -349,7 +374,7 @@ static void create_ghost_curves(bAnimContext *ac, int start, int end) float cfrae = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP); fpt->vec[0] = cfrae; - fpt->vec[1] = fcurve_samplingcb_evalcurve(fcu, NULL, cfrae) * unitFac; + fpt->vec[1] = (fcurve_samplingcb_evalcurve(fcu, NULL, cfrae) + offset) * unitFac; } /* set color of ghost curve @@ -498,12 +523,17 @@ static void insert_graph_keys(bAnimContext *ac, short mode) else cfra = (float)CFRA; - /* if there's an id */ - if (ale->id) + /* 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...) + */ + if (ale->id && !ale->owner) insert_keyframe(reports, ale->id, NULL, ((fcu->grp) ? (fcu->grp->name) : (NULL)), fcu->rna_path, fcu->array_index, cfra, flag); else insert_vert_fcurve(fcu, cfra, fcu->curval, 0); - + ale->update |= ANIM_UPDATE_DEFAULT; } @@ -582,7 +612,7 @@ static int graphkeys_click_insert_exec(bContext *C, wmOperator *op) ListBase anim_data; short mapping_flag = ANIM_get_normalization_flags(&ac); - + float scale, offset; /* get frame and value from props */ frame = RNA_float_get(op->ptr, "frame"); val = RNA_float_get(op->ptr, "value"); @@ -592,16 +622,18 @@ static int graphkeys_click_insert_exec(bContext *C, wmOperator *op) frame = BKE_nla_tweakedit_remap(adt, frame, NLATIME_CONVERT_UNMAP); /* apply inverse unit-mapping to value to get correct value for F-Curves */ - val *= ANIM_unit_mapping_get_factor(ac.scene, ale->id, fcu, mapping_flag | ANIM_UNITCONV_RESTORE); - + 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, 0); - + ale->update |= ANIM_UPDATE_DEPS; - + BLI_listbase_clear(&anim_data); BLI_addtail(&anim_data, ale); - + ANIM_animdata_update(&ac, &anim_data); } else { @@ -851,13 +883,6 @@ static int graphkeys_duplicate_exec(bContext *C, wmOperator *UNUSED(op)) return OPERATOR_FINISHED; } -static int graphkeys_duplicate_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) -{ - graphkeys_duplicate_exec(C, op); - - return OPERATOR_FINISHED; -} - void GRAPH_OT_duplicate(wmOperatorType *ot) { /* identifiers */ @@ -866,7 +891,6 @@ void GRAPH_OT_duplicate(wmOperatorType *ot) ot->description = "Make a copy of all selected keyframes"; /* api callbacks */ - ot->invoke = graphkeys_duplicate_invoke; ot->exec = graphkeys_duplicate_exec; ot->poll = graphop_editable_keyframes_poll; @@ -1155,6 +1179,11 @@ static int graphkeys_sound_bake_exec(bContext *C, wmOperator *op) 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; + } + scene = ac.scene; /* current scene */ /* store necessary data for the baking steps */ @@ -1877,7 +1906,8 @@ static int graphkeys_framejump_exec(bContext *C, wmOperator *UNUSED(op)) AnimData *adt = ANIM_nla_mapping_get(&ac, ale); short mapping_flag = ANIM_get_normalization_flags(&ac); KeyframeEditData current_ked; - float unit_scale = ANIM_unit_mapping_get_factor(ac.scene, ale->id, ale->key_data, mapping_flag | ANIM_UNITCONV_ONLYKEYS); + float offset; + float unit_scale = ANIM_unit_mapping_get_factor(ac.scene, ale->id, ale->key_data, mapping_flag | ANIM_UNITCONV_ONLYKEYS, &offset); memset(¤t_ked, 0, sizeof(current_ked)); @@ -1891,7 +1921,7 @@ static int graphkeys_framejump_exec(bContext *C, wmOperator *UNUSED(op)) ked.f1 += current_ked.f1; ked.i1 += current_ked.i1; - ked.f2 += current_ked.f2 * unit_scale; + ked.f2 += (current_ked.f2 + offset) * unit_scale; ked.i2 += current_ked.i2; } @@ -1984,9 +2014,10 @@ static void snap_graph_keys(bAnimContext *ac, short mode) /* normalise cursor value (for normalised F-Curves display) */ if (mode == GRAPHKEYS_SNAP_VALUE) { short mapping_flag = ANIM_get_normalization_flags(ac); - float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, ale->key_data, mapping_flag); + 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; + ked.f1 = (cursor_value / unit_scale) - offset; } /* perform snapping */ @@ -2111,9 +2142,10 @@ static void mirror_graph_keys(bAnimContext *ac, short mode) /* apply unit corrections */ if (mode == GRAPHKEYS_MIRROR_VALUE) { short mapping_flag = ANIM_get_normalization_flags(ac); - float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, ale->key_data, mapping_flag | ANIM_UNITCONV_ONLYKEYS); + 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 * unit_scale; + ked.f1 = (cursor_value + offset) * unit_scale; } /* perform actual mirroring */ @@ -2243,7 +2275,7 @@ static EnumPropertyItem *graph_fmodifier_itemf(bContext *C, PointerRNA *UNUSED(p /* start from 1 to skip the 'Invalid' modifier type */ for (i = 1; i < FMODIFIER_NUM_TYPES; i++) { - FModifierTypeInfo *fmi = get_fmodifier_typeinfo(i); + const FModifierTypeInfo *fmi = get_fmodifier_typeinfo(i); int index; /* check if modifier is valid for this context */ diff --git a/source/blender/editors/space_graph/graph_intern.h b/source/blender/editors/space_graph/graph_intern.h index 50412952139..a478a86a5e2 100644 --- a/source/blender/editors/space_graph/graph_intern.h +++ b/source/blender/editors/space_graph/graph_intern.h @@ -32,11 +32,8 @@ #define __GRAPH_INTERN_H__ struct bContext; -struct wmWindowManager; struct bAnimContext; struct bAnimListElem; -struct FCurve; -struct FModifier; struct SpaceIpo; struct ScrArea; struct ARegion; @@ -94,6 +91,7 @@ void get_graph_keyframe_extents(struct bAnimContext *ac, float *xmin, float *xma void GRAPH_OT_previewrange_set(struct wmOperatorType *ot); void GRAPH_OT_view_all(struct wmOperatorType *ot); void GRAPH_OT_view_selected(struct wmOperatorType *ot); +void GRAPH_OT_view_frame(struct wmOperatorType *ot); void GRAPH_OT_click_insert(struct wmOperatorType *ot); void GRAPH_OT_keyframe_insert(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c index da308d0b1f1..f4cce29bda8 100644 --- a/source/blender/editors/space_graph/graph_ops.c +++ b/source/blender/editors/space_graph/graph_ops.c @@ -87,8 +87,9 @@ static void graphview_cursor_apply(bContext *C, wmOperator *op) * NOTE: sync this part of the code with ANIM_OT_change_frame */ CFRA = RNA_int_get(op->ptr, "frame"); + FRAMENUMBER_MIN_CLAMP(CFRA); SUBFRA = 0.f; - sound_seek_scene(bmain, scene); + BKE_sound_seek_scene(bmain, scene); /* set the cursor value */ sipo->cursorVal = RNA_float_get(op->ptr, "value"); @@ -380,6 +381,7 @@ void graphedit_operatortypes(void) 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); @@ -440,6 +442,7 @@ void ED_operatormacros_graph(void) 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); } @@ -562,15 +565,14 @@ static void graphedit_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap) WM_keymap_add_item(keymap, "GRAPH_OT_easing_type", EKEY, KM_PRESS, KM_CTRL, 0); /* destructive */ - WM_keymap_add_item(keymap, "GRAPH_OT_clean", OKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "GRAPH_OT_smooth", OKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "GRAPH_OT_sample", OKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "GRAPH_OT_bake", CKEY, KM_PRESS, KM_ALT, 0); - WM_keymap_add_item(keymap, "GRAPH_OT_delete", XKEY, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, "GRAPH_OT_delete", DELKEY, KM_PRESS, 0, 0); - + WM_keymap_add_menu(keymap, "GRAPH_MT_delete", XKEY, KM_PRESS, 0, 0); + WM_keymap_add_menu(keymap, "GRAPH_MT_delete", DELKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "GRAPH_OT_duplicate_move", DKEY, KM_PRESS, KM_SHIFT, 0); /* insertkey */ @@ -594,7 +596,8 @@ static void graphedit_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap) WM_keymap_add_item(keymap, "GRAPH_OT_view_all", HOMEKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "GRAPH_OT_view_all", NDOF_BUTTON_FIT, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "GRAPH_OT_view_selected", PADPERIOD, KM_PRESS, 0, 0); - + WM_keymap_add_item(keymap, "GRAPH_OT_view_frame", PAD0, KM_PRESS, 0, 0); + /* F-Modifiers */ kmi = WM_keymap_add_item(keymap, "GRAPH_OT_fmodifier_add", MKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0); RNA_boolean_set(kmi->ptr, "only_active", false); @@ -608,6 +611,9 @@ static void graphedit_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap) /* transform system */ transform_keymap_for_space(keyconf, keymap, SPACE_IPO); + kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", OKEY, KM_PRESS, 0, 0); + RNA_string_set(kmi->ptr, "data_path", "tool_settings.use_proportional_fcurve"); + /* pivot point settings */ kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", COMMAKEY, KM_PRESS, 0, 0); RNA_string_set(kmi->ptr, "data_path", "space_data.pivot_point"); diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c index 78dbae7618b..4cf8a1de7ab 100644 --- a/source/blender/editors/space_graph/graph_select.c +++ b/source/blender/editors/space_graph/graph_select.c @@ -272,7 +272,8 @@ static void borderselect_graphkeys( for (ale = anim_data.first; ale; ale = ale->next) { AnimData *adt = ANIM_nla_mapping_get(ac, ale); FCurve *fcu = (FCurve *)ale->key_data; - float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag); + 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 @@ -282,8 +283,8 @@ static void borderselect_graphkeys( scaled_rectf.xmin = rectf.xmin; scaled_rectf.xmax = rectf.xmax; - scaled_rectf.ymin = rectf.ymin / unit_scale; - scaled_rectf.ymax = rectf.ymax / unit_scale; + 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 @@ -1089,6 +1090,8 @@ typedef struct tNearestVertInfo { 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 */ } tNearestVertInfo; /* Tags for the type of graph vert that we have */ @@ -1116,8 +1119,8 @@ static bool fcurve_handle_sel_check(SpaceIpo *sipo, BezTriple *bezt) /* 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, - BezTriple *bezt, FPoint *fpt, short hpoint, const int mval[2], float unit_scale) + 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) { @@ -1129,7 +1132,7 @@ static void nearest_fcurve_vert_store( * 'vec' matrix */ if (UI_view2d_view_to_region_clip(v2d, - bezt->vec[hpoint + 1][0], bezt->vec[hpoint + 1][1] * unit_scale, + 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)) @@ -1149,6 +1152,8 @@ static void nearest_fcurve_vert_store( /* store values */ nvi->fcu = fcu; + nvi->ctype = ctype; + nvi->bezt = bezt; nvi->hpoint = hpoint; nvi->dist = dist; @@ -1189,30 +1194,31 @@ static void get_nearest_fcurve_verts_list(bAnimContext *ac, const int mval[2], L for (ale = anim_data.first; ale; ale = ale->next) { FCurve *fcu = (FCurve *)ale->key_data; AnimData *adt = ANIM_nla_mapping_get(ac, ale); - float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag); - + 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, bezt1, NULL, NEAREST_HANDLE_KEY, mval, unit_scale); + 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, bezt1, NULL, NEAREST_HANDLE_LEFT, mval, unit_scale); + 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, bezt1, NULL, NEAREST_HANDLE_RIGHT, mval, unit_scale); + nearest_fcurve_vert_store(matches, v2d, fcu, ale->type, bezt1, NULL, NEAREST_HANDLE_RIGHT, mval, unit_scale, offset); } } } @@ -1405,7 +1411,7 @@ static void mouse_graph_keys(bAnimContext *ac, const int mval[2], short select_m /* needs to be called with (sipo->flag & SIPO_SELCUVERTSONLY) otherwise the active flag won't be set [#26452] */ 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, ANIMTYPE_FCURVE); + ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, nvi->fcu, nvi->ctype); } /* free temp sample data for filtering */ diff --git a/source/blender/editors/space_graph/graph_utils.c b/source/blender/editors/space_graph/graph_utils.c index eea360ced45..0e56dc817e4 100644 --- a/source/blender/editors/space_graph/graph_utils.c +++ b/source/blender/editors/space_graph/graph_utils.c @@ -210,13 +210,18 @@ int graphop_active_fcurve_poll(bContext *C) if (ale == NULL) return 0; - /* free temp data... */ - has_fcurve = ((ale->data) && (ale->type == ANIMTYPE_FCURVE)); + /* 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 */ |