diff options
author | Alexander Gavrilov <angavrilov@gmail.com> | 2017-10-17 19:39:10 +0300 |
---|---|---|
committer | Alexander Gavrilov <angavrilov@gmail.com> | 2017-10-17 19:39:10 +0300 |
commit | 1cb884be35e160740e97065afd6548e6a052c9d8 (patch) | |
tree | bc93243f86ec4f28f65c32619538e1e5857e0b6b /source/blender/blenkernel/intern/fmodifier.c | |
parent | 7d3723a54d8a809d5c95b235e90a12e2f6295f0e (diff) |
Make auto handle placement aware of cyclic extrapolation.
Cyclic extrapolation is implemented as an f-curve modifier, so this
technically violates abstraction separation and is something of a hack.
However without such behavior achieving smooth looping with cyclic
extrapolation is extremely cumbersome.
The new behavior is applied when the first modifier is Cyclic
extrapolation in Repeat or Repeat with Offset mode without
using influence, repeat count or range restrictions.
This change in behavior means that curve handles have to be updated
when the modifier is added, removed or its options change. Due to the
way code is structured, it seems it requires a helper link to the
containing curve from the modifier object.
Reviewers: aligorith
Differential Revision: https://developer.blender.org/D2783
Diffstat (limited to 'source/blender/blenkernel/intern/fmodifier.c')
-rw-r--r-- | source/blender/blenkernel/intern/fmodifier.c | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c index f1732ee7a9a..f1834bdf8a6 100644 --- a/source/blender/blenkernel/intern/fmodifier.c +++ b/source/blender/blenkernel/intern/fmodifier.c @@ -1077,7 +1077,7 @@ const FModifierTypeInfo *fmodifier_get_typeinfo(const FModifier *fcm) /* API --------------------------- */ /* Add a new F-Curve Modifier to the given F-Curve of a certain type */ -FModifier *add_fmodifier(ListBase *modifiers, int type) +FModifier *add_fmodifier(ListBase *modifiers, int type, FCurve *owner_fcu) { const FModifierTypeInfo *fmi = get_fmodifier_typeinfo(type); FModifier *fcm; @@ -1098,6 +1098,7 @@ FModifier *add_fmodifier(ListBase *modifiers, int type) fcm = MEM_callocN(sizeof(FModifier), "F-Curve Modifier"); fcm->type = type; fcm->flag = FMODIFIER_FLAG_EXPANDED; + fcm->curve = owner_fcu; fcm->influence = 1.0f; BLI_addtail(modifiers, fcm); @@ -1111,6 +1112,10 @@ FModifier *add_fmodifier(ListBase *modifiers, int type) /* init custom settings if necessary */ if (fmi->new_data) fmi->new_data(fcm->data); + + /* update the fcurve if the Cycles modifier is added */ + if ((owner_fcu) && (type == FMODIFIER_TYPE_CYCLES)) + calchandles_fcurve(owner_fcu); /* return modifier for further editing */ return fcm; @@ -1129,6 +1134,7 @@ FModifier *copy_fmodifier(const FModifier *src) /* copy the base data, clearing the links */ dst = MEM_dupallocN(src); dst->next = dst->prev = NULL; + dst->curve = NULL; /* make a new copy of the F-Modifier's data */ dst->data = MEM_dupallocN(src->data); @@ -1157,6 +1163,7 @@ void copy_fmodifiers(ListBase *dst, const ListBase *src) /* make a new copy of the F-Modifier's data */ fcm->data = MEM_dupallocN(fcm->data); + fcm->curve = NULL; /* only do specific constraints if required */ if (fmi && fmi->copy_data) @@ -1173,6 +1180,9 @@ bool remove_fmodifier(ListBase *modifiers, FModifier *fcm) if (fcm == NULL) return false; + /* removing the cycles modifier requires a handle update */ + FCurve *update_fcu = (fcm->type == FMODIFIER_TYPE_CYCLES) ? fcm->curve : NULL; + /* free modifier's special data (stored inside fcm->data) */ if (fcm->data) { if (fmi && fmi->free_data) @@ -1185,6 +1195,11 @@ bool remove_fmodifier(ListBase *modifiers, FModifier *fcm) /* remove modifier from stack */ if (modifiers) { BLI_freelinkN(modifiers, fcm); + + /* update the fcurve if the Cycles modifier is removed */ + if (update_fcu) + calchandles_fcurve(update_fcu); + return true; } else { |