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
    1. Maxon Developers Forum
    2. augustin
    A
    • Profile
    • Following 0
    • Followers 0
    • Topics 2
    • Posts 5
    • Best 1
    • Controversial 0
    • Groups 0

    augustin

    @augustin

    1
    Reputation
    9
    Profile views
    5
    Posts
    0
    Followers
    0
    Following
    Joined Last Online

    augustin Unfollow Follow

    Best posts made by augustin

    • Keyframing morph pose animations in Python

      Hello again,

      I have a model with a Pose Morph tag.

      I can get the tag from the object. What I want to achieve is control the values of the different poses through code and keyFrame those. I actually only need to toggle them on or off as they'll either be 0 or 100%,

      I've toggled visibility of a model on and off using CTrack, CCurve and CKey. Would it work similarly with the poses?

      How can I loop through all the poses and toglle them on and off and keyFrame that?

      Edit (by @ferdinand consolidating posts):

      So here's what I got so far:

          face = doc.SearchObject('Body')
          tpose = face.GetTag(c4d.Tposemorph)
          morph = tpose.GetMorph(2)
          morphId = morph.GetID()
          descId = morphId * c4d.ID_CA_POSE_ANIMATE_CNT + \
          c4d.ID_CA_POSE_ANIMATE_OFFSET + c4d.ID_CA_POSE_ANIMATE_STRENGTH
          print(descId)
      
          smirkTrack = obj.FindCTrack(descId)
          if not smirkTrack:
              smirkTrack =  c4d.CTrack(face, descId)
              print(smirkTrack)
      

      It works up until the point it has to create the CTrack:

      1201
      Traceback (most recent call last):
        File "C:\Users\Augustin\AppData\Roaming\Maxon\Maxon Cinema 4D R25_1FE0824E\library\scripts\test.py", line 80, in <module>
        File "C:\Users\Augustin\AppData\Roaming\Maxon\Maxon Cinema 4D R25_1FE0824E\library\scripts\test.py", line 46, in main
      
      BaseException: the plugin 'c4d.CTrack' (ID 5350) is missing. Could not allocate instance
      

      It doesn't return this code if I use another descID like the one for editor visibility.

      I realise my DescId or the way I calculate it is what's wrong but I don't where to find the documentation for that.

      So I'm making progress. I was obviously not looking in the right place to find the DescId.
      I went back to the doc and found this:

      For a plugin and special tracks you pass the ID.
      
      tr = c4d.CTrack(op, c4d.DescID(ID, ID, 0))
      IDs for Cinema 4D’s special tracks are:
      
      CTpla PLA.
      
      CTsound Sound.
      
      CTmorph Morph.
      
      CTtime Time.
      

      So I tried:
      descId = c4d.DescID(c4d.CTmorph, c4d.CTmorph, 0)
      But get hit with:
      TypeError: argument 2 must be c4d.DescLevel, not int

      I then realised it should be:
      descId = c4d.DescID(c4d.DescLevel(c4d.CTmorph, c4d.CTmorph, 2))
      So it would be good to fix the documentation

      Here's my code so far:

          visTrack.FillKey (doc, obj, keyDict["key"])
          print(c4d.Tposemorph)
      
          face = doc.SearchObject('Body')
          tpose = face.GetTag(c4d.Tposemorph)
          print(tpose.GetMorphCount())
          firstMorph = tpose.GetMorph(2)
          morphId = firstMorph.GetID()
          print(morphId)
          
          descId =  c4d.DescID(c4d.DescLevel(c4d.CTmorph, c4d.CTmorph, 3))
          
          smirkTrack = face.FindCTrack(descId)
          if not smirkTrack:
              smirkTrack =  c4d.CTrack(face,descId)
              
          smirkCurve = smirkTrack.GetCurve()
          # kdict = curve.AddKey(curTime)
          # kdict.SetValue(0)
          # smirkTrack.FillKeu (doc, face, kdit["key"])
          # Creates a keyframe in the memory
          key = c4d.CKey()
          
          # Fills the key with the default data
          smirkTrack.FillKey(doc, face, key)
          
          # Defines the key value
          key.SetValue(smirkCurve, 0)
      
          # Defines the time value
          key.SetTime(smirkCurve, curTime)
          
          smirkCurve.InsertKey(key)
      

      Unfortunately it doesn't seem to have any effect on the values of the pose, nor the keyFrames.
      I've also tried applying all of the track and curve to the tag rather than the object but it did not have any more impact. I think I'm at the point where I could use some help.

      Making progress:

      for i in range( tpose.GetMorphCount()):
              descID = tpose.GetMorphID(i)
              currentValue = tpose.GetParameter(descID, c4d.DESCFLAGS_GET_NONE)
              print(descID, currentValue)
              tpose.SetParameter(descID, 0, c4d.DESCFLAGS_GET_NONE )
      

      returns all the values of the morphs as expected. I suppose they're the descIds I should use for the keyframes. But should the keyframe be on the tag or on the object the tag belongs to?

      I tried something like this:

      for i in range( tpose.GetMorphCount()):
              descID = tpose.GetMorphID(i)
              currentValue = tpose.GetParameter(descID, c4d.DESCFLAGS_GET_NONE)
              print(descID, currentValue)
              tpose.SetParameter(descID, 0, c4d.DESCFLAGS_GET_NONE )
              track = tpose.FindCTrack(descId)
              if not track:
                  track = c4d.CTrack(tpose, descId)
                  tpose.InsertTrackSorted(track)
              curve = track.GetCurve()
              keyDict = curve.AddKey(curTime)
              track.FillKey (doc, tpose, keyDict["key"])
      

      to no avail, I also tried the same thing with the object and it didn't do much either

      I also tried like this:

       for i in range( tpose.GetMorphCount()):
              descID = tpose.GetMorphID(i)
              currentValue = tpose.GetParameter(descID, c4d.DESCFLAGS_GET_NONE)
              print(descID, currentValue)
              tpose.SetParameter(descID, 1.26, c4d.DESCFLAGS_GET_NONE )
              track = face.FindCTrack(descId)
              if not track:
                  print('no')
                  track = c4d.CTrack(face, descId)
                  face.InsertTrackSorted(track)
              curve = track.GetCurve()
              # keyDict = curve.AddKey(curTime)
              key = c4d.CKey()
              key.SetValue(curve, 0)
              key.SetTime(curve, curTime)
              curve.InsertKey(key)
      

      Didn't do much more. However it does appear that the CTracks exist.
      My brain is fried. I'm admitting defeat for tonight.

      posted in Cinema 4D SDK python
      A
      augustin

    Latest posts made by augustin

    • RE: Keyframing morph pose animations in Python

      @jmckeehen personally morph_tracks returns an empty array in this case.
      C4d is so incredibly obscure with the way to get the proper CTracks it blows my mind.

      @ferdinand or @m_magalhaes, if either of you think you can help me solve this problem, or are available asap to discuss this issue further I really need to solve this very quick. I'm ready to pay for a private 1 on 1 explanation of certain core concepts as I can't afford to waste hours inching towards a potential solution to what seems like a very fundamental concept.

      Thank you in advance.

      posted in Cinema 4D SDK
      A
      augustin
    • RE: Keyframing morph pose animations in Python

      HI @ferdinand , duly noted I'll try to be more concise in the future. Thanks for your help. So I'm at a point where I can change the values of the properties but not keyframe it. When I try to get the CTrack I get hit with following error:

      BaseException: the plugin 'c4d.CTrack' (ID 5350) is missing. Could not allocate instance
      

      Which leads me to believe I'm not using the proper descId. Here's the current code:

          face = doc.SearchObject('Body')
          tpose = face.GetTag(c4d.Tposemorph)
          
          for i in range( tpose.GetMorphCount()):
              descID = tpose.GetMorphID(i)
              currentValue = tpose.GetParameter(descID, c4d.DESCFLAGS_GET_NONE)
              print(descID, currentValue)
              tpose.SetParameter(descID, 1.0, c4d.DESCFLAGS_GET_NONE )
              track = face.FindCTrack(descID)
              if not track:
                  print('no')
                  track = c4d.CTrack(face, descID)
                  face.InsertTrackSorted(track)
              curve = track.GetCurve()
              keyDict = curve.AddKey(curTime)
              track.FillKey (doc, face, keyDict["key"])
      
      posted in Cinema 4D SDK
      A
      augustin
    • Keyframing morph pose animations in Python

      Hello again,

      I have a model with a Pose Morph tag.

      I can get the tag from the object. What I want to achieve is control the values of the different poses through code and keyFrame those. I actually only need to toggle them on or off as they'll either be 0 or 100%,

      I've toggled visibility of a model on and off using CTrack, CCurve and CKey. Would it work similarly with the poses?

      How can I loop through all the poses and toglle them on and off and keyFrame that?

      Edit (by @ferdinand consolidating posts):

      So here's what I got so far:

          face = doc.SearchObject('Body')
          tpose = face.GetTag(c4d.Tposemorph)
          morph = tpose.GetMorph(2)
          morphId = morph.GetID()
          descId = morphId * c4d.ID_CA_POSE_ANIMATE_CNT + \
          c4d.ID_CA_POSE_ANIMATE_OFFSET + c4d.ID_CA_POSE_ANIMATE_STRENGTH
          print(descId)
      
          smirkTrack = obj.FindCTrack(descId)
          if not smirkTrack:
              smirkTrack =  c4d.CTrack(face, descId)
              print(smirkTrack)
      

      It works up until the point it has to create the CTrack:

      1201
      Traceback (most recent call last):
        File "C:\Users\Augustin\AppData\Roaming\Maxon\Maxon Cinema 4D R25_1FE0824E\library\scripts\test.py", line 80, in <module>
        File "C:\Users\Augustin\AppData\Roaming\Maxon\Maxon Cinema 4D R25_1FE0824E\library\scripts\test.py", line 46, in main
      
      BaseException: the plugin 'c4d.CTrack' (ID 5350) is missing. Could not allocate instance
      

      It doesn't return this code if I use another descID like the one for editor visibility.

      I realise my DescId or the way I calculate it is what's wrong but I don't where to find the documentation for that.

      So I'm making progress. I was obviously not looking in the right place to find the DescId.
      I went back to the doc and found this:

      For a plugin and special tracks you pass the ID.
      
      tr = c4d.CTrack(op, c4d.DescID(ID, ID, 0))
      IDs for Cinema 4D’s special tracks are:
      
      CTpla PLA.
      
      CTsound Sound.
      
      CTmorph Morph.
      
      CTtime Time.
      

      So I tried:
      descId = c4d.DescID(c4d.CTmorph, c4d.CTmorph, 0)
      But get hit with:
      TypeError: argument 2 must be c4d.DescLevel, not int

      I then realised it should be:
      descId = c4d.DescID(c4d.DescLevel(c4d.CTmorph, c4d.CTmorph, 2))
      So it would be good to fix the documentation

      Here's my code so far:

          visTrack.FillKey (doc, obj, keyDict["key"])
          print(c4d.Tposemorph)
      
          face = doc.SearchObject('Body')
          tpose = face.GetTag(c4d.Tposemorph)
          print(tpose.GetMorphCount())
          firstMorph = tpose.GetMorph(2)
          morphId = firstMorph.GetID()
          print(morphId)
          
          descId =  c4d.DescID(c4d.DescLevel(c4d.CTmorph, c4d.CTmorph, 3))
          
          smirkTrack = face.FindCTrack(descId)
          if not smirkTrack:
              smirkTrack =  c4d.CTrack(face,descId)
              
          smirkCurve = smirkTrack.GetCurve()
          # kdict = curve.AddKey(curTime)
          # kdict.SetValue(0)
          # smirkTrack.FillKeu (doc, face, kdit["key"])
          # Creates a keyframe in the memory
          key = c4d.CKey()
          
          # Fills the key with the default data
          smirkTrack.FillKey(doc, face, key)
          
          # Defines the key value
          key.SetValue(smirkCurve, 0)
      
          # Defines the time value
          key.SetTime(smirkCurve, curTime)
          
          smirkCurve.InsertKey(key)
      

      Unfortunately it doesn't seem to have any effect on the values of the pose, nor the keyFrames.
      I've also tried applying all of the track and curve to the tag rather than the object but it did not have any more impact. I think I'm at the point where I could use some help.

      Making progress:

      for i in range( tpose.GetMorphCount()):
              descID = tpose.GetMorphID(i)
              currentValue = tpose.GetParameter(descID, c4d.DESCFLAGS_GET_NONE)
              print(descID, currentValue)
              tpose.SetParameter(descID, 0, c4d.DESCFLAGS_GET_NONE )
      

      returns all the values of the morphs as expected. I suppose they're the descIds I should use for the keyframes. But should the keyframe be on the tag or on the object the tag belongs to?

      I tried something like this:

      for i in range( tpose.GetMorphCount()):
              descID = tpose.GetMorphID(i)
              currentValue = tpose.GetParameter(descID, c4d.DESCFLAGS_GET_NONE)
              print(descID, currentValue)
              tpose.SetParameter(descID, 0, c4d.DESCFLAGS_GET_NONE )
              track = tpose.FindCTrack(descId)
              if not track:
                  track = c4d.CTrack(tpose, descId)
                  tpose.InsertTrackSorted(track)
              curve = track.GetCurve()
              keyDict = curve.AddKey(curTime)
              track.FillKey (doc, tpose, keyDict["key"])
      

      to no avail, I also tried the same thing with the object and it didn't do much either

      I also tried like this:

       for i in range( tpose.GetMorphCount()):
              descID = tpose.GetMorphID(i)
              currentValue = tpose.GetParameter(descID, c4d.DESCFLAGS_GET_NONE)
              print(descID, currentValue)
              tpose.SetParameter(descID, 1.26, c4d.DESCFLAGS_GET_NONE )
              track = face.FindCTrack(descId)
              if not track:
                  print('no')
                  track = c4d.CTrack(face, descId)
                  face.InsertTrackSorted(track)
              curve = track.GetCurve()
              # keyDict = curve.AddKey(curTime)
              key = c4d.CKey()
              key.SetValue(curve, 0)
              key.SetTime(curve, curTime)
              curve.InsertKey(key)
      

      Didn't do much more. However it does appear that the CTracks exist.
      My brain is fried. I'm admitting defeat for tonight.

      posted in Cinema 4D SDK python
      A
      augustin
    • RE: Python script to keyframe visibility of object

      Well I found the solution.

      I was creating a new CTrack instead of getting the one already attached to the object. That lead to a conflict, I imagine. Anyway it's working now.

      posted in Cinema 4D SDK
      A
      augustin
    • Python script to keyframe visibility of object

      Hello,

      I'm pretty new to C4D and I am tasked with creating a script.
      What I want to achieve is pretty basic, in theory, but I have been struggling so I hope you'll be able to provide me with a solution.

      I want to toggle the visibility of an object and keyframe that parameter.
      Here's what I've tried so far:

      import c4d
      from c4d import gui
      
      
      def main():
          # c4d.CallCommand(12410)
          curTime = doc.GetTime()
          fps = doc[c4d.DOCUMENT_FPS]
          obj = doc.SearchObject('Tshirt_white')
      
          print(obj)
          print(curTime.GetFrame(fps))
      
          # setting visibility ON
          obj[c4d.ID_BASEOBJECT_VISIBILITY_EDITOR] = 0
      
          # getting the animation track for the object's visibility'
          visTrack = c4d.CTrack(obj, c4d.ID_BASEOBJECT_VISIBILITY_EDITOR)
      
          # getting the curve? of the track
          curve = visTrack.GetCurve()
      
          # adding a keyframe to the curve of the track
          keyDict = curve.AddKey (curTime)
      
          # no idea what's going on here
          visTrack.FillKey (doc, obj, keyDict["key"])
          obj.InsertTrackSorted(visTrack)
      
      

      Some of these comments might be wrong as I'm not entirely sure what I'm doing and the documentation is not a lot of help.

      This does change the value of the editor visibility and toggles the keyFrame indicator orange. Orange is not really the color I want though as it doesn't save the value if I move up one frame and come back.

      Any suggestions would be appreciated.

      posted in Cinema 4D SDK
      A
      augustin