Page MenuHome

Make auto handle placement aware of cyclic extrapolation.
ClosedPublic

Authored by Alexander Gavrilov (angavrilov) on Aug 11 2017, 7:53 PM.

Details

Summary

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.

Diff Detail

Repository
rB Blender

Event Timeline

After looking at this again, it's not actually as bad as I initially suspected.

source/blender/blenkernel/BKE_fcurve.h
192

Instead of two functions, I'd be tempted to only have a single one (keeping the original name), with the FCurve arg as an optional last arg (e.g. FCurve *owner_fcu)

source/blender/blenkernel/intern/fcurve.c
945

Ugh... since we're doing these checks in several places, I'd consider defining a macro for these checks within this function, and using it for these two lines and also on 959.

e.g.

#define BEZT_HAS_AUTOH(bz)  ELEM((bz)->h1, HD_AUTO, HD_AUTO_ANIM) && ELEM((bz)->h2, HD_AUTO, HD_AUTO_ANIM)

...

bool cycle = detect_cycle_modifier(fcu) && BEZT_HAS_AUTOH(first) && BEZT_HAS_AUTOH(last);
972–973

Looks like it's time to use braces here for the if/else, instead of keeping everything on single lines

source/blender/blenkernel/intern/fmodifier.c
1124

See comments above (in the header). Is this function really necessary?!

source/blender/blenloader/intern/readfile.c
2397

lib_link() is only for stuff from another datablock. You should only need to fix the link in direct_link() since the F-Curve and F-Modifiers should be in the same datablock.

source/blender/editors/animation/fmodifier_ui.c
103

This should be handled in the remove_fmodifier function. Saves spraying this logic all over the code.

source/blender/makesdna/DNA_anim_types.h
55

IIRC, a few of the other RNA callbacks may also benefit from having this info

source/blender/makesrna/intern/rna_fcurve.c
499

This should probably be in add_fmodifier

512

This shouldn't be here (or in that other place in the UI code). It should instead be in remove_fmodifier)

595

It'd be better to have a rna_FModCycles_update(...) that looks something like

static void rna_FModCycles_update(...)
{
    if (fcm->curve) {
        calchandles_fcurve(fcm->curve);
    }
    rna_FModifier_update(bmain, scene, ptr);
}
Joshua Leung (aligorith) requested changes to this revision.Aug 15 2017, 2:48 PM
This revision now requires changes to proceed.Aug 15 2017, 2:48 PM
Alexander Gavrilov (angavrilov) edited edge metadata.

Change add_modifier and a few of the other points.

Alexander Gavrilov (angavrilov) marked 3 inline comments as done.Aug 19 2017, 2:48 PM
Alexander Gavrilov (angavrilov) added inline comments.
source/blender/blenloader/intern/readfile.c
2397

Basically I treated the field as runtime-only, with any values coming from saved data being considered untrustworthy. It's simpler than special file format upgrade code.

source/blender/editors/animation/fmodifier_ui.c
103

I'm not really sure to perform handle recalculation in a low level function that simply deletes a modifier. It would be even more abstraction level hackiness. Note that calchandles_fcurve doesn't just set flags, it actually recalculates everything.

Removed lib_link stuff and made BKE_fcurve_is_cyclic non-static.

Alexander Gavrilov (angavrilov) marked 2 inline comments as done.Sep 22 2017, 9:28 AM
Alexander Gavrilov (angavrilov) added inline comments.
source/blender/editors/animation/fmodifier_ui.c
103

After more investigation, remove_fmodifier is also indirectly called when deleting an fcurve, after most of its data is already freed. Trying to recalculate handles from remove_fmodifier in this case will access deallocated memory.

source/blender/makesrna/intern/rna_fcurve.c
499

Since remove_modifier can't update handles, neither should add_fmodifier.

595

The problem is that changing common properties like influence should also trigger an update, and using "rna_FModeCycles_update" for them would be strange.

Moved updates into add_modifier and remove_modifier.

Alexander Gavrilov (angavrilov) marked 6 inline comments as done.Oct 16 2017, 9:24 PM
This revision was automatically updated to reflect the committed changes.