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