Keyframe animation curves for TouchDesigner, as native C++ Custom Operators with a full Python API.
Build curves from keyframes with cubic Bézier interpolation, drive them from Python, and get them back as CHOP channels — without rebuilding an animation system out of Pattern CHOPs and Lookup CHOPs every time.
The animation maths lives in anim, a standalone C++20 library; these operators are the TouchDesigner binding around it.
| AnimationCHOP | Holds named animation channels and cooks them to CHOP samples. This is the operator you script against. |
| AnimationViewCHOP | Exposes an AnimationCHOP's internals as CHOP data — samples, keyframes, Bézier segments, channels — for building UI on top. |
| Keyframer.tox | A ready-made keyframe editor component built on both operators, with a GLSL-rendered curve view. |
- Named channels, each an independent curve; multiple channels per operator
- Per-keyframe interpolation:
Constant(step),Linear,Bezier - Bézier handle modes:
Flat,Smooth,Aligned,Free, and the aligned variantsAlignStrict/AlignFlex/AlignAdjustable - Per-channel extrapolation before the first and after the last keyframe:
Hold,Repeat,Mirror - Output modes: a fixed time range, an auto range fitted to the content, an index driven by an input CHOP, or a single scrubbed sequence index
- A complete Python API — create and edit channels and keyframes, evaluate the curve at any time, and save or restore whole-animation state as a plain dict
- Animations persist inside the
.toe: channels and keyframes are saved with the project and restored on load, with no external files
- TouchDesigner 2025.33070 or newer. Earlier builds will refuse to load the
operators. That build is where the Custom Operator API gained node data
persistence (
saveData/loadData), which is how animations are stored in the.toe; the operators target CHOP API version 10 / common API version 2. - Windows or macOS. Windows builds are x64.
-
Download the archive for your platform from Releases.
-
Copy the operator libraries into a
Pluginsfolder beside your.toe:MyProject/ MyProject.toe Plugins/ AnimationCHOP.dll (or .plugin on macOS) AnimationViewCHOP.dllTouchDesigner only loads Custom Operators from a
Pluginsfolder next to the project file, or from the system-wide plugin folder. -
Open the project. The first load of a new operator build shows a prompt asking you to trust it — approve it once.
-
Add an AnimationCHOP from the operator palette, or drop in the included
Keyframer.toxfor the full editor.
The release archive also contains an example project you can open directly.
Everything is driven from Python on the operator itself:
n = op('animation1')
# Create a channel and key it
tx = n.create_channel('tx')
tx.create_keyframe(0, 0)
tx.create_keyframe(30, 100, n.Function.BEZIER, n.HandleMode.SMOOTH)
# Evaluate anywhere on the curve
print(tx.evaluate(15))
# Edit in place...
tx.set_keyframe_value(1, 250)
# ...or read, modify, write back
kf = tx[0]
kf.function = n.Function.LINEAR
tx[0] = kf
# Save and restore the whole animation
state = n.state
n.clear()
n.state = stateOne thing to know before writing much against it: Channel is a live handle,
but Keyframe and Point are values. tx[0] gives you a detached copy, so
setting a property on it does not reach the channel until you write it back.
The docs explain why —
it is a consequence of how keyframes have to be re-solved against their
neighbours.
Full Python API reference under docs/:
- AnimationCHOP — the operator: channels, range, state
- Channel — a single curve
- Keyframe · Point
- Function · HandleMode · RangeEnd
git clone --recurse-submodules https://github.com/Actualize-Interactive/AnimationCHOP.git
cd AnimationCHOP(If you already cloned without submodules: git submodule update --init --recursive.)
# Windows
.\build.ps1# macOS
./build.shEither way the built operators are copied into td/Plugins/ so the example
project picks them up.
Windows vendors the CPython 3.11 headers and import libraries it needs, so there
is nothing to install. macOS builds against TouchDesigner's own Python framework
and expects TouchDesigner in /Applications.
cmake --workflow --preset dev # configure, build, run the unit testsThe pytest suite runs the real binding sources against a fake TouchDesigner context, so it needs no TouchDesigner install. There is also an integration harness that drives a real project inside TouchDesigner. See TESTING.md.
See CONTRIBUTING.md.
MIT — see LICENSE.
The TouchDesigner SDK headers under ext/td/ are Derivative Inc.'s and carry
their own terms; the vendored CPython headers are under the PSF License. See
NOTICE for the full third-party attribution.