Merged changes in the trunk up to revision 42116.
[blender.git] / source / blender / blenkernel / BKE_fcurve.h
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2009 Blender Foundation, Joshua Leung
19  * All rights reserved.
20  *
21  * Contributor(s): Joshua Leung (full recode)
22  *
23  * ***** END GPL LICENSE BLOCK *****
24  */
25
26 #ifndef BKE_FCURVE_H
27 #define BKE_FCURVE_H
28
29 /** \file BKE_fcurve.h
30  *  \ingroup bke
31  *  \author Joshua Leung
32  *  \since 2009
33  */
34
35 #ifdef __cplusplus
36 extern "C" {
37 #endif
38
39 struct FCurve;
40 struct FModifier;
41 struct ChannelDriver;
42 struct DriverVar;
43 struct DriverTarget;
44
45 struct bAction;
46 struct BezTriple;
47 struct StructRNA;
48 struct PointerRNA;
49 struct PropertyRNA;
50
51 #include "DNA_curve_types.h"
52
53 /* ************** Keyframe Tools ***************** */
54
55 typedef struct CfraElem {
56         struct CfraElem *next, *prev;
57         float cfra;
58         int sel;
59 } CfraElem;
60
61 void bezt_add_to_cfra_elem(ListBase *lb, struct BezTriple *bezt);
62
63 /* ************** F-Curve Drivers ***************** */
64
65 /* With these iterators for convenience, the variables "tarIndex" and "dtar" can be 
66  * accessed directly from the code using them, but it is not recommended that their
67  * values be changed to point at other slots...
68  */
69
70 /* convenience looper over ALL driver targets for a given variable (even the unused ones) */
71 #define DRIVER_TARGETS_LOOPER(dvar) \
72         { \
73                 DriverTarget *dtar= &dvar->targets[0]; \
74                 int tarIndex= 0; \
75                 for (; tarIndex < MAX_DRIVER_TARGETS; tarIndex++, dtar++)
76                  
77 /* convenience looper over USED driver targets only */
78 #define DRIVER_TARGETS_USED_LOOPER(dvar) \
79         { \
80                 DriverTarget *dtar= &dvar->targets[0]; \
81                 int tarIndex= 0; \
82                 for (; tarIndex < dvar->num_targets; tarIndex++, dtar++)
83                 
84 /* tidy up for driver targets loopers */
85 #define DRIVER_TARGETS_LOOPER_END \
86         }
87
88 /* ---------------------- */
89
90 void fcurve_free_driver(struct FCurve *fcu);
91 struct ChannelDriver *fcurve_copy_driver(struct ChannelDriver *driver);
92
93 void driver_free_variable(struct ChannelDriver *driver, struct DriverVar *dvar);
94 void driver_change_variable_type(struct DriverVar *dvar, int type);
95 struct DriverVar *driver_add_new_variable(struct ChannelDriver *driver);
96
97 float driver_get_variable_value (struct ChannelDriver *driver, struct DriverVar *dvar);
98
99 /* ************** F-Curve Modifiers *************** */
100
101 /* F-Curve Modifier Type-Info (fmi):
102  *  This struct provides function pointers for runtime, so that functions can be
103  *  written more generally (with fewer/no special exceptions for various modifiers).
104  *
105  *  Callers of these functions must check that they actually point to something useful,
106  *  as some constraints don't define some of these.
107  *
108  *  Warning: it is not too advisable to reorder order of members of this struct,
109  *                      as you'll have to edit quite a few ($FMODIFIER_NUM_TYPES) of these
110  *                      structs.
111  */
112 typedef struct FModifierTypeInfo {
113         /* admin/ident */
114         short type;                             /* FMODIFIER_TYPE_### */
115         short size;                             /* size in bytes of the struct */
116         short acttype;                  /* eFMI_Action_Types */
117         short requires;                 /* eFMI_Requirement_Flags */
118         char name[64];                  /* name of modifier in interface */
119         char structName[64];    /* name of struct for SDNA */
120         
121         /* data management function pointers - special handling */
122                 /* free any data that is allocated separately (optional) */
123         void (*free_data)(struct FModifier *fcm);
124                 /* copy any special data that is allocated separately (optional) */
125         void (*copy_data)(struct FModifier *fcm, struct FModifier *src);
126                 /* set settings for data that will be used for FCuModifier.data (memory already allocated using MEM_callocN) */
127         void (*new_data)(void *mdata);
128                 /* verifies that the modifier settings are valid */
129         void (*verify_data)(struct FModifier *fcm);
130         
131         /* evaluation */
132                 /* evaluate time that the modifier requires the F-Curve to be evaluated at */
133         float (*evaluate_modifier_time)(struct FCurve *fcu, struct FModifier *fcm, float cvalue, float evaltime);
134                 /* evaluate the modifier for the given time and 'accumulated' value */
135         void (*evaluate_modifier)(struct FCurve *fcu, struct FModifier *fcm, float *cvalue, float evaltime);
136 } FModifierTypeInfo;
137
138 /* Values which describe the behaviour of a FModifier Type */
139 typedef enum eFMI_Action_Types {
140                 /* modifier only modifies values outside of data range */
141         FMI_TYPE_EXTRAPOLATION = 0,
142                 /* modifier leaves data-points alone, but adjusts the interpolation between and around them */
143         FMI_TYPE_INTERPOLATION,
144                 /* modifier only modifies the values of points (but times stay the same) */
145         FMI_TYPE_REPLACE_VALUES,
146                 /* modifier generates a curve regardless of what came before */
147         FMI_TYPE_GENERATE_CURVE
148 } eFMI_Action_Types;
149
150 /* Flags for the requirements of a FModifier Type */
151 typedef enum eFMI_Requirement_Flags {
152                 /* modifier requires original data-points (kindof beats the purpose of a modifier stack?) */
153         FMI_REQUIRES_ORIGINAL_DATA              = (1<<0),
154                 /* modifier doesn't require on any preceding data (i.e. it will generate a curve). 
155                  * Use in conjunction with FMI_TYPE_GENRATE_CURVE 
156                  */
157         FMI_REQUIRES_NOTHING                    = (1<<1),
158                 /* refer to modifier instance */
159         FMI_REQUIRES_RUNTIME_CHECK              = (1<<2)
160 } eFMI_Requirement_Flags;
161
162 /* Function Prototypes for FModifierTypeInfo's */
163 FModifierTypeInfo *fmodifier_get_typeinfo(struct FModifier *fcm);
164 FModifierTypeInfo *get_fmodifier_typeinfo(int type);
165
166 /* ---------------------- */
167
168 struct FModifier *add_fmodifier(ListBase *modifiers, int type);
169 struct FModifier *copy_fmodifier(struct FModifier *src);
170 void copy_fmodifiers(ListBase *dst, ListBase *src);
171 int remove_fmodifier(ListBase *modifiers, struct FModifier *fcm);
172 void free_fmodifiers(ListBase *modifiers);
173
174 struct FModifier *find_active_fmodifier(ListBase *modifiers);
175 void set_active_fmodifier(ListBase *modifiers, struct FModifier *fcm);
176
177 short list_has_suitable_fmodifier(ListBase *modifiers, int mtype, short acttype);
178
179 float evaluate_time_fmodifiers(ListBase *modifiers, struct FCurve *fcu, float cvalue, float evaltime);
180 void evaluate_value_fmodifiers(ListBase *modifiers, struct FCurve *fcu, float *cvalue, float evaltime);
181
182 void fcurve_bake_modifiers(struct FCurve *fcu, int start, int end);
183
184 /* ************** F-Curves API ******************** */
185
186 /* -------- Data Managemnt  --------  */
187
188 void free_fcurve(struct FCurve *fcu);
189 struct FCurve *copy_fcurve(struct FCurve *fcu);
190
191 void free_fcurves(ListBase *list);
192 void copy_fcurves(ListBase *dst, ListBase *src);
193
194 /* find matching F-Curve in the given list of F-Curves */
195 struct FCurve *list_find_fcurve(ListBase *list, const char rna_path[], const int array_index);
196
197 struct FCurve *iter_step_fcurve (struct FCurve *fcu_iter, const char rna_path[]);
198
199 /* high level function to get an fcurve from C without having the rna */
200 struct FCurve *id_data_find_fcurve(ID *id, void *data, struct StructRNA *type, const char *prop_name, int index, char *driven);
201
202 /* Get list of LinkData's containing pointers to the F-Curves which control the types of data indicated 
203  *      e.g.  numMatches = list_find_data_fcurves(matches, &act->curves, "pose.bones[", "MyFancyBone");
204  */
205 int list_find_data_fcurves(ListBase *dst, ListBase *src, const char *dataPrefix, const char *dataName);
206
207 /* find an f-curve based on an rna property */
208 struct FCurve *rna_get_fcurve(struct PointerRNA *ptr, struct PropertyRNA *prop, int rnaindex, struct bAction **action, int *driven);
209
210 /* Binary search algorithm for finding where to 'insert' BezTriple with given frame number.
211  * Returns the index to insert at (data already at that index will be offset if replace is 0)
212  */
213 int binarysearch_bezt_index(struct BezTriple array[], float frame, int arraylen, short *replace);
214
215 /* get the time extents for F-Curve */
216 void calc_fcurve_range(struct FCurve *fcu, float *min, float *max,
217                        const short do_sel_only, const short do_min_length);
218
219 /* get the bounding-box extents for F-Curve */
220 void calc_fcurve_bounds(struct FCurve *fcu, float *xmin, float *xmax, float *ymin, float *ymax,
221                         const short do_sel_only);
222
223 /* .............. */
224
225 /* Are keyframes on F-Curve of any use (to final result, and to show in editors)? */
226 short fcurve_are_keyframes_usable(struct FCurve *fcu);
227
228 /* Can keyframes be added to F-Curve? */
229 short fcurve_is_keyframable(struct FCurve *fcu);
230
231 /* -------- Curve Sanity --------  */
232
233 void calchandles_fcurve(struct FCurve *fcu);
234 void testhandles_fcurve(struct FCurve *fcu, const short use_handle);
235 void sort_time_fcurve(struct FCurve *fcu);
236 short test_time_fcurve(struct FCurve *fcu);
237
238 void correct_bezpart(float *v1, float *v2, float *v3, float *v4);
239
240 /* -------- Evaluation --------  */
241
242 /* evaluate fcurve */
243 float evaluate_fcurve(struct FCurve *fcu, float evaltime);
244 /* evaluate fcurve and store value */
245 void calculate_fcurve(struct FCurve *fcu, float ctime);
246
247 /* ************* F-Curve Samples API ******************** */
248
249 /* -------- Defines --------  */
250
251 /* Basic signature for F-Curve sample-creation function 
252  *      - fcu: the F-Curve being operated on
253  *      - data: pointer to some specific data that may be used by one of the callbacks
254  */
255 typedef float (*FcuSampleFunc)(struct FCurve *fcu, void *data, float evaltime);
256
257 /* ----- Sampling Callbacks ------  */
258
259 /* Basic sampling callback which acts as a wrapper for evaluate_fcurve() */
260 float fcurve_samplingcb_evalcurve(struct FCurve *fcu, void *data, float evaltime);
261
262 /* -------- Main Methods --------  */
263
264 /* Main API function for creating a set of sampled curve data, given some callback function 
265  * used to retrieve the values to store.
266  */
267 void fcurve_store_samples(struct FCurve *fcu, void *data, int start, int end, FcuSampleFunc sample_cb);
268
269 #ifdef __cplusplus
270 }
271 #endif
272
273 #endif /* BKE_FCURVE_H*/