Bugfix [#32331] Graph editor zoom to selected includes coordinate origin if more
authorJoshua Leung <aligorith@gmail.com>
Sat, 18 Aug 2012 04:39:15 +0000 (04:39 +0000)
committerJoshua Leung <aligorith@gmail.com>
Sat, 18 Aug 2012 04:39:15 +0000 (04:39 +0000)
than one curve is displayed

The range calculation used to use a fixed 0-1 range whenever it couldn't find
any values for a particular F-Curve. However, this was then taken by the
aggregation calculation to be used as just another value, leading to problems if
only vertices of a very high-value curve are selected to be included.

Modified the range calculation to ensure that suitable vertices were found
before trying to take the range values returned.

source/blender/blenkernel/BKE_fcurve.h
source/blender/blenkernel/intern/fcurve.c
source/blender/editors/space_graph/graph_edit.c

index ad1a63fd1e6d229ccdda37d7b416526ffc08ab91..bf2f1262eee809e1a6fc284f180435628951e73b 100644 (file)
@@ -217,8 +217,8 @@ void calc_fcurve_range(struct FCurve *fcu, float *min, float *max,
                        const short do_sel_only, const short do_min_length);
 
 /* get the bounding-box extents for F-Curve */
-void calc_fcurve_bounds(struct FCurve *fcu, float *xmin, float *xmax, float *ymin, float *ymax,
-                        const short do_sel_only, const short include_handles);
+short calc_fcurve_bounds(struct FCurve *fcu, float *xmin, float *xmax, float *ymin, float *ymax,
+                         const short do_sel_only, const short include_handles);
 
 /* .............. */
 
index 97b245bd067637e1c712c7bad6e378c058f4e836..67e7743c8a4504270c173db5b736759830d465c7 100644 (file)
@@ -433,16 +433,18 @@ int binarysearch_bezt_index(BezTriple array[], float frame, int arraylen, short
 /* ...................................... */
 
 /* helper for calc_fcurve_* functions -> find first and last BezTriple to be used */
-static void get_fcurve_end_keyframes(FCurve *fcu, BezTriple **first, BezTriple **last,
-                                     const short do_sel_only)
+static short get_fcurve_end_keyframes(FCurve *fcu, BezTriple **first, BezTriple **last,
+                                      const short do_sel_only)
 {
+       short found = FALSE;
+       
        /* init outputs */
        *first = NULL;
        *last = NULL;
        
        /* sanity checks */
        if (fcu->bezt == NULL)
-               return;
+               return found;
        
        /* only include selected items? */
        if (do_sel_only) {
@@ -454,6 +456,7 @@ static void get_fcurve_end_keyframes(FCurve *fcu, BezTriple **first, BezTriple *
                for (i = 0; i < fcu->totvert; bezt++, i++) {
                        if (BEZSELECTED(bezt)) {
                                *first = bezt;
+                               found = TRUE;
                                break;
                        }
                }
@@ -463,6 +466,7 @@ static void get_fcurve_end_keyframes(FCurve *fcu, BezTriple **first, BezTriple *
                for (i = 0; i < fcu->totvert; bezt--, i++) {
                        if (BEZSELECTED(bezt)) {
                                *last = bezt;
+                               found = TRUE;
                                break;
                        }
                }
@@ -471,13 +475,16 @@ static void get_fcurve_end_keyframes(FCurve *fcu, BezTriple **first, BezTriple *
                /* just full array */
                *first = fcu->bezt;
                *last = ARRAY_LAST_ITEM(fcu->bezt, BezTriple, sizeof(BezTriple), fcu->totvert);
+               found = TRUE;
        }
+       
+       return found;
 }
 
 
 /* Calculate the extents of F-Curve's data */
-void calc_fcurve_bounds(FCurve *fcu, float *xmin, float *xmax, float *ymin, float *ymax,
-                        const short do_sel_only, const short include_handles)
+short calc_fcurve_bounds(FCurve *fcu, float *xmin, float *xmax, float *ymin, float *ymax,
+                         const short do_sel_only, const short include_handles)
 {
        float xminv = 999999999.0f, xmaxv = -999999999.0f;
        float yminv = 999999999.0f, ymaxv = -999999999.0f;
@@ -490,7 +497,7 @@ void calc_fcurve_bounds(FCurve *fcu, float *xmin, float *xmax, float *ymin, floa
                        
                        if (xmin || xmax) {
                                /* get endpoint keyframes */
-                               get_fcurve_end_keyframes(fcu, &bezt_first, &bezt_last, do_sel_only);
+                               foundvert = get_fcurve_end_keyframes(fcu, &bezt_first, &bezt_last, do_sel_only);
                                
                                if (bezt_first) {
                                        BLI_assert(bezt_last != NULL);
@@ -566,6 +573,8 @@ void calc_fcurve_bounds(FCurve *fcu, float *xmin, float *xmax, float *ymin, floa
                if (ymin) *ymin = 0.0f;
                if (ymax) *ymax = 1.0f;
        }
+       
+       return foundvert;
 }
 
 /* Calculate the extents of F-Curve's keyframes */
index 8a0538eddb05fc425dabca17b00e8a051e0b03ee..de6aa42d5a6ce700c3f731b5b46615c8b6b4d073 100644 (file)
@@ -86,6 +86,8 @@
 void get_graph_keyframe_extents(bAnimContext *ac, float *xmin, float *xmax, float *ymin, float *ymax, 
                                 const short do_sel_only, const short include_handles)
 {
+       Scene *scene = ac->scene;
+       
        ListBase anim_data = {NULL, NULL};
        bAnimListElem *ale;
        int filter;
@@ -94,7 +96,7 @@ void get_graph_keyframe_extents(bAnimContext *ac, float *xmin, float *xmax, floa
        filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
        ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
        
-       /* set large values to try to override */
+       /* 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;
@@ -102,6 +104,8 @@ void get_graph_keyframe_extents(bAnimContext *ac, float *xmin, float *xmax, floa
        
        /* check if any channels to set range with */
        if (anim_data.first) {
+               short 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);
@@ -110,29 +114,39 @@ void get_graph_keyframe_extents(bAnimContext *ac, float *xmin, float *xmax, floa
                        float unitFac;
                        
                        /* get range */
-                       calc_fcurve_bounds(fcu, &txmin, &txmax, &tymin, &tymax, do_sel_only, include_handles);
-                       
-                       /* 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);
+                       if (calc_fcurve_bounds(fcu, &txmin, &txmax, &tymin, &tymax, do_sel_only, include_handles)) {
+                               /* 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, 0);
+                               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;
                        }
-                       
-                       /* apply unit corrections */
-                       unitFac = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, 0);
-                       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;
                }
                
                /* ensure that the extents are not too extreme that view implodes...*/
-               if ((xmin && xmax) && (fabsf(*xmax - *xmin) < 0.1f)) *xmax += 0.1f;
-               if ((ymin && ymax) && (fabsf(*ymax - *ymin) < 0.1f)) *ymax += 0.1f;
+               if (foundBounds) {
+                       if ((xmin && xmax) && (fabsf(*xmax - *xmin) < 0.1f)) *xmax += 0.1f;
+                       if ((ymin && ymax) && (fabsf(*ymax - *ymin) < 0.1f)) *ymax += 0.1f;
+               }
+               else {
+                       if (xmin) *xmin = (float)PSFRA;
+                       if (xmax) *xmax = (float)PEFRA;
+                       if (ymin) *ymin = -5;
+                       if (ymax) *ymax = 5;
+               }
                
                /* free memory */
                BLI_freelistN(&anim_data);
@@ -140,8 +154,8 @@ void get_graph_keyframe_extents(bAnimContext *ac, float *xmin, float *xmax, floa
        else {
                /* set default range */
                if (ac->scene) {
-                       if (xmin) *xmin = (float)ac->scene->r.sfra;
-                       if (xmax) *xmax = (float)ac->scene->r.efra;
+                       if (xmin) *xmin = (float)PSFRA;
+                       if (xmax) *xmax = (float)PEFRA;
                }
                else {
                        if (xmin) *xmin = -5;