Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Camera animation to Text file?

    Cinema 4D SDK
    r20 python
    2
    3
    838
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • V
      Vibz
      last edited by Vibz

      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()
      
      1 Reply Last reply Reply Quote 0
      • ManuelM
        Manuel
        last edited by Manuel

        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.

        • Q&A New Functionality.

        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

        1 Reply Last reply Reply Quote 1
        • V
          Vibz
          last edited by

          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!

          1 Reply Last reply Reply Quote 0
          • First post
            Last post