Solved Camera animation to Text file?

I'm trying to find a way to export moving camera data (rotation and position) from cinema 4d to a csv file.
I have found a python script on how to get this on ONE single frame. I'll insert the code I found bellow.
This code outputs position (x, y and z) and rotation degrees (x, y and z) on one row in different columns, which is perfect.

My question is how to expand the code to make the script look through each frame in the timeline and not only one frame,
giving each frame it's own row in the csv doc.

My lack of python knowledge hinders me from getting closer to my goals. All help is appreciated!

import c4d
#Welcome to the world of Python
 
def Walker(obj):
    if not obj: return
 
    elif obj.GetDown():
        return obj.GetDown()
    while obj.GetUp() and not obj.GetNext():
        obj = obj.GetUp()
    return obj.GetNext()
 
def main():
    file = c4d.storage.SaveDialog(c4d.FILESELECTTYPE_ANYTHING, title='Save csv file as', force_suffix='csv')
    csv_file = open(file, 'w')
    obj = doc.GetFirstObject()
    while obj:
        if obj.GetType() == 5103:
            name = obj.GetName()
            obj_matrix = obj.GetMg()
            position = obj_matrix.off
            rotation_rad = c4d.utils.MatrixToHPB(obj_matrix,c4d.ROTATIONORDER_XYZGLOBAL)
            rotation_deg = c4d.Vector(c4d.utils.Deg(rotation_rad.x), c4d.utils.Deg(rotation_rad.y), c4d.utils.Deg(rotation_rad.z))
            line = '%s, %s, %s, %s, %s, %s'%(position.x,
                                                 position.y,
                                                 position.z,
                                                 rotation_deg.x,
                                                 rotation_deg.y,
                                                 rotation_deg.z)
            csv_file.write(line + '\n')
        obj = Walker(obj)
    csv_file.close()
 
 
if __name__=='__main__':
    main()

Hello and thanks for the question,

First, for your next threads, please help us keeping things organised and clean. It really simplify our work here.

I've marked this thread as a question so when you considered it as solved, please change the state 🙂

About your question :

you need to update the document's time and use ExecutesPasses, you can have more information on this manual

You can also add some variable to have the beginning and the end of the animation range

I've updated your script but you should considered doing something better.
Depending on how many camera you need to export and how your scene update of course.
You should update each frame, collect all the data than go to the next frame. And organize it on your csv file.

import c4d
#Welcome to the world of Python
 
def Walker(obj):
    if not obj: return
 
    elif obj.GetDown():
        return obj.GetDown()
    while obj.GetUp() and not obj.GetNext():
        obj = obj.GetUp()
    return obj.GetNext()
 
def main():
    if doc is None:
        raise ValueError("there's no document")
    # Animation Range and save the actual time of the document
    startingFrame = 0
    endFrame = 30
    savedTime = doc.GetTime()
    docFPS = doc.GetFps()
    
    # Changes the document's time to the start of the animation
    currentTime = c4d.BaseTime(startingFrame, docFPS)
    doc.SetTime(currentTime)
    # ExecutePasses to update the whole scene
    doc.ExecutePasses(None, True, True, True, c4d.BUILDFLAGS_NONE)

    file = c4d.storage.SaveDialog(c4d.FILESELECTTYPE_ANYTHING, title='Save csv file as', force_suffix='csv')
    csv_file = open(file, 'w')
    obj = doc.GetFirstObject()
    while obj:
        if obj.GetType() == 5103:
            while startingFrame < endFrame:
                name = obj.GetName()
                obj_matrix = obj.GetMg()
                position = obj_matrix.off
                rotation_rad = c4d.utils.MatrixToHPB(obj_matrix,c4d.ROTATIONORDER_XYZGLOBAL)
                rotation_deg = c4d.Vector(c4d.utils.Deg(rotation_rad.x), c4d.utils.Deg(rotation_rad.y), c4d.utils.Deg(rotation_rad.z))
                line = '%s, %s, %s, %s, %s, %s'%(position.x,
                                                 position.y,
                                                 position.z,
                                                 rotation_deg.x,
                                                 rotation_deg.y,
                                                 rotation_deg.z)
                csv_file.write(line + '\n')
                # updates the document's time and the scene
                startingFrame += 1
                currentTime = c4d.BaseTime(startingFrame, docFPS)
                doc.SetTime(currentTime)
                doc.ExecutePasses(None,True, True, True, c4d.BUILDFLAGS_NONE)
        obj = Walker(obj)
    csv_file.close()
    
    # Restores the time 
    doc.SetTime(savedTime)
 
if __name__=='__main__':
    main()

If your camera is animated with only key frames (tracks) you can retrieves those value with CCurve.GetValue(time, fps).

    # tracks to export
    trackListToExport = [c4d.ID_BASEOBJECT_POSITION, c4d.ID_BASEOBJECT_ROTATION, c4d.ID_BASEOBJECT_SCALE]
    
    # Gets all tracks
    tracks = op.GetCTracks()
    if not tracks:
        raise ValueError("Failed to retrieved animated tracks information for 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 trackListToExport we go to the next one.
        if not did[0].id in trackListToExport:
            continue

        # Finds the track
        foundTrack = op.FindCTrack(did)
        if foundTrack:
            # Gets the curve of that track
            cc = foundTrack.GetCurve()
            if cc is None:
                raise ValueError("no curve retrieved")
            
            t = doc.GetTime()
            print cc.GetValue(t, doc.GetFps())

Cheers,
Manuel

MAXON SDK Specialist

MAXON Registered Developer

This is a great start - will defiantly be using this to get closer to the desired end result 🙂
Thanks so much Manuel for your help!