Blender V2.61 - r43446

graph_utils.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version. 
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2009 Blender Foundation.
00019  * All rights reserved.
00020  *
00021  * 
00022  * Contributor(s): Blender Foundation, Joshua Leung
00023  *
00024  * ***** END GPL LICENSE BLOCK *****
00025  */
00026 
00032 #include <string.h>
00033 #include <stdio.h>
00034 #include <math.h>
00035 #include <float.h>
00036 
00037 #include "DNA_anim_types.h"
00038 #include "DNA_space_types.h"
00039 #include "DNA_screen_types.h"
00040 
00041 #include "MEM_guardedalloc.h"
00042 
00043 #include "BLI_math.h"
00044 #include "BLI_blenlib.h"
00045 #include "BLI_editVert.h"
00046 #include "BLI_rand.h"
00047 
00048 #include "BKE_context.h"
00049 #include "BKE_fcurve.h"
00050 
00051 
00052 #include "WM_api.h"
00053 
00054 
00055 #include "ED_anim_api.h"
00056 
00057 
00058 #include "graph_intern.h"   // own include
00059 
00060 /* ************************************************************** */
00061 /* Active F-Curve */
00062 
00063 /* Find 'active' F-Curve. It must be editable, since that's the purpose of these buttons (subject to change).  
00064  * We return the 'wrapper' since it contains valuable context info (about hierarchy), which will need to be freed 
00065  * when the caller is done with it.
00066  *
00067  * NOTE: curve-visible flag isn't included, otherwise selecting a curve via list to edit is too cumbersome
00068  */
00069 bAnimListElem *get_active_fcurve_channel (bAnimContext *ac)
00070 {
00071     ListBase anim_data = {NULL, NULL};
00072     int filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_ACTIVE);
00073     size_t items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
00074     
00075     /* We take the first F-Curve only, since some other ones may have had 'active' flag set
00076      * if they were from linked data.
00077      */
00078     if (items) {
00079         bAnimListElem *ale= (bAnimListElem *)anim_data.first;
00080         
00081         /* remove first item from list, then free the rest of the list and return the stored one */
00082         BLI_remlink(&anim_data, ale);
00083         BLI_freelistN(&anim_data);
00084         
00085         return ale;
00086     }
00087     
00088     /* no active F-Curve */
00089     return NULL;
00090 }
00091 
00092 /* ************************************************************** */
00093 /* Operator Polling Callbacks */
00094 
00095 /* Check if there are any visible keyframes (for selection tools) */
00096 int graphop_visible_keyframes_poll (bContext *C)
00097 {
00098     bAnimContext ac;
00099     bAnimListElem *ale;
00100     ListBase anim_data = {NULL, NULL};
00101     ScrArea *sa= CTX_wm_area(C);
00102     size_t items;
00103     int filter;
00104     short found = 0;
00105     
00106     /* firstly, check if in Graph Editor */
00107     // TODO: also check for region?
00108     if ((sa == NULL) || (sa->spacetype != SPACE_IPO))
00109         return 0;
00110         
00111     /* try to init Anim-Context stuff ourselves and check */
00112     if (ANIM_animdata_get_context(C, &ac) == 0)
00113         return 0;
00114     
00115     /* loop over the visible (selection doesn't matter) F-Curves, and see if they're suitable
00116      * stopping on the first successful match
00117      */
00118     filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE);
00119     items = ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
00120     if (items == 0) 
00121         return 0;
00122     
00123     for (ale = anim_data.first; ale; ale= ale->next) {
00124         FCurve *fcu= (FCurve *)ale->data;
00125         
00126         /* visible curves for selection must fulfull the following criteria:
00127          *  - it has bezier keyframes
00128          *  - F-Curve modifiers do not interfere with the result too much 
00129          *    (i.e. the modifier-control drawing check returns false)
00130          */
00131         if (fcu->bezt == NULL)
00132             continue;
00133         if (fcurve_are_keyframes_usable(fcu)) {
00134             found = 1;
00135             break;
00136         }
00137     }
00138     
00139     /* cleanup and return findings */
00140     BLI_freelistN(&anim_data);
00141     return found;
00142 }
00143 
00144 /* Check if there are any visible + editable keyframes (for editing tools) */
00145 int graphop_editable_keyframes_poll (bContext *C)
00146 {
00147     bAnimContext ac;
00148     bAnimListElem *ale;
00149     ListBase anim_data = {NULL, NULL};
00150     ScrArea *sa= CTX_wm_area(C);
00151     size_t items;
00152     int filter;
00153     short found = 0;
00154     
00155     /* firstly, check if in Graph Editor */
00156     // TODO: also check for region?
00157     if ((sa == NULL) || (sa->spacetype != SPACE_IPO))
00158         return 0;
00159         
00160     /* try to init Anim-Context stuff ourselves and check */
00161     if (ANIM_animdata_get_context(C, &ac) == 0)
00162         return 0;
00163     
00164     /* loop over the editable F-Curves, and see if they're suitable
00165      * stopping on the first successful match
00166      */
00167     filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVE_VISIBLE);
00168     items = ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
00169     if (items == 0) 
00170         return 0;
00171     
00172     for (ale = anim_data.first; ale; ale= ale->next) {
00173         FCurve *fcu= (FCurve *)ale->data;
00174         
00175         /* editable curves must fulfull the following criteria:
00176          *  - it has bezier keyframes
00177          *  - it must not be protected from editing (this is already checked for with the foredit flag
00178          *  - F-Curve modifiers do not interfere with the result too much 
00179          *    (i.e. the modifier-control drawing check returns false)
00180          */
00181         if (fcu->bezt == NULL)
00182             continue;
00183         if (fcurve_is_keyframable(fcu)) {
00184             found = 1;
00185             break;
00186         }
00187     }
00188     
00189     /* cleanup and return findings */
00190     BLI_freelistN(&anim_data);
00191     return found;
00192 }
00193 
00194 /* has active F-Curve that's editable */
00195 int graphop_active_fcurve_poll (bContext *C)
00196 {
00197     bAnimContext ac;
00198     bAnimListElem *ale;
00199     ScrArea *sa= CTX_wm_area(C);
00200     short has_fcurve= 0;
00201     
00202     /* firstly, check if in Graph Editor */
00203     // TODO: also check for region?
00204     if ((sa == NULL) || (sa->spacetype != SPACE_IPO))
00205         return 0;
00206         
00207     /* try to init Anim-Context stuff ourselves and check */
00208     if (ANIM_animdata_get_context(C, &ac) == 0)
00209         return 0;
00210         
00211     /* try to get the Active F-Curve */
00212     ale= get_active_fcurve_channel(&ac);
00213     if (ale == NULL)
00214         return 0;
00215         
00216     /* free temp data... */
00217     has_fcurve= ((ale->data) && (ale->type == ANIMTYPE_FCURVE));
00218     if (has_fcurve) {
00219         FCurve *fcu= (FCurve *)ale->data;
00220         has_fcurve= (fcu->flag & FCURVE_VISIBLE)!=0;
00221     }
00222     
00223     MEM_freeN(ale);
00224     
00225     /* return success */
00226     return has_fcurve;
00227 }
00228 
00229 /* has selected F-Curve that's editable */
00230 int graphop_selected_fcurve_poll (bContext *C)
00231 {
00232     bAnimContext ac;
00233     ListBase anim_data = {NULL, NULL};
00234     ScrArea *sa= CTX_wm_area(C);
00235     size_t items;
00236     int filter;
00237     
00238     /* firstly, check if in Graph Editor */
00239     // TODO: also check for region?
00240     if ((sa == NULL) || (sa->spacetype != SPACE_IPO))
00241         return 0;
00242         
00243     /* try to init Anim-Context stuff ourselves and check */
00244     if (ANIM_animdata_get_context(C, &ac) == 0)
00245         return 0;
00246     
00247     /* get the editable + selected F-Curves, and as long as we got some, we can return 
00248      * NOTE: curve-visible flag isn't included, otherwise selecting a curve via list to edit is too cumbersome
00249      */
00250     filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT);
00251     items = ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
00252     if (items == 0) 
00253         return 0;
00254     
00255     /* cleanup and return findings */
00256     BLI_freelistN(&anim_data);
00257     return 1;
00258 }
00259 
00260 /* ************************************************************** */