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

    How to create a Track on a Vector Userdata?

    Cinema 4D SDK
    python
    2
    3
    267
    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.
    • P
      pyr
      last edited by

      I have a Python Tag that loads on button press a json with some animation data. Position / Rotation working fine but i still haven't figured out how to create a track on a userdata with the type vector. i think i'm missing the desc ids or something like that

      def CreateOrUpdateKey(curve, time, value, interpolation):
          keyDict = curve.FindKey(time)
          if keyDict:
              key = keyDict["key"]
              key.SetValue(curve, value)
              key.SetInterpolation(curve, interpolation)
          else:
              keyDict = curve.AddKey(time)
              if not keyDict:
                  raise MemoryError("Failed to create key")
              key = keyDict["key"]
              index = keyDict["nidx"]
              key.SetValue(curve, value)
              curve.SetKeyDefault(doc, index)
              key.SetInterpolation(curve, interpolation)
      
      def LoadJsonToTracks(obj, path):
          if not os.path.isfile(path):
              raise FileNotFoundError(f"JSON file not found: {path}")
          with open(path, "r") as f:
              rawData = json.load(f)
      
          fps = doc.GetFps()
          interpolation = c4d.CINTERPOLATION_LINEAR
      
          # --- POSITION TRACKS ---
          pos_curves = []
          for axis in [c4d.VECTOR_X, c4d.VECTOR_Y, c4d.VECTOR_Z]:
              descID = c4d.DescID(
                  c4d.DescLevel(c4d.ID_BASEOBJECT_REL_POSITION, c4d.DTYPE_VECTOR, 0),
                  c4d.DescLevel(axis, c4d.DTYPE_REAL, 0)
              )
              track = obj.FindCTrack(descID)
              if not track:
                  track = c4d.CTrack(obj, descID)
                  obj.InsertTrackSorted(track)
              curve = track.GetCurve()
              curve.FlushKeys()
              pos_curves.append(curve)
      
          # --- ROTATION TRACKS ---
          rot_curves = []
          for axis in [c4d.VECTOR_X, c4d.VECTOR_Y, c4d.VECTOR_Z]:
              descID = c4d.DescID(
                  c4d.DescLevel(c4d.ID_BASEOBJECT_REL_ROTATION, c4d.DTYPE_VECTOR, 0),
                  c4d.DescLevel(axis, c4d.DTYPE_REAL, 0)
              )
              track = obj.FindCTrack(descID)
              if not track:
                  track = c4d.CTrack(obj, descID)
                  obj.InsertTrackSorted(track)
              curve = track.GetCurve()
              curve.FlushKeys()
              rot_curves.append(curve)
      
          # --- Add keyframes from JSON ---
          for entry in rawData:
              frame = entry.get("frame")
              pos = entry.get("position", [0, 0, 0])
              rot = entry.get("rotation", [0, 0, 0])
              if frame is None or len(pos) != 3 or len(rot) != 3:
                  continue
      
              time = c4d.BaseTime(frame, fps)
      
              for i in range(3):
                  CreateOrUpdateKey(pos_curves[i], time, pos[i], interpolation)
                  CreateOrUpdateKey(rot_curves[i], time, rot[i], interpolation)
      
      ferdinandF 1 Reply Last reply Reply Quote 0
      • ferdinandF
        ferdinand @pyr
        last edited by ferdinand

        Hey @pyr,

        Thank you for reaching out to us. Do you refer with 'userdata' to your JSON input or do you mean 'a vector parameter in the user data of an object.'? Your code generally looks fine, as you took the main hurdle of understanding that there is no such thing as an animated vector; for animations, all data is decomposed into float/int/bool or custom tracks.

        When you just want to address a vector inside the user data, the answer is simply that you have to add that desc level for the user data, forming an ID such as (user data container, user data element, ...). Because the user data is itself a just a parameter of type DTYPE_SUBCONTAINER.

        Cheers,
        Ferdinand

        """Showcases how to use a three level DescID to address the x component of a vector in the user 
        data of a scene element.
        """
        
        import c4d
        
        doc: c4d.documents.BaseDocument  # The currently active document.
        op: c4d.BaseObject | None  # The primary selected object in `doc`. Can be `None`.
        
        def main() -> None:
            """Called by Cinema 4D when the script is being executed.
            """
            if not op:
                c4d.gui.MessageDialog("No object selected.")
                return
            
            uid: int = 1 # The ID of the thing in the user data we want to access.
            did: c4d.DescID = c4d.DescID(
                c4d.DescLevel(c4d.ID_USERDATA, c4d.DTYPE_SUBCONTAINER, 0), # 1st level, the user data container.
                c4d.DescLevel(uid, c4d.DTYPE_VECTOR, 0), # 2nd level, the user data ID, here a vector.
                c4d.DescLevel(c4d.VECTOR_X, c4d.DTYPE_REAL, 0)) # 3rd level, the x component of the vector.
            
            if op.FindCTrack(did):
                return
            
            track: c4d.CTrack = c4d.CTrack(op, did)
            op.InsertTrackSorted(track)
            c4d.EventAdd()
            print(f"Added track for {did} to {op.GetName()}.")
        
        
        if __name__ == '__main__':
            main()
        
        

        MAXON SDK Specialist
        developers.maxon.net

        1 Reply Last reply Reply Quote 1
        • P
          pyr
          last edited by

          Works! Thank you!

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