1 /* 2 * This program is free software; you can redistribute it and/or 3 * modify it under the terms of the GNU General Public License 4 * as published by the Free Software Foundation; either version 2 5 * of the License, or (at your option) any later version. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU General Public License for more details. 11 * 12 * You should have received a copy of the GNU General Public License 13 * along with this program; if not, write to the Free Software Foundation, 14 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 15 * 16 * The Original Code is Copyright (C) 2009 Blender Foundation, Joshua Leung 17 * All rights reserved. 18 */ 19 20 #pragma once 21 22 /** \file 23 * \ingroup bke 24 */ 25 26 #include "DNA_curve_types.h" 27 28 #ifdef __cplusplus 29 extern "C" { 30 #endif 31 32 struct ChannelDriver; 33 struct FCM_EnvelopeData; 34 struct FCurve; 35 struct FModifier; 36 37 struct AnimData; 38 struct AnimationEvalContext; 39 struct BezTriple; 40 struct BlendDataReader; 41 struct BlendExpander; 42 struct BlendLibReader; 43 struct BlendWriter; 44 struct LibraryForeachIDData; 45 struct PathResolvedRNA; 46 struct PointerRNA; 47 struct PropertyRNA; 48 struct StructRNA; 49 struct bAction; 50 struct bContext; 51 52 /* ************** Keyframe Tools ***************** */ 53 54 typedef struct CfraElem { 55 struct CfraElem *next, *prev; 56 float cfra; 57 int sel; 58 } CfraElem; 59 60 /* ************** F-Curve Modifiers *************** */ 61 62 /* F-Curve Modifier Type-Info (fmi): 63 * This struct provides function pointers for runtime, so that functions can be 64 * written more generally (with fewer/no special exceptions for various modifiers). 65 * 66 * Callers of these functions must check that they actually point to something useful, 67 * as some constraints don't define some of these. 68 * 69 * Warning: it is not too advisable to reorder order of members of this struct, 70 * as you'll have to edit quite a few ($FMODIFIER_NUM_TYPES) of these 71 * structs. 72 */ 73 typedef struct FModifierTypeInfo { 74 /* admin/ident */ 75 /** #FMODIFIER_TYPE_* */ 76 short type; 77 /** size in bytes of the struct. */ 78 short size; 79 /** #eFMI_Action_Types. */ 80 short acttype; 81 /** #eFMI_Requirement_Flags. */ 82 short requires; 83 /** name of modifier in interface. */ 84 char name[64]; 85 /** name of struct for SDNA. */ 86 char structName[64]; 87 /** Size of buffer that can be reused between time and value evaluation. */ 88 uint storage_size; 89 90 /* data management function pointers - special handling */ 91 /** Free any data that is allocated separately (optional). */ 92 void (*free_data)(struct FModifier *fcm); 93 /** Copy any special data that is allocated separately (optional). */ 94 void (*copy_data)(struct FModifier *fcm, const struct FModifier *src); 95 /** 96 * Set settings for data that will be used for FCuModifier.data 97 * (memory already allocated using #MEM_callocN). */ 98 void (*new_data)(void *mdata); 99 /** Verifies that the modifier settings are valid */ 100 void (*verify_data)(struct FModifier *fcm); 101 102 /* evaluation */ 103 /** Evaluate time that the modifier requires the F-Curve to be evaluated at */ 104 float (*evaluate_modifier_time)( 105 struct FCurve *fcu, struct FModifier *fcm, float cvalue, float evaltime, void *storage); 106 /** Evaluate the modifier for the given time and 'accumulated' value */ 107 void (*evaluate_modifier)( 108 struct FCurve *fcu, struct FModifier *fcm, float *cvalue, float evaltime, void *storage); 109 } FModifierTypeInfo; 110 111 /* Values which describe the behavior of a FModifier Type */ 112 typedef enum eFMI_Action_Types { 113 /* modifier only modifies values outside of data range */ 114 FMI_TYPE_EXTRAPOLATION = 0, 115 /* modifier leaves data-points alone, but adjusts the interpolation between and around them */ 116 FMI_TYPE_INTERPOLATION, 117 /* modifier only modifies the values of points (but times stay the same) */ 118 FMI_TYPE_REPLACE_VALUES, 119 /* modifier generates a curve regardless of what came before */ 120 FMI_TYPE_GENERATE_CURVE, 121 } eFMI_Action_Types; 122 123 /* Flags for the requirements of a FModifier Type */ 124 typedef enum eFMI_Requirement_Flags { 125 /* modifier requires original data-points (kindof beats the purpose of a modifier stack?) */ 126 FMI_REQUIRES_ORIGINAL_DATA = (1 << 0), 127 /* modifier doesn't require on any preceding data (i.e. it will generate a curve). 128 * Use in conjunction with FMI_TYPE_GENRATE_CURVE 129 */ 130 FMI_REQUIRES_NOTHING = (1 << 1), 131 /* refer to modifier instance */ 132 FMI_REQUIRES_RUNTIME_CHECK = (1 << 2), 133 } eFMI_Requirement_Flags; 134 135 /* Function Prototypes for FModifierTypeInfo's */ 136 const FModifierTypeInfo *fmodifier_get_typeinfo(const struct FModifier *fcm); 137 const FModifierTypeInfo *get_fmodifier_typeinfo(const int type); 138 139 /* ---------------------- */ 140 141 struct FModifier *add_fmodifier(ListBase *modifiers, int type, struct FCurve *owner_fcu); 142 struct FModifier *copy_fmodifier(const struct FModifier *src); 143 void copy_fmodifiers(ListBase *dst, const ListBase *src); 144 bool remove_fmodifier(ListBase *modifiers, struct FModifier *fcm); 145 void free_fmodifiers(ListBase *modifiers); 146 147 struct FModifier *find_active_fmodifier(ListBase *modifiers); 148 void set_active_fmodifier(ListBase *modifiers, struct FModifier *fcm); 149 150 bool list_has_suitable_fmodifier(ListBase *modifiers, int mtype, short acttype); 151 152 typedef struct FModifiersStackStorage { 153 uint modifier_count; 154 uint size_per_modifier; 155 void *buffer; 156 } FModifiersStackStorage; 157 158 uint evaluate_fmodifiers_storage_size_per_modifier(ListBase *modifiers); 159 float evaluate_time_fmodifiers(FModifiersStackStorage *storage, 160 ListBase *modifiers, 161 struct FCurve *fcu, 162 float cvalue, 163 float evaltime); 164 void evaluate_value_fmodifiers(FModifiersStackStorage *storage, 165 ListBase *modifiers, 166 struct FCurve *fcu, 167 float *cvalue, 168 float evaltime); 169 170 void fcurve_bake_modifiers(struct FCurve *fcu, int start, int end); 171 172 int BKE_fcm_envelope_find_index(struct FCM_EnvelopeData *array, 173 float frame, 174 int arraylen, 175 bool *r_exists); 176 177 /* ************** F-Curves API ******************** */ 178 179 /* threshold for binary-searching keyframes - threshold here should be good enough for now, 180 * but should become userpref */ 181 #define BEZT_BINARYSEARCH_THRESH 0.01f /* was 0.00001, but giving errors */ 182 183 /* -------- Data Management -------- */ 184 struct FCurve *BKE_fcurve_create(void); 185 void BKE_fcurve_free(struct FCurve *fcu); 186 struct FCurve *BKE_fcurve_copy(const struct FCurve *fcu); 187 188 void BKE_fcurves_free(ListBase *list); 189 void BKE_fcurves_copy(ListBase *dst, ListBase *src); 190 191 void BKE_fcurve_foreach_id(struct FCurve *fcu, struct LibraryForeachIDData *data); 192 193 /* find matching F-Curve in the given list of F-Curves */ 194 struct FCurve *BKE_fcurve_find(ListBase *list, const char rna_path[], const int array_index); 195 196 struct FCurve *BKE_fcurve_iter_step(struct FCurve *fcu_iter, const char rna_path[]); 197 198 /* high level function to get an fcurve from C without having the rna */ 199 struct FCurve *id_data_find_fcurve( 200 ID *id, void *data, struct StructRNA *type, const char *prop_name, int index, bool *r_driven); 201 202 /* Get list of LinkData's containing pointers to the F-Curves which control the types of data 203 * indicated 204 * e.g. numMatches = BKE_fcurves_filter(matches, &act->curves, "pose.bones[", "MyFancyBone"); 205 */ 206 int BKE_fcurves_filter(ListBase *dst, ListBase *src, const char *dataPrefix, const char *dataName); 207 208 /* Find an f-curve based on an rna property. */ 209 struct FCurve *BKE_fcurve_find_by_rna(struct PointerRNA *ptr, 210 struct PropertyRNA *prop, 211 int rnaindex, 212 struct AnimData **r_adt, 213 struct bAction **r_action, 214 bool *r_driven, 215 bool *r_special); 216 /* Same as above, but takes a context data, 217 * temp hack needed for complex paths like texture ones. */ 218 struct FCurve *BKE_fcurve_find_by_rna_context_ui(struct bContext *C, 219 struct PointerRNA *ptr, 220 struct PropertyRNA *prop, 221 int rnaindex, 222 struct AnimData **r_animdata, 223 struct bAction **r_action, 224 bool *r_driven, 225 bool *r_special); 226 227 /* Binary search algorithm for finding where to 'insert' BezTriple with given frame number. 228 * Returns the index to insert at (data already at that index will be offset if replace is 0) 229 */ 230 int BKE_fcurve_bezt_binarysearch_index(struct BezTriple array[], 231 float frame, 232 int arraylen, 233 bool *r_replace); 234 235 /* get the time extents for F-Curve */ 236 bool BKE_fcurve_calc_range( 237 struct FCurve *fcu, float *min, float *max, const bool do_sel_only, const bool do_min_length); 238 239 /* get the bounding-box extents for F-Curve */ 240 bool BKE_fcurve_calc_bounds(struct FCurve *fcu, 241 float *xmin, 242 float *xmax, 243 float *ymin, 244 float *ymax, 245 const bool do_sel_only, 246 const bool include_handles); 247 248 void BKE_fcurve_active_keyframe_set(struct FCurve *fcu, const struct BezTriple *active_bezt); 249 int BKE_fcurve_active_keyframe_index(const struct FCurve *fcu); 250 251 /* .............. */ 252 253 /* Are keyframes on F-Curve of any use (to final result, and to show in editors)? */ 254 bool BKE_fcurve_are_keyframes_usable(struct FCurve *fcu); 255 256 /* Can keyframes be added to F-Curve? */ 257 bool BKE_fcurve_is_keyframable(struct FCurve *fcu); 258 bool BKE_fcurve_is_protected(struct FCurve *fcu); 259 260 /* The curve is an infinite cycle via Cycles modifier */ 261 bool BKE_fcurve_is_cyclic(struct FCurve *fcu); 262 263 /* Type of infinite cycle for a curve. */ 264 typedef enum eFCU_Cycle_Type { 265 FCU_CYCLE_NONE = 0, 266 /* The cycle repeats identically to the base range. */ 267 FCU_CYCLE_PERFECT, 268 /* The cycle accumulates the change between start and end keys. */ 269 FCU_CYCLE_OFFSET, 270 } eFCU_Cycle_Type; 271 272 eFCU_Cycle_Type BKE_fcurve_get_cycle_type(struct FCurve *fcu); 273 274 /* Recompute handles to neatly subdivide the prev-next range at bezt. */ 275 bool BKE_fcurve_bezt_subdivide_handles(struct BezTriple *bezt, 276 struct BezTriple *prev, 277 struct BezTriple *next, 278 float *r_pdelta); 279 280 /* -------- Curve Sanity -------- */ 281 282 void calchandles_fcurve(struct FCurve *fcu); 283 void calchandles_fcurve_ex(struct FCurve *fcu, eBezTriple_Flag handle_sel_flag); 284 void testhandles_fcurve(struct FCurve *fcu, eBezTriple_Flag sel_flag, const bool use_handle); 285 void sort_time_fcurve(struct FCurve *fcu); 286 bool test_time_fcurve(struct FCurve *fcu); 287 288 void BKE_fcurve_correct_bezpart(const float v1[2], float v2[2], float v3[2], const float v4[2]); 289 290 /* -------- Evaluation -------- */ 291 292 /* evaluate fcurve */ 293 float evaluate_fcurve(struct FCurve *fcu, float evaltime); 294 float evaluate_fcurve_only_curve(struct FCurve *fcu, float evaltime); 295 float evaluate_fcurve_driver(struct PathResolvedRNA *anim_rna, 296 struct FCurve *fcu, 297 struct ChannelDriver *driver_orig, 298 const struct AnimationEvalContext *anim_eval_context); 299 bool BKE_fcurve_is_empty(struct FCurve *fcu); 300 /* evaluate fcurve and store value */ 301 float calculate_fcurve(struct PathResolvedRNA *anim_rna, 302 struct FCurve *fcu, 303 const struct AnimationEvalContext *anim_eval_context); 304 305 /* ************* F-Curve Samples API ******************** */ 306 307 /* -------- Defines -------- */ 308 309 /* Basic signature for F-Curve sample-creation function 310 * - fcu: the F-Curve being operated on 311 * - data: pointer to some specific data that may be used by one of the callbacks 312 */ 313 typedef float (*FcuSampleFunc)(struct FCurve *fcu, void *data, float evaltime); 314 315 /* ----- Sampling Callbacks ------ */ 316 317 /* Basic sampling callback which acts as a wrapper for evaluate_fcurve() */ 318 float fcurve_samplingcb_evalcurve(struct FCurve *fcu, void *data, float evaltime); 319 320 /* -------- Main Methods -------- */ 321 322 /* Main API function for creating a set of sampled curve data, given some callback function 323 * used to retrieve the values to store. 324 */ 325 void fcurve_store_samples( 326 struct FCurve *fcu, void *data, int start, int end, FcuSampleFunc sample_cb); 327 328 /* ************* F-Curve .blend file API ******************** */ 329 330 void BKE_fmodifiers_blend_write(struct BlendWriter *writer, struct ListBase *fmodifiers); 331 void BKE_fmodifiers_blend_read_data(struct BlendDataReader *reader, 332 ListBase *fmodifiers, 333 struct FCurve *curve); 334 void BKE_fmodifiers_blend_read_lib(struct BlendLibReader *reader, 335 struct ID *id, 336 struct ListBase *fmodifiers); 337 void BKE_fmodifiers_blend_read_expand(struct BlendExpander *expander, struct ListBase *fmodifiers); 338 339 void BKE_fcurve_blend_write(struct BlendWriter *writer, struct ListBase *fcurves); 340 void BKE_fcurve_blend_read_data(struct BlendDataReader *reader, struct ListBase *fcurves); 341 void BKE_fcurve_blend_read_lib(struct BlendLibReader *reader, 342 struct ID *id, 343 struct ListBase *fcurves); 344 void BKE_fcurve_blend_read_expand(struct BlendExpander *expander, struct ListBase *fcurves); 345 346 #ifdef __cplusplus 347 } 348 #endif 349