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

    Keyframing a property using python.

    Cinema 4D SDK
    2
    3
    786
    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.
    • M
      martijnlambada
      last edited by Manuel

      Hi all,

      I’m trying to make a little script that takes all selected cameras and puts them in a (newly created) stage object (one camera per frame).

      Super useful if you want to render out stills on a render farm that doesn’t support takes.

      I’ve got almost everything working:

      • Getting the selected cameras and putting them in an array.
      • Creating a stage object
      • Looping through the array and putting the cameras into the camera slot of the stage object.
      • Moving 1 frame forward

      The two things I’m struggling with:

      1. How to key frame the camera slot properly so it actually creates the animation (different camera per frame). I’m using the mydoc.RecordKey() property but how do I find out which id (?) the camera property has?
      2. Ideally I want to catch errors when someone selects something other than a camera. Is there an easy way to catch that error? Should I loop through the array and check the individual elements?

      Who can point me into the right direction?

      Your help is much appreciated.

      Best regards,
      Martijn

      script:

      import c4d, math
      from c4d import gui
      
      # This is a little script that puts the selected cameras into a stage object with keyframes
      
      
      # Main function
      def main():
          # Clear Console for easy debugging
          c4d.CallCommand(13957, 13957)
      
          # Get selected cameras
          obj = doc.GetActiveObjects(1)
      
          # Check if selected objects are cameras, if not pop-up error
          #code should come here
      
      
          # Go to Start of timeline
          c4d.CallCommand(12501)
      
          #create stage object
          stage = c4d.BaseObject(c4d.Ostage)
          doc.InsertObject(stage)
      
          # Get active document
          mydoc = c4d.documents.GetActiveDocument()
      
          # Loop through the array of cameras & put selected cameras in stage object
          for x in obj:
              mytime = mydoc.GetTime()
              myfps = mydoc.GetFps() # define prject fps
              myframe = mytime.GetFrame(myfps) #get current frame
              print(myframe) # print frame number
      
              stage[c4d.STAGEOBJECT_CLINK] = x # put camera camera slot of stage object
      
              #set keyframe How??
              #mydoc.RecordKey(stage,[c4d.ID_BASEOBJECT_REL_ROTATION,c4d.VECTOR_X]) #Add the keyframe to Rotation X successfully
              mydoc.RecordKey(stage, 1)
      
      
      
              # Go to next key frame
              c4d.CallCommand(12414)
      
          c4d.EventAdd() #update
      
      
      
      # Execute main()
      if __name__=='__main__':
          main()
      
      1 Reply Last reply Reply Quote 0
      • ManuelM
        Manuel
        last edited by Manuel

        hello,

        For your next threads, please help us keeping things organised and clean. I know it's not your priority but it really simplify our work here. I've made the changes for this one already.

        • Q&A New Functionality.
        • How to Post Questions especially the tagging part.

        Regarding your question you have an example on our github repository how to create a keyFrame and add the track

        We have useful information about ctrack in our c++ manual

        In the github example, the CreateKey function was expecting a float value, I've change it in the example to use SetGeData instead of SetValue as the track is storing links.

        If you have any questions, just ask.
        Feel free to pass this thread as solved when ever you think it is.

        Cheers,
        Manuel

        import c4d
        
        def CreateKey(curve, time, value, interpolation):
          
            # Adds the key
            keyDict = curve.AddKey(time)
        
            # Checks if the key have been added
            if keyDict is None:
                raise MemoryError("Failed to create a key")
        
            # Retrieves the inserted key
            key = keyDict["key"]
            keyIndex = keyDict["nidx"]
        
            # Sets the value of the key
            key.SetGeData(curve, value)
        
            # Mandatory: Fill the key with default settings
            curve.SetKeyDefault(doc, keyIndex)
        
            # Changes it's interpolation
            key.SetInterpolation(curve, interpolation)
        
            return key, keyIndex
        
        
        # Main function
        def main():
            # Retrieves the selected cameras
            cams = [x for x in doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_SELECTIONORDER) if x.IsInstanceOf(c4d.Ocamera)]
            # Creates the StageObject
            so = c4d.BaseObject(c4d.Ostage)
            
            # Creates the track in memory
            trackCamera = c4d.CTrack(so, c4d.DescID(c4d.DescLevel(1100, c4d.DTYPE_BASELISTLINK, 0)))
            
            # Retrieves the curve of the track
            curve = trackCamera.GetCurve()
        
            
            for i,cam in enumerate(cams):
                time = c4d.BaseTime(i, doc.GetFps())
                CreateKey(curve, time, value=cam, interpolation=c4d.CINTERPOLATION_STEP)
            
            # Inserts the track to the stage object
            so.InsertTrackSorted(trackCamera)
        
            # Inserts the object to the scene and add an Undo step.
            doc.StartUndo()
            doc.InsertObject(so)
            doc.AddUndo(c4d.UNDOTYPE_NEW, so)
            doc.EndUndo()
        
            # Pushes an update event to Cinema 4D
            c4d.EventAdd()
        
        # Execute main()
        if __name__=='__main__':
            main()
        

        MAXON SDK Specialist

        MAXON Registered Developer

        1 Reply Last reply Reply Quote 1
        • M
          martijnlambada
          last edited by

          Hi Manual,

          Thanks for your help! Next time I will use the 'ask question' when posting a question.
          You code does exactly what I need, much appreciated!

          Cheers,
          Martijn

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