Get selected keyframe in f-curve editor



  • On 06/04/2017 at 07:47, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:   R17 
    Platform:   Windows  ;   
    Language(s) :       PYTHON  ;

    ---------
    Hey there,

    for my plugin I need to know which keyframe and or fcurve has been selected.

    I know of checking key via GetNBit, running the following code in a loop returns 0 for every single bit when selecting a curve or key in the f-curve timeline.
    If I select keys in dopesheet-mode c4d.NBIT_TLx_SELECT returns the right values

    print ("------------------ SEL BITS KEY ---------------")  
    print str(key.GetNBit(c4d.NBIT_TL1_SELECT))  
    print str(key.GetNBit(c4d.NBIT_TL2_SELECT))  
    print str(key.GetNBit(c4d.NBIT_TL3_SELECT))  
    print str(key.GetNBit(c4d.NBIT_TL4_SELECT))  
    print ("------------------ SEL BITS CURVE ---------------")  
      
    print str(curve.GetNBit(c4d.NBIT_TL1_FCSELECT))  
    print str(curve.GetNBit(c4d.NBIT_TL2_FCSELECT))  
    print str(curve.GetNBit(c4d.NBIT_TL3_FCSELECT))  
    print str(curve.GetNBit(c4d.NBIT_TL4_FCSELECT))  
    print ("------------------ SEL BITS END -----------------")
    

    I can act on any curve or keys that get I try this part of the code, so there shouldnt be a problem there.

    Am I using this feature wrong or is there a bug with the NBits? Is there any other way to find out if a key got selected in the f-curve editor?



  • On 06/04/2017 at 08:13, xxxxxxxx wrote:

    Hello and welcome unti have a look at this thread
    https://plugincafe.maxon.net/topic/5517/5536_selected-keys-move-keys
    Basicly you have to check c4d.BIT_ACTIVE

    Moreover I know it's a bit stupid but SDK forum is for C++ while in your case you must use Python category.



  • On 06/04/2017 at 08:38, xxxxxxxx wrote:

    Hey, thanks for the quick reply. I already found that thread.

    Sadly, this doesn't work as CKey does not inherit from BaseList2D which provides the GetBit functionality.

    Beeing thorough, I already tested getBit() and check for active in code which doesn't work.

    Oh, ok..  I put this post into the general sdkHelp as it seems to be the same case with the c++ api



  • On 06/04/2017 at 10:23, xxxxxxxx wrote:

    Hoo yes you are right I can't either get the selection in Fcurves mode



  • On 06/04/2017 at 11:13, xxxxxxxx wrote:

    I think this is what you're look for

    import c4d  
    def main() :  
      
      obj = doc.GetActiveObject()  
      if obj is None: return False      
        
      trk = obj.GetFirstCTrack()  
      if trk is None: return False      
        
      curve = trk.GetCurve()  
      key = curve.GetKey(0)      #The first key on the track (change as desired)  
      selected = key.GetNBit(5)  #5 is the ID for the animation layout's timeline GUI  
        
      if selected == True:  
          print key.GetValue()  
      c4d.EventAdd(c4d.MSG_UPDATE)   
      
    if __name__=='__main__':  
      main()
    

    -ScottA



  • On 07/04/2017 at 00:12, xxxxxxxx wrote:

    Hey Scott, thanks for your answer.

    Basically key.GetNBit(5) is the same as key.GetNBit(c4d.NBIT_TL1_SELECT) which works in dopesheet mode but doesn't in f-curve mode, like indicated in my first question. Dopesheetmode is not a workaround for my intended function, so if anyone could shed some light on that, it would be great. Also, if this is a bug in R17 that has been fixed in R18, let me know.

    Other than that your code is perfect for testing my snippet and see if any NBIT returns 1 in cinema without reloading my plugin :) Thanks for that.



  • On 07/04/2017 at 05:18, xxxxxxxx wrote:

    Hi,

    sorry for being late to the party.
    So, there are these four private bits: NBIT_TL1_SELECT2 to NBIT_TL4_SELECT2
    I talked to our development and you may use them read-only. So you may detect if a key is selected in F-Curve mode. Please do not try to change the selection with these. It might have unexpected consequences and you have been warned! I know, I say something like this sometimes with a wink, but not this time. I really mean it, please use it for reading, only. In the end no one will benefit if customer's projects get destroyed, right?



  • On 07/04/2017 at 06:42, xxxxxxxx wrote:

    So what is the utility of the NBIT_TL1_FCSELECT?
    In case we want to make a selection on the fcruve. Does Set NBIT_TL1_SELECT will automaticly set NBIT_TL1_SELECT2 ? And the most important is it safe?



  • On 07/04/2017 at 09:32, xxxxxxxx wrote:

    Hey, thanks a lot, NBIT_TLx_SELECT2 did the job perfectly.

    Find attached a 'fixed' version of Scotts code:
    This code only checks the very first key it can find, to use it to detect more than that you will have to run it in a loop. I might whip up a short example for everyone else next week.
    Thanks again.

    Just to dig a little deeper, is there an API even when a key gets selected? - But this is just for optimization purposes, so dont bother if its to complicated.

    I can't seem to mark this post as solved, so if any admin would do that it would be great :)

    import c4d  
    def main() :  
      
      obj = doc.GetActiveObject()  
      if obj is None: return False      
        
      trk = obj.GetFirstCTrack()  
      if trk is None: return False      
        
      curve = trk.GetCurve()  
      key = curve.GetKey(0)      #The first key on the track (change as desired)  
      selected = key.GetNBit(NBIT_TL1_SELECT2)  #5 is the ID for the animation layout's timeline GUI  
        
      if selected == True:  
          print key.GetValue()  
      c4d.EventAdd(c4d.MSG_UPDATE)   
      
    if \__name\_\_=='\__main\_\_':  
      main()  
    


  • On 07/04/2017 at 09:32, xxxxxxxx wrote:

    Sorry about the unti. I wasn't really sure what you were asking for since there is no "dope sheet" mode in C4D. Only key mode & f-curve modes.

    @gr4ph0s,
    The NBIT_TL1_SELECT bit does not select the keys.
    I've used it several times myself, and so far it seems to be safe with no issues.
    Example:

    import c4d  
    def main() :  
      
      obj = doc.GetActiveObject()  
      if obj is None: return False      
        
      trk = obj.GetFirstCTrack()  
      if trk is None: return False      
        
      curve = trk.GetCurve()  
      key = curve.GetKey(0)      #The first key on the track (change as desired)  
      
      #Do this code block only if we are in F-Curve mode  
      if c4d.IsCommandChecked(465001190) :  
            
          #Selects the track's curve...but not the curve's keys  
          trk.ChangeNBit(c4d.NBIT_TL1_FCSELECT, c4d.NBITCONTROL_SET)  
          print trk.GetNBit(c4d.NBIT_TL1_FCSELECT)  
            
          trk.ChangeNBit(c4d.NBIT_TL1_FCSELECT, c4d.NBITCONTROL_CLEAR)  #un-selects the curve  
          print trk.GetNBit(c4d.NBIT_TL1_FCSELECT)  
       
      c4d.EventAdd(c4d.MSG_UPDATE)   
      
    if __name__=='__main__':  
      main()
    

    -ScottA


Log in to reply