Blender V2.61 - r43446
|
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 /* ************************************************************** */