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 -
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!