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

    SetTimeRight fail!

    Cinema 4D SDK
    python s22
    3
    10
    1.5k
    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.
    • chuanzhenC
      chuanzhen
      last edited by

      Hi, when the value I set is very small, such as BaseTime.get() is 0.001, by using SetTimeRight(), but when I access this value again by script, the result is BaseTime.get() is 0. but SetTimeLeft() can Successfully set, such as BaseTime.get() is -0.001 !
      Thanks for any help!

              key.SetInterpolation(curve,c4d.CINTERPOLATION_SPLINE)
              
      
              key.SetTimeLeft(curve,L_time_v)
              key.SetValueLeft(curve,TL_vector[1])
              key.SetTimeRight(curve, R_time_v)
              key.SetValueRight(curve, TR_vector[1])
      
              key[c4d.ID_CKEY_PRESET] = c4d.ID_CKEY_PRESET__CUSTOM
              key.ChangeNBit(c4d.NBIT_CKEY_AUTO, c4d.NBITCONTROL_CLEAR)
              key.ChangeNBit(c4d.NBIT_CKEY_BREAK, c4d.NBITCONTROL_SET)
              key.ChangeNBit(c4d.NBIT_CKEY_KEEPVISUALANGLE, c4d.NBITCONTROL_SET)
      

      相信我,可以的!

      ferdinandF 1 Reply Last reply Reply Quote 0
      • A
        AiMiDi
        last edited by

        Please use the curve->SetTangents(index, &curveTleftX, &curveTRightX, &curveTleftY, &curveTRightY); .
        Detailed see:
        https://developers.maxon.net/forum/topic/13352/ccurve-gettangents-broken
        https://developers.maxon.net/forum/topic/13344/ckey-auto-tangents

        chuanzhenC 1 Reply Last reply Reply Quote 0
        • ferdinandF
          ferdinand @chuanzhen
          last edited by ferdinand

          Hello @chuanzhen,

          thank you for reaching out to us. There is some truncating going on when setting the time component of a key to a value which is within the sub-second range. But I cannot reproduce any differences between the left and right tangent and also not than a tangent is zero when it should not be zero. within a second.

          I would declare this an acceptable limitation of the Cinema 4D; since animation definitions below the millisecond range do not seem particularly useful for most users. If you can reproduce differences for setting the left and right time value of a key, I would ask you to provide an example file and/or executable code. But even then, chances are good that we will declare this an acceptable limitation.

          Cheers,
          Ferdinand

          The output of the example code below:

          doc.GetFps()=300
          
          
           Key Index|                Set Value|            GetTimeLeft()|           GetTimeRight()
          ----------------------------------------------------------------------------------------
                   0|                   0.0125|                    0.013|                    0.013
                   1|                    0.012|                    0.012|                    0.012
                   2|                   0.0115|                    0.012|                    0.012
                   3|                    0.011|                    0.011|                    0.011
                   4|                   0.0105|                    0.011|                    0.011
                   5|                     0.01|                     0.01|                     0.01
                   6|                   0.0095|                     0.01|                     0.01
                   7|     0.009000000000000001|                    0.009|                    0.009
                   8|                   0.0085|                    0.009|                    0.009
                   9|                    0.008|                    0.008|                    0.008
                  10|                   0.0075|                    0.008|                    0.008
                  11|                    0.007|                    0.007|                    0.007
                  12|     0.006500000000000001|                    0.007|                    0.007
                  13|                    0.006|                    0.006|                    0.006
                  14|                   0.0055|                    0.006|                    0.006
                  15|                    0.005|                    0.005|                    0.005
                  16|    0.0045000000000000005|                    0.005|                    0.005
                  17|                    0.004|                    0.004|                    0.004
                  18|                   0.0035|                    0.004|                    0.004
                  19|                    0.003|                    0.003|                    0.003
                  20|                   0.0025|                    0.003|                    0.003
                  21|                    0.002|                    0.002|                    0.002
                  22|                   0.0015|                    0.002|                    0.002
                  23|                    0.001|                    0.001|                    0.001
                  24|                   0.0005|                    0.001|                    0.001
          

          The code:

          """Provides an example for setting the time component of key-tangents to very
          low values.
          
          Creates a cube object with tweenty-five keys in a position-x track. Then loops
          over the time component of the key-tangents of these keys, sets them to
          increasingly smaller values and prints out the time values before and after
          the changes, as well as the true value of the time t.
          """
          import c4d
          
          
          def main():
              """Runs the example.
              """
              # Creates a cube with a postion-x animation with 25 keys.
              cube = c4d.BaseList2D(c4d.Ocube)
              if cube is None:
                  raise MemoryError("Could not allocate object.")
          
              descID = c4d.DescID (c4d.DescLevel(c4d.ID_BASEOBJECT_REL_POSITION),
                                   c4d.DescLevel(c4d.VECTOR_X))
              track = c4d.CTrack(cube, descID)
              if track is None:
                  raise MemoryError("Could not allocate track.")
              cube.InsertTrackSorted(track)
              curve = track.GetCurve()
              count = 25
          
              for t in range(count):
                  result = curve.AddKey(c4d.BaseTime(t))
                  if result is None:
                      raise MemoryError("Could not allocate key.")
                  result["key"].SetValue(curve, t ** 1.5)
                  result["key"].SetInterpolation(curve, c4d.CINTERPOLATION_SPLINE)
          
              doc.InsertObject(cube)
              c4d.EventAdd()
          
              # Loop over the created key and print out their time-tagent values while
              # attempting to set them to incerasingly smaller values.
              print (f"{doc.GetFps()=}\n\n")
              print (f"{'Key Index':>10}|{'Set Value':>25}|{'GetTimeLeft()':>25}|"
                     f"{'GetTimeRight()':>25}")
              line = "{:>10}|{:>25}|{:>25}|{:>25}"
              print ("-"*88)
          
              for i in range(curve.GetKeyCount()):
                  ckey = curve.GetKey(i)
                  t = (count - i) * 0.0005
                  ckey.SetTimeLeft(curve, c4d.BaseTime(t))
                  ckey.SetTimeRight(curve, c4d.BaseTime(t))
                  print (line.format(
                      i, t, ckey.GetTimeLeft().Get(), ckey.GetTimeRight().Get()))
              c4d.EventAdd()
          
          
          if __name__ == '__main__':
              main()
          

          MAXON SDK Specialist
          developers.maxon.net

          1 Reply Last reply Reply Quote 0
          • chuanzhenC
            chuanzhen @AiMiDi
            last edited by

            @aimidi said in SetTimeRight fail!:

            SetTangents

            Thanks for your help,but not find SetTangents() in python sdk

            相信我,可以的!

            ferdinandF 1 Reply Last reply Reply Quote 0
            • ferdinandF
              ferdinand @chuanzhen
              last edited by

              Hello @chuanzhen,

              SetTangent() is a member of CCurve and you must use it when you want to access tangents of keys with a non-custom interpolation. CKey.Get/SetTimeLeft/Right on the other hand always accesses the raw underlying tangent data. So, even when key[c4d.ID_CKEY_PRESET] != c4d.ID_CKEY_PRESET__CUSTOM, CKey.Get/SetTimeLeft/Right will always retrieve the then for the user invisible custom tangents.

              Long story short: using CCurve.Get\SetTangent() should not make a difference for you in this case. At least I do not see how it should. But you can of course try.

              Cheers,
              Ferdinand

              MAXON SDK Specialist
              developers.maxon.net

              chuanzhenC 1 Reply Last reply Reply Quote 0
              • chuanzhenC
                chuanzhen @ferdinand
                last edited by chuanzhen

                @ferdinand Thanks for your help!
                I have been looking for the source of the problem. After seeing your answer, I should have looked in the wrong direction (I always thought that SetTimeLeft() could not accurately transmit the value I calculated). Below I uploaded a GIF to show the problem I encountered more accurately.
                1: I use Add key slider to dynamically add functions. It will call my autoweight function by default. It can be seen that in the process of dynamic addition, the error of RightTime == 0 of some key frames appears
                2: When I dynamically use EasyInOut slider to perform the smoothing process, it also calls the autoweight function, and it still does not correct the wrong situation
                3: When I use c4d's default auto tangent classic for these key frames, then use EasyInOut again to perform the smoothing process, the autoweight function will work normally.
                So I don’t know why this happens, because the above code is used to set the key in the autoweight function

                It seems that can't see the gif in full,i upload a file ,can be download. easyinout2.gif

                easyinout2.gif

                相信我,可以的!

                1 Reply Last reply Reply Quote 0
                • ferdinandF
                  ferdinand
                  last edited by ferdinand

                  Hello @chuanzhen,

                  thank you for your detailed explanation, but I unfortunately still struggle a bit with the details. I will answer as best as I can from what I do understand.

                  I assume your major problem are the kinks that are introduced into your spline by incorrect tangents.

                  1. Cinema 4D has multiple tangent modes which partially or fully take away the control from the user how the tangents between keys are set. So, when you are in another mode than ID_CKEY_PRESET__CUSTOM or have any of the automatisms enabled in ID_CKEY_PRESET__CUSTOM, then setting the raw tangents with CKey won't help you, as they always set the raw tangents. As lined out before, when you want to set tangents with the automatisms enabled, you must must use the tangent methods attached to CCurve.
                  2. When you just want to ensure the smoothness/continuity of your curve, you can also use CCurve.SetTimeLeftAdjustValue and its counter part for the right tangent.
                  3. Finally, when you want to construct a smooth spline from a to b with all automatisms turned of, you will have to get your hands dirty yourself. I once posted this example, but this is more complicated than your case, since this was for 3D.
                  4. When you just want to subdivide a curve without changing its curvature, we cannot give you any detailed instructions on how the curve interpolation of ours works, but you should get pretty close with the common cubic-bezier curves.

                  If there are remaining questions, I would propose that you follow the recommended pattern of posting executable example code and line out what you would expect to happen and what happens instead.

                  Cheers,
                  Ferdinand

                  MAXON SDK Specialist
                  developers.maxon.net

                  chuanzhenC 1 Reply Last reply Reply Quote 0
                  • chuanzhenC
                    chuanzhen @ferdinand
                    last edited by chuanzhen

                    @ferdinand Thank you for your detailed answer!
                    In my autoweight function, there is no error in the calculation result of the tangent, but when setting the CKey, there is a problem. It seems that there are too many parameters set, which causes the left and right time values of the key frame to be set according to the calculation results. Then an unknown change was made, causing the final value to not match the calculated value. Although I still don't know why those settings will cause the value to go wrong.

                    wrong code:

                        key.SetInterpolation(curve,c4d.CINTERPOLATION_SPLINE)
                    
                        key.SetTimeLeft(curve,L_time_v)
                        key.SetValueLeft(curve,TL_vector[1])
                        key.SetTimeRight(curve, R_time_v)
                        key.SetValueRight(curve, TR_vector[1])
                    
                        key[c4d.ID_CKEY_PRESET] = c4d.ID_CKEY_PRESET__CUSTOM
                        key.ChangeNBit(c4d.NBIT_CKEY_AUTO, c4d.NBITCONTROL_CLEAR)
                        key.ChangeNBit(c4d.NBIT_CKEY_BREAK, c4d.NBITCONTROL_SET)
                        key.ChangeNBit(c4d.NBIT_CKEY_KEEPVISUALANGLE, c4d.NBITCONTROL_SET)
                    

                    current code:

                        key.SetInterpolation(curve,c4d.CINTERPOLATION_SPLINE)
                        key.SetTimeLeft(curve,L_time_v)
                        key.SetValueLeft(curve,TL_vector[1])
                        key.SetTimeRight(curve, R_time_v)
                        key.SetValueRight(curve, TR_vector[1])
                        key.ChangeNBit(c4d.NBIT_CKEY_AUTO, c4d.NBITCONTROL_CLEAR)
                    

                    Using the current code, the left and right time values of CKey, the calculated result matches the final result.
                    this is an print example:

                        Calculate_RTime: 0.0301874202486 After_Set_Get_from_Key_RTime 0.03
                    

                    gif also shows that it is working fine now.

                    easyinout_end.gif

                    相信我,可以的!

                    1 Reply Last reply Reply Quote 0
                    • ferdinandF
                      ferdinand
                      last edited by

                      Hey @chuanzhen,

                      great to hear that you found your solution! Also: I have not missed that you reported problems with your GIFs. We have discussed this problem internally before (it was then me having a problem) but then moved on. I will reraise the topic and we will see what we can do. The problem is a bit weird; I cannot guarantee that we will fix it. I think it has something to do with standard conformance of file types. ScreenToGif, the tool I am using, seems to produce files that deviate from some sort of core standard. But in other cases, the same files load fine. As I said, it is a bit weird, but we will see if we can squeeze in some time for looking at it.

                      Cheers,
                      Ferdinand

                      MAXON SDK Specialist
                      developers.maxon.net

                      chuanzhenC 1 Reply Last reply Reply Quote 0
                      • chuanzhenC
                        chuanzhen @ferdinand
                        last edited by

                        @ferdinand I also use ScreenToGif to make pictures!

                        相信我,可以的!

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