track_copy¶
Copies the position, rotation and animation Tracks (so all Keyframes) from obj1 to obj2.
track_copy.py¶
"""Copies the position, rotation and animation Tracks (so all Keyframes) from obj1 to obj2.
Topics:
* BaseObject.GetCTracks()
* CTracks.GetDescriptionID()
* CTracks.FindCTrack()
* C4DAtom.GetClone()
* CTracks.InsertTrackSorted()
* BaseDocument.AnimateObject()
Notes:
- If obj2 already have some animation data for its position, rotation, and animation these data will be lost.
"""
__author__ = "Manuel Magalhaes"
__copyright__ = "Copyright (C) 2026 MAXON Computer GmbH"
__license__ = "Apache-2.0 License"
__version__ = "R14"
import c4d
def main():
# Retrieves the object called obj1 from the active document.
animatedBox = doc.SearchObject("obj1")
if animatedBox is None:
raise RuntimeError("Failed to retrieve obj1 in document.")
# Retrieves the object called obj2 from the active document.
fixedBox = doc.SearchObject("obj2")
if fixedBox is None:
raise RuntimeError("Failed to retrieve obj2 in document.")
# Retrieves all the CTrack of obj1. CTracks contains all keyframes information of a parameter.
tracks = animatedBox.GetCTracks()
if not tracks:
raise ValueError("Failed to retrieve animated tracks information for obj1.")
# Defines a list that will contains the ID of parameters we want to copy.
# Such ID can be found by drag-and-drop a parameter into the python console.
trackListToCopy = [c4d.ID_BASEOBJECT_REL_POSITION, c4d.ID_BASEOBJECT_REL_ROTATION, c4d.ID_BASEOBJECT_REL_SCALE]
# Start the Undo process.
doc.StartUndo()
# Iterates overs the CTracks of obj1.
for track in tracks:
# Retrieves the full parameter ID (DescID) describing a parameter.
did = track.GetDescriptionID()
# If the Parameter ID of the current CTracks is not on the trackListToCopy we go to the next one.
if not did[0].id in trackListToCopy:
continue
# Find if our static object already got an animation track for this parameter ID.
foundTrack = fixedBox.FindCTrack(did)
if foundTrack:
# Removes the track if found.
doc.AddUndo(c4d.UNDOTYPE_DELETEOBJ, foundTrack)
foundTrack.Remove()
# Copies the initial CTrack in memory. All CCurve and CKey are kept in this CTrack.
clone = track.GetClone()
# Inserts the copied CTrack to the static object.
fixedBox.InsertTrackSorted(clone)
doc.AddUndo(c4d.UNDOTYPE_NEWOBJ, clone)
# Ends the Undo Process.
doc.EndUndo()
# Updates fixedBox Geometry taking in account previously created keyframes
animateFlag = c4d.ANIMATEFLAGS_NONE if c4d.GetC4DVersion() > 20000 else c4d.ANIMATEFLAGS_0
doc.AnimateObject(fixedBox, doc.GetTime(), animateFlag)
# Pushes an update event to Cinema 4D
c4d.EventAdd()
if __name__ == "__main__":
main()