CTrack Manual


A CTrack represents an animation track of a parameter of an object in Cinema 4D. The tracks are stored with the animated object and contain curves and keys.

CTrack objects are an instance of CTbase.

// This example creates a track for the "Camera" parameter of the given Stage object.
// Two keyframes for the given two camera objects are created.
// search for the track and create a new one if needed
CTrack* track = stage->FindCTrack(trackID);
if (track == nullptr)
track = CTrack::Alloc(stage, trackID);
if (track == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
// add track to stage object
CCurve* const curve = track->GetCurve();
if (curve == nullptr)
return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
// Create first key
CKey* const key1 = curve->AddKey(BaseTime(0.0));
if (key1 == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
GeData data;
key1->SetGeData(curve, data);
// Create second key
CKey* const key2 = curve->AddKey(BaseTime(1.0));
if (key2 == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
GeData data;
key2->SetGeData(curve, data);
CTrack * FindCTrack(const DescID &id)
Definition: c4d_basetime.h:25
Definition: c4d_canimation.h:366
CKey * AddKey(const BaseTime &time, Int32 *nidx=nullptr, Bool bUndo=false, Bool SynchronizeKeys=false)
Definition: c4d_canimation.h:423
Represents a key in the CCurve of a track which represent the animation of a parameter.
Definition: c4d_canimation.h:58
void SetGeData(CCurve *seq, const GeData &d)
Sets the data of the key.
Definition: c4d_canimation.h:177
Definition: c4d_canimation.h:671
static CTrack * Alloc(BaseList2D *bl, const DescID &id)
CCurve * GetCurve(CCURVE type=CCURVE::CURVE, Bool bCreate=true)
Definition: c4d_canimation.h:835
Definition: c4d_gedata.h:83
void SetBaseList2D(BaseList2D *bl)
Definition: c4d_gedata.h:657
Definition: apibase.h:2818
Definition: lib_description.h:74
Definition: memoryallocationbase.h:67
Definition: ostage.h:6
const void * key2
Definition: pycore_hashtable.h:79
Represents a level within a DescID.
Definition: lib_description.h:289


The animation tracks of an object's parameters are stored with the object itself:

The keyframe selection is defined with the BaseList2D class, see BaseList2D Manual.
// This snippet loops through all animation tracks of the given object.
const CTrack* track = obj->GetFirstCTrack();
while (track != nullptr)
ApplicationOutput("Track: " + track->GetName());
track = track->GetNext();
String GetName() const
Definition: c4d_baselist.h:2363
CTrack * GetNext() const
Definition: c4d_canimation.h:716
PyObject * obj
Definition: complexobject.h:60
#define ApplicationOutput(formatString,...)
Definition: debugdiagnostics.h:210


A CTrack can be created with the usual tools:

A newly created CTrack must be added to a host object:

// This example checks if an animation track for the position X parameter
// exists in the given object. If not, the track will be created.
const DescLevel vectorXLevel = DescLevel(VECTOR_X, DTYPE_REAL, 0);
const DescID id = DescID(relPosLevel, vectorXLevel);
CTrack* track = obj->FindCTrack(id);
if (track == nullptr)
track = CTrack::Alloc(obj, id);
if (track == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
track->SetName("My New Animation Track"_s);
void SetName(const maxon::String &name)
Definition: c4d_baselist.h:2369
Definition: lib_description.h:330
Definition: lib_description.h:70
Definition: lib_description.h:68
X component.
Definition: lib_description.h:269
Definition: obase.h:15

To create special tracks the ID of that special track must be used. The special tracks are:

// This example adds a sound track to the given object
// and sets the referenced sound file.
const DescLevel soundTrackID = DescLevel(CTsound, CTsound, 0);
CTrack* const soundTrack = CTrack::Alloc(obj, soundTrackID);
if (soundTrack == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
soundTrack->SetName("New Sound Track"_s);
Bool SetParameter(const DescID &id, const GeData &t_data, DESCFLAGS_SET flags)
Definition: ctsound.h:7
#define CTsound
Definition: ge_prepass.h:1513
// This example adds a PLA track to the polygon object.
const DescID plaID = DescLevel(CTpla, CTpla, 0);
CTrack* const plaTrack = CTrack::Alloc(polyObject, plaID);
if (plaTrack == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
CCurve* curve = plaTrack->GetCurve();
if (curve == nullptr)
return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
// set first key
CKey* const key1 = curve->AddKey(BaseTime(0.0));
if (key1 == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
plaTrack->FillKey(doc, polyObject, key1);
// change polygon object randomly
Random random;
for (Int32 i = 0; i < count; ++i)
points[i] = points[i] + Vector(0, 100.0 * random.Get01(), 0.0);
// set second key
CKey* const key2 = curve->AddKey(BaseTime(1.0));
if (key2 == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
plaTrack->FillKey(doc, polyObject, key2);
Py_ssize_t i
Definition: abstract.h:645
Py_ssize_t count
Definition: abstract.h:640
Bool FillKey(BaseDocument *doc, BaseList2D *bl, CKey *key)
Definition: c4d_canimation.h:821
Definition: c4d_tools.h:812
Float Get01(void)
maxon::Vec3< maxon::Float64, 1 > Vector
Definition: ge_math.h:145
maxon::Int32 Int32
Definition: ge_sys_math.h:60
#define MSG_UPDATE
Must be sent if the bounding box has to be recalculated. (Otherwise use MSG_CHANGE....
Definition: c4d_baselist.h:341
#define CTpla
Definition: ge_prepass.h:1512
const char * doc
Definition: pyerrors.h:226


CTrack objects are stored in a list:

// This snippet loops through all animation tracks of the given object.
const CTrack* track = obj->GetFirstCTrack();
while (track != nullptr)
ApplicationOutput("Track: " + track->GetName());
track = track->GetNext();
The GeListHead object that is the parent of the tracks can be obtained with BaseList2D::GetCTrackRoot().

Read-Only Properties

Several values can be read from a CTrack:

The track categories are:

// This example checks if the given track is a "value" track.
// If so, the current value is printed to the console.
// check if the track is "value" track (float)
const BaseTime now = doc->GetTime();
const Float value = track->GetValue(doc, now);
PyObject * value
Definition: abstract.h:715
Float GetValue(BaseDocument *doc, const BaseTime &time)
Definition: c4d_canimation.h:855
Int32 GetTrackCategory() const
Definition: c4d_canimation.h:841
static String FloatToString(Float32 v, Int32 vvk=-1, Int32 nnk=-3)
Definition: c4d_string.h:529
maxon::Float Float
Definition: ge_sys_math.h:66
Value track.
Definition: c4d_canimation.h:633

See also CKey Value.



The parameters of a track can be edited as usual with C4DAtom::SetParameter() and C4DAtom::GetParameter(). The parameter IDs are defined in ctbase.h.

// This example sets the color to display the track's f-curve:
const Vector red { 1.0, 0, 0 };
Definition: ctbase.h:38
Definition: ctbase.h:10


In Cinema 4D there can be up to four timeline windows. An animation track can be selected in one or multiple of these windows. The selection state is stored as a bit:

// This example selects the given track if it does not contain any keys.
const CCurve* const curve = track->GetCurve();
if (curve)
const Int32 keyCount = curve->GetKeyCount();
if (keyCount == 0)
Int32 GetKeyCount(void) const
Definition: c4d_canimation.h:381
Bool ChangeNBit(NBIT bit, NBITCONTROL bitmode)
Clear bit.
Set bit.
Selection bit for Timeline 1.

See also CKey Selection.

Description ID

The parameter animated using a certain track is defined with its DescID. This DescID can be accessed:

// This example clones a track and sets the new description ID of that clone.
const DescLevel vectorXLevel(VECTOR_X, DTYPE_REAL, 0);
const DescID ID = DescID(relPosLevel, vectorXLevel);
// find track
CTrack* const track = obj->FindCTrack(ID);
if (track == nullptr)
return maxon::IllegalArgumentError(MAXON_SOURCE_LOCATION);
// get track root
GeListHead* const trackRoot = obj->GetCTrackRoot();
if (trackRoot == nullptr)
return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
// clone track
CTrack* const clone = static_cast<CTrack*>(track->GetClone(COPYFLAGS::NONE, nullptr));
if (clone == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
// insert and set new ID
const DescLevel vectorYLevel(VECTOR_Y, DTYPE_REAL, 0);
const DescID targetID = DescID(relPosLevel, vectorYLevel);
clone->SetDescriptionID(obj, targetID);
C4DAtom * GetClone(COPYFLAGS flags, AliasTrans *trn)
Definition: c4d_baselist.h:1462
Bool SetDescriptionID(BaseList2D *object, const DescID &id)
Definition: c4d_canimation.h:741
Definition: c4d_baselist.h:2026
void InsertLast(GeListNode *bn)
Definition: c4d_baselist.h:2110
Y component.
Definition: lib_description.h:270

Loop Settings

The loop settings define how an animation track should behave before the first key and after the last key.

The loop types are:

// This example defines the loop settings of the given track.
void SetBefore(CLOOP type)
Definition: c4d_canimation.h:758
void SetAfter(CLOOP type)
Definition: c4d_canimation.h:770
Offset repeat.

Points in time beyond the defined animation track can be mapped into time inside the track.

  • CTrack::Remap(): Remaps the given time into a position inside the animation track.
// This example calculates the remapped time for each given time in seconds.
// loop from 0.0 to 1.0
for (Float64 t = 0.0; t < 10.0; t = t + 0.1)
Float64 remapTime;
Int32 cycle;
track->Remap(t, &remapTime, &cycle);
ApplicationOutput("Remap Time: " + String::FloatToString(remapTime));
Bool Remap(Float64 time, Float64 *ret_time, Int32 *ret_cycle) const
Definition: c4d_canimation.h:885
maxon::Float64 Float64
Definition: ge_sys_math.h:67

Time Track

The behavior of an animation track depends on the current time which is typically the current time of the BaseDocument. But the time that controls a track can be also defined with a time track.

// This example applies the found time track to all other tracks.
// serach for time track
CTrack* const timeTrack = obj->FindCTrack(CTtime);
if (timeTrack == nullptr)
return maxon::IllegalArgumentError(MAXON_SOURCE_LOCATION);
// apply time track to other tracks
CTrack* track = obj->GetFirstCTrack();
while (track != nullptr)
const DescID id = track->GetDescriptionID();
// check if the track is not a "Time" track
if (id[0].id != CTtime)
track = track->GetNext();
void SetTimeTrack(CTrack *track)
Definition: c4d_canimation.h:788
const DescID & GetDescriptionID() const
Definition: c4d_canimation.h:733
#define CTtime
Definition: ge_prepass.h:1515

Timeline Height

An animation track can be displayed in a Timeline window.

Track Information

An animation track can provide additional information for each key or the current time in form of a String.

// This example prints the information for each key of the track.
CKey* const key = curve->GetKey(i);
if (key == nullptr)
return maxon::UnexpectedError(MAXON_SOURCE_LOCATION);
track->TrackInformation(doc, key, &info, false);
PyObject * key
Definition: abstract.h:289
const CKey * GetKey(Int32 index) const
Definition: c4d_canimation.h:388
Bool TrackInformation(BaseDocument *doc, CKey *key, maxon::String *str, Bool set)
Definition: c4d_canimation.h:896
Definition: c4d_string.h:39
_Py_clock_info_t * info
Definition: pytime.h:197


Multiple tracks can be synchronized. Typically this applies to tracks of the components of a Vector parameter.


Since a track might be displayed in the GUI (Timeline window) it can draw an image:

// This example calls the "Draw" function of the given sound track
// and displays the result image.
if (clipMap == nullptr)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
if (clipMap->Init(400, 100, 32) != IMAGERESULT::OK)
return maxon::UnknownError(MAXON_SOURCE_LOCATION);
soundTrack->Draw(clipMap, BaseTime(0), BaseTime(1.0));
Bool ShowBitmap(const Filename &fn)
Definition: ge_autoptr.h:37
Bool Draw(GeClipMap *map, const BaseTime &clip_left, const BaseTime &clip_right) const
Definition: c4d_canimation.h:812
@ OK
Image loaded/created.

Further utility functions are:

// This eample accesses the CCurve from the given animation track.
CCurve* const curve = track->GetCurve();
if (curve)
// do something with the curve

See also CCurve Manual.

Further Reading