From 7e940f184f598b8418e063d9017ba7142f91f5a2 Mon Sep 17 00:00:00 2001 From: Christoph Lendenfeld Date: Thu, 30 Mar 2023 10:01:12 +0200 Subject: [PATCH] Animation: Auto frame curves Y extents when hitting normalize When hitting the "normalize" button in the graph editor, set the y extents of the view to the extents of the `FCurves`. Previously you had to search for your curves after pressing that button. Pull Request: https://projects.blender.org/blender/blender/pulls/105857 --- .../editors/animation/anim_channels_edit.c | 48 +++++++++++++++++-- source/blender/editors/include/ED_anim_api.h | 2 + source/blender/makesrna/intern/rna_space.c | 16 ++++++- 3 files changed, 60 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c index 481e7f413d3..590f69b3224 100644 --- a/source/blender/editors/animation/anim_channels_edit.c +++ b/source/blender/editors/animation/anim_channels_edit.c @@ -142,7 +142,7 @@ static bool get_channel_bounds(bAnimContext *ac, /* Pad the given rctf with regions that could block the view. * For example Markers and Time Scrubbing. */ -static void add_region_padding(bContext *C, bAnimContext *ac, rctf *bounds) +static void add_region_padding(bContext *C, ARegion *region, rctf *bounds) { BLI_rctf_scale(bounds, 1.1f); @@ -150,9 +150,8 @@ static void add_region_padding(bContext *C, bAnimContext *ac, rctf *bounds) const float pad_bottom = BLI_listbase_is_empty(ED_context_get_markers(C)) ? V2D_SCROLL_HANDLE_HEIGHT : UI_MARKER_MARGIN_Y; - BLI_rctf_pad_y(bounds, ac->region->winy, pad_bottom, pad_top); + BLI_rctf_pad_y(bounds, region->winy, pad_bottom, pad_top); } - /** \} */ /* -------------------------------------------------------------------- */ @@ -731,6 +730,45 @@ void ANIM_flush_setting_anim_channels(bAnimContext *ac, anim_flush_channel_setting_down(ac, setting, mode, match, matchLevel); } +void ANIM_frame_channel_y_extents(bContext *C, bAnimContext *ac) +{ + + ARegion *window_region = BKE_area_find_region_type(ac->area, RGN_TYPE_WINDOW); + + if (!window_region) { + return; + } + + ListBase anim_data = {NULL, NULL}; + const int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS | + ANIMFILTER_FCURVESONLY); + ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); + + rctf bounds = {.xmin = FLT_MAX, .xmax = -FLT_MAX, .ymin = FLT_MAX, .ymax = -FLT_MAX}; + const bool include_handles = false; + const float frame_range[2] = {window_region->v2d.cur.xmin, window_region->v2d.cur.xmax}; + + LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) { + rctf channel_bounds; + const bool found_bounds = get_channel_bounds( + ac, ale, frame_range, include_handles, &channel_bounds); + if (found_bounds) { + BLI_rctf_union(&bounds, &channel_bounds); + } + } + + if (!BLI_rctf_is_valid(&bounds)) { + ANIM_animdata_freelist(&anim_data); + return; + } + + add_region_padding(C, window_region, &bounds); + + window_region->v2d.cur.ymin = bounds.ymin; + window_region->v2d.cur.ymax = bounds.ymax; + + ANIM_animdata_freelist(&anim_data); +} /** \} */ /* -------------------------------------------------------------------- */ @@ -3805,7 +3843,7 @@ static int graphkeys_view_selected_channels_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - add_region_padding(C, &ac, &bounds); + add_region_padding(C, window_region, &bounds); if (ac.spacetype == SPACE_ACTION) { bounds.ymin = window_region->v2d.cur.ymin; @@ -3893,7 +3931,7 @@ static int graphkeys_channel_view_pick_invoke(bContext *C, wmOperator *op, const return OPERATOR_CANCELLED; } - add_region_padding(C, &ac, &bounds); + add_region_padding(C, window_region, &bounds); if (ac.spacetype == SPACE_ACTION) { bounds.ymin = window_region->v2d.cur.ymin; diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index a436fa43989..a5c99dd717f 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -676,6 +676,8 @@ void ANIM_flush_setting_anim_channels(bAnimContext *ac, eAnimChannel_Settings setting, eAnimChannels_SetFlag mode); +void ANIM_frame_channel_y_extents(struct bContext *C, bAnimContext *ac); + /** * Set selection state of all animation channels in the context. */ diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 1df30e12782..8c26502fddd 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -2376,6 +2376,18 @@ static void rna_SpaceGraphEditor_display_mode_update(bContext *C, PointerRNA *pt ED_area_tag_refresh(area); } +static void rna_SpaceGraphEditor_normalize_update(bContext *C, PointerRNA *UNUSED(ptr)) +{ + bAnimContext ac; + + if (ANIM_animdata_get_context(C, &ac) == 0) { + return; + } + + ANIM_frame_channel_y_extents(C, &ac); + ED_area_tag_refresh(ac.area); +} + static bool rna_SpaceGraphEditor_has_ghost_curves_get(PointerRNA *ptr) { SpaceGraph *sipo = (SpaceGraph *)(ptr->data); @@ -6414,7 +6426,9 @@ static void rna_def_space_graph(BlenderRNA *brna) "Use Normalization", "Display curves in normalized range from -1 to 1, " "for easier editing of multiple curves with different ranges"); - RNA_def_property_update(prop, NC_SPACE | ND_SPACE_GRAPH, NULL); + RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); + RNA_def_property_update( + prop, NC_SPACE | ND_SPACE_GRAPH, "rna_SpaceGraphEditor_normalize_update"); prop = RNA_def_property(srna, "use_auto_normalization", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SIPO_NORMALIZE_FREEZE);