Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/fcurve.c')
-rw-r--r--source/blender/blenkernel/intern/fcurve.c332
1 files changed, 320 insertions, 12 deletions
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index acbbf50701a..ba4a1e7b310 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -48,6 +48,8 @@
#include "BKE_lib_query.h"
#include "BKE_nla.h"
+#include "BLO_read_write.h"
+
#include "RNA_access.h"
#include "CLG_log.h"
@@ -57,13 +59,21 @@
static CLG_LogRef LOG = {"bke.fcurve"};
-/* ************************** Data-Level Functions ************************* */
+/* -------------------------------------------------------------------- */
+/** \name F-Curve Data Create
+ * \{ */
+
FCurve *BKE_fcurve_create(void)
{
FCurve *fcu = MEM_callocN(sizeof(FCurve), __func__);
return fcu;
}
-/* ---------------------- Freeing --------------------------- */
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name F-Curve Data Free
+ * \{ */
/* Frees the F-Curve itself too, so make sure BLI_remlink is called before calling this... */
void BKE_fcurve_free(FCurve *fcu)
@@ -110,7 +120,11 @@ void BKE_fcurves_free(ListBase *list)
BLI_listbase_clear(list);
}
-/* ---------------------- Copy --------------------------- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name F-Curve Data Copy
+ * \{ */
/* duplicate an F-Curve */
FCurve *BKE_fcurve_copy(const FCurve *fcu)
@@ -320,7 +334,7 @@ int BKE_fcurves_filter(ListBase *dst, ListBase *src, const char *dataPrefix, con
if (ELEM(NULL, dst, src, dataPrefix, dataName)) {
return 0;
}
- else if ((dataPrefix[0] == 0) || (dataName[0] == 0)) {
+ if ((dataPrefix[0] == 0) || (dataName[0] == 0)) {
return 0;
}
@@ -478,7 +492,11 @@ FCurve *BKE_fcurve_find_by_rna_context_ui(bContext *C,
return fcu;
}
-/* ----------------- Finding Keyframes/Extents -------------------------- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Finding Keyframes/Extents
+ * \{ */
/* Binary search algorithm for finding where to insert BezTriple,
* with optional argument for precision required.
@@ -809,7 +827,11 @@ bool BKE_fcurve_calc_range(
return foundvert;
}
-/* ----------------- Status Checks -------------------------- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Status Checks
+ * \{ */
/* Are keyframes on F-Curve of any use?
* Usability of keyframes refers to whether they should be displayed,
@@ -899,7 +921,11 @@ bool BKE_fcurve_is_keyframable(FCurve *fcu)
return true;
}
-/* ***************************** Keyframe Column Tools ********************************* */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Keyframe Column Tools
+ * \{ */
/* add a BezTriple to a column */
void bezt_add_to_cfra_elem(ListBase *lb, BezTriple *bezt)
@@ -915,7 +941,7 @@ void bezt_add_to_cfra_elem(ListBase *lb, BezTriple *bezt)
return;
}
/* should key be inserted before this column? */
- else if (ce->cfra > bezt->vec[1][0]) {
+ if (ce->cfra > bezt->vec[1][0]) {
break;
}
}
@@ -933,7 +959,12 @@ void bezt_add_to_cfra_elem(ListBase *lb, BezTriple *bezt)
cen->sel = bezt->f2;
}
-/* ***************************** Samples Utilities ******************************* */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Samples Utilities
+ * \{ */
+
/* Some utilities for working with FPoints (i.e. 'sampled' animation curve data, such as
* data imported from BVH/Mocap files), which are specialized for use with high density datasets,
* which BezTriples/Keyframe data are ill equipped to do.
@@ -1271,7 +1302,11 @@ short test_time_fcurve(FCurve *fcu)
return 0;
}
-/* ***************************** Curve Calculations ********************************* */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name F-Curve Calculations
+ * \{ */
/* The total length of the handles is not allowed to be more
* than the horizontal distance between (v1-v4).
@@ -1449,7 +1484,11 @@ static void berekeny(float f1, float f2, float f3, float f4, float *o, int b)
}
}
-/* -------------------------- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name F-Curve Evaluation
+ * \{ */
static float fcurve_eval_keyframes_extrapolate(
FCurve *fcu, BezTriple *bezts, float evaltime, int endpoint_offset, int direction_to_neighbor)
@@ -1812,7 +1851,11 @@ static float fcurve_eval_samples(FCurve *fcu, FPoint *fpts, float evaltime)
return cvalue;
}
-/* ***************************** F-Curve - Evaluation ********************************* */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name F-Curve - Evaluation
+ * \{ */
/* Evaluate and return the value of the given F-Curve at the specified frame ("evaltime")
* Note: this is also used for drivers
@@ -1947,3 +1990,268 @@ float calculate_fcurve(PathResolvedRNA *anim_rna,
fcu->curval = curval; /* debug display only, not thread safe! */
return curval;
}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name F-Curve - .blend file API
+ * \{ */
+
+void BKE_fmodifiers_blend_write(BlendWriter *writer, ListBase *fmodifiers)
+{
+ /* Write all modifiers first (for faster reloading) */
+ BLO_write_struct_list(writer, FModifier, fmodifiers);
+
+ /* Modifiers */
+ LISTBASE_FOREACH (FModifier *, fcm, fmodifiers) {
+ const FModifierTypeInfo *fmi = fmodifier_get_typeinfo(fcm);
+
+ /* Write the specific data */
+ if (fmi && fcm->data) {
+ /* firstly, just write the plain fmi->data struct */
+ BLO_write_struct_by_name(writer, fmi->structName, fcm->data);
+
+ /* do any modifier specific stuff */
+ switch (fcm->type) {
+ case FMODIFIER_TYPE_GENERATOR: {
+ FMod_Generator *data = fcm->data;
+
+ /* write coefficients array */
+ if (data->coefficients) {
+ BLO_write_float_array(writer, data->arraysize, data->coefficients);
+ }
+
+ break;
+ }
+ case FMODIFIER_TYPE_ENVELOPE: {
+ FMod_Envelope *data = fcm->data;
+
+ /* write envelope data */
+ if (data->data) {
+ BLO_write_struct_array(writer, FCM_EnvelopeData, data->totvert, data->data);
+ }
+
+ break;
+ }
+ case FMODIFIER_TYPE_PYTHON: {
+ FMod_Python *data = fcm->data;
+
+ /* Write ID Properties -- and copy this comment EXACTLY for easy finding
+ * of library blocks that implement this.*/
+ IDP_BlendWrite(writer, data->prop);
+
+ break;
+ }
+ }
+ }
+ }
+}
+
+void BKE_fmodifiers_blend_data_read(BlendDataReader *reader, ListBase *fmodifiers, FCurve *curve)
+{
+ LISTBASE_FOREACH (FModifier *, fcm, fmodifiers) {
+ /* relink general data */
+ BLO_read_data_address(reader, &fcm->data);
+ fcm->curve = curve;
+
+ /* do relinking of data for specific types */
+ switch (fcm->type) {
+ case FMODIFIER_TYPE_GENERATOR: {
+ FMod_Generator *data = (FMod_Generator *)fcm->data;
+ BLO_read_float_array(reader, data->arraysize, &data->coefficients);
+ break;
+ }
+ case FMODIFIER_TYPE_ENVELOPE: {
+ FMod_Envelope *data = (FMod_Envelope *)fcm->data;
+
+ BLO_read_data_address(reader, &data->data);
+
+ break;
+ }
+ case FMODIFIER_TYPE_PYTHON: {
+ FMod_Python *data = (FMod_Python *)fcm->data;
+
+ BLO_read_data_address(reader, &data->prop);
+ IDP_BlendDataRead(reader, &data->prop);
+
+ break;
+ }
+ }
+ }
+}
+
+void BKE_fmodifiers_blend_lib_read(BlendLibReader *reader, ID *id, ListBase *fmodifiers)
+{
+ LISTBASE_FOREACH (FModifier *, fcm, fmodifiers) {
+ /* data for specific modifiers */
+ switch (fcm->type) {
+ case FMODIFIER_TYPE_PYTHON: {
+ FMod_Python *data = (FMod_Python *)fcm->data;
+ BLO_read_id_address(reader, id->lib, &data->script);
+ break;
+ }
+ }
+ }
+}
+
+void BKE_fmodifiers_blend_expand(BlendExpander *expander, ListBase *fmodifiers)
+{
+ LISTBASE_FOREACH (FModifier *, fcm, fmodifiers) {
+ /* library data for specific F-Modifier types */
+ switch (fcm->type) {
+ case FMODIFIER_TYPE_PYTHON: {
+ FMod_Python *data = (FMod_Python *)fcm->data;
+ BLO_expand(expander, data->script);
+ break;
+ }
+ }
+ }
+}
+
+void BKE_fcurve_blend_write(BlendWriter *writer, ListBase *fcurves)
+{
+ BLO_write_struct_list(writer, FCurve, fcurves);
+ LISTBASE_FOREACH (FCurve *, fcu, fcurves) {
+ /* curve data */
+ if (fcu->bezt) {
+ BLO_write_struct_array(writer, BezTriple, fcu->totvert, fcu->bezt);
+ }
+ if (fcu->fpt) {
+ BLO_write_struct_array(writer, FPoint, fcu->totvert, fcu->fpt);
+ }
+
+ if (fcu->rna_path) {
+ BLO_write_string(writer, fcu->rna_path);
+ }
+
+ /* driver data */
+ if (fcu->driver) {
+ ChannelDriver *driver = fcu->driver;
+
+ BLO_write_struct(writer, ChannelDriver, driver);
+
+ /* variables */
+ BLO_write_struct_list(writer, DriverVar, &driver->variables);
+ LISTBASE_FOREACH (DriverVar *, dvar, &driver->variables) {
+ DRIVER_TARGETS_USED_LOOPER_BEGIN (dvar) {
+ if (dtar->rna_path) {
+ BLO_write_string(writer, dtar->rna_path);
+ }
+ }
+ DRIVER_TARGETS_LOOPER_END;
+ }
+ }
+
+ /* write F-Modifiers */
+ BKE_fmodifiers_blend_write(writer, &fcu->modifiers);
+ }
+}
+
+void BKE_fcurve_blend_data_read(BlendDataReader *reader, ListBase *fcurves)
+{
+ /* link F-Curve data to F-Curve again (non ID-libs) */
+ LISTBASE_FOREACH (FCurve *, fcu, fcurves) {
+ /* curve data */
+ BLO_read_data_address(reader, &fcu->bezt);
+ BLO_read_data_address(reader, &fcu->fpt);
+
+ /* rna path */
+ BLO_read_data_address(reader, &fcu->rna_path);
+
+ /* group */
+ BLO_read_data_address(reader, &fcu->grp);
+
+ /* clear disabled flag - allows disabled drivers to be tried again ([#32155]),
+ * but also means that another method for "reviving disabled F-Curves" exists
+ */
+ fcu->flag &= ~FCURVE_DISABLED;
+
+ /* driver */
+ BLO_read_data_address(reader, &fcu->driver);
+ if (fcu->driver) {
+ ChannelDriver *driver = fcu->driver;
+
+ /* Compiled expression data will need to be regenerated
+ * (old pointer may still be set here). */
+ driver->expr_comp = NULL;
+ driver->expr_simple = NULL;
+
+ /* give the driver a fresh chance - the operating environment may be different now
+ * (addons, etc. may be different) so the driver namespace may be sane now [#32155]
+ */
+ driver->flag &= ~DRIVER_FLAG_INVALID;
+
+ /* relink variables, targets and their paths */
+ BLO_read_list(reader, &driver->variables);
+ LISTBASE_FOREACH (DriverVar *, dvar, &driver->variables) {
+ DRIVER_TARGETS_LOOPER_BEGIN (dvar) {
+ /* only relink the targets being used */
+ if (tarIndex < dvar->num_targets) {
+ BLO_read_data_address(reader, &dtar->rna_path);
+ }
+ else {
+ dtar->rna_path = NULL;
+ }
+ }
+ DRIVER_TARGETS_LOOPER_END;
+ }
+ }
+
+ /* modifiers */
+ BLO_read_list(reader, &fcu->modifiers);
+ BKE_fmodifiers_blend_data_read(reader, &fcu->modifiers, fcu);
+ }
+}
+
+void BKE_fcurve_blend_lib_read(BlendLibReader *reader, ID *id, ListBase *fcurves)
+{
+ if (fcurves == NULL) {
+ return;
+ }
+
+ /* relink ID-block references... */
+ LISTBASE_FOREACH (FCurve *, fcu, fcurves) {
+ /* driver data */
+ if (fcu->driver) {
+ ChannelDriver *driver = fcu->driver;
+ LISTBASE_FOREACH (DriverVar *, dvar, &driver->variables) {
+ DRIVER_TARGETS_LOOPER_BEGIN (dvar) {
+ /* only relink if still used */
+ if (tarIndex < dvar->num_targets) {
+ BLO_read_id_address(reader, id->lib, &dtar->id);
+ }
+ else {
+ dtar->id = NULL;
+ }
+ }
+ DRIVER_TARGETS_LOOPER_END;
+ }
+ }
+
+ /* modifiers */
+ BKE_fmodifiers_blend_lib_read(reader, id, &fcu->modifiers);
+ }
+}
+
+void BKE_fcurve_blend_expand(BlendExpander *expander, ListBase *fcurves)
+{
+ LISTBASE_FOREACH (FCurve *, fcu, fcurves) {
+ /* Driver targets if there is a driver */
+ if (fcu->driver) {
+ ChannelDriver *driver = fcu->driver;
+
+ LISTBASE_FOREACH (DriverVar *, dvar, &driver->variables) {
+ DRIVER_TARGETS_LOOPER_BEGIN (dvar) {
+ // TODO: only expand those that are going to get used?
+ BLO_expand(expander, dtar->id);
+ }
+ DRIVER_TARGETS_LOOPER_END;
+ }
+ }
+
+ /* F-Curve Modifiers */
+ BKE_fmodifiers_blend_expand(expander, &fcu->modifiers);
+ }
+}
+
+/** \} */