SetKnot to a gradient does not work properly



  • On 17/03/2013 at 03:46, xxxxxxxx wrote:

    Hi,
    i am new to phyton and have a problem regarding the gradient of a material.
    I would like to control the knots as shown below but it does not work.
    I found a post similar to my problem and tried the adviceses from there but it does not work.

    This is my code:

    import c4d

    def main() :

    #this routine shall adjust every other knots position depending on the position of the
      #knot before and a  customer value so that the distance of Knot 0 to 1, 2 to 3 etc. ist always the same 
      #a gradient with knots does already exist

    mat = doc.GetFirstMaterial()           #Gets the first material in the materials manager
      shdr = mat[c4d.MATERIAL_COLOR_SHADER]  #The shader inside the "texture" option
      grad = shdr[c4d.SLA_GRADIENT_GRADIENT] #Get the gradient GUI and assign it to a variable
      step = 0.2

    knots_count = grad.GetKnotCount()                #How many knots are there?
      if knots_count > 1:                              #if more then 1 knot...
          for i in range(0, knots_count,2) :            #for every other knot (begin with 0)
                                    
              knots_pos = grad.GetKnot(i)              #get the "dict" values like index, pos, bias etc.
              position = knots_pos["pos"]              #get only the position value
            
              grad.SetKnot(index=i+1, pos=position+step) #set the new position for every second knot does not work
              shdr[c4d.SLA_GRADIENT_GRADIENT] = grad     #write the value back to the system

    shdr[c4d.SLA_GRADIENT_GRADIENT] = grad #Update the gradient data
      mat.Message(c4d.MSG_UPDATE )           #Update the material changes
      mat.Update( True, True )               #Update the material's icon image

    c4d.EventAdd()                         #Update C4D so things update quickly

    if __name__=='__main__':
      main()

    I cannot set the new position, the knot always jumps to the 0 position. Moreover it seams that i cannot change the first knot witch has the index 0 as far as i know.
    Any ideas?

    Thanks, CoffeeCup



  • On 17/03/2013 at 08:09, xxxxxxxx wrote:

    I went through this same thing some time ago.
    These are my notes on the subject gained from talking with Maxon support:

    -To edit a Gradient data (color knots, interpolation, mode etc.) it needs to be reassigned completely  
    We cannot simply move color knots(only their handles). So to change them we have to delete them using Flush  
    Then re-create them from scratch again with the new position & color data  
      
    -It's only possible to get/set the gradient data with GetData() & SetData().  
     So to retrieve the gradient interpolation we have to call: gradient.GetData(c4d.GRADIENT_INTERPOLATION)  
     Which is c4d.GRADIENT_INTERPOLATION_SMOOTHKNOT by default (see customgui_gradient.h).
    

    And here is a working example script that shows how to create your own knots changes

    #This is an example of changing an existing gradient in a material  
      
    import c4d  
      
    def main() :  
      
      # First we get the material we want to work with  
      
      mat = doc.GetFirstMaterial()           #Gets the first material in the materials manager  
      color = c4d.DescLevel(c4d.MATERIAL_COLOR_COLOR, c4d.DTYPE_COLOR)#The material's color channel  
      
      
      # Now lets grab the gradient(also known as "Xs**gradient") that is already there in the color channel  
      # We are not creating that gradient with code in this example..So it needs to be there already  
      
      shdr = mat[c4d.MATERIAL_COLOR_SHADER]  #The shader inside the "texture" option  
      shdr[c4d.SLA_GRADIENT_TYPE]= 2000      #The "Type" option...ID's are found in the xs**gradient.h file  
      shdr[c4d.SLA_GRADIENT_CYCLE] = True    #The "Cycle" option  
      shdr[c4d.SLA_GRADIENT_TURBULENCE]=0    #The "Turbulence" option  
      shdr[c4d.SLA_GRADIENT_SPACE]= 2021     #The "Space" option...ID's are found in the xs**gradient.h file  
      
      
      # Now lets drill into the gradient shader to control the knots, interpolation, and color bar  
      
      grad = shdr[c4d.SLA_GRADIENT_GRADIENT] #Get the gradient GUI and assign it to a variable   
      grad.FlushKnots()                      #Delete all existing knots  
      k1 = grad.InsertKnot(col=c4d.Vector(0.5, 0.1, 0.0), pos=0.0,index = 0)  #Gets the first knot  
      k2 = grad.InsertKnot(col=c4d.Vector(1.0 , 1.0, 1.0), pos=1.0,index= 1)  #Gets the second knot  
      
      k1 = grad.GetKnot(k1)  #Get the first knot so we can read it's dictionary values  
      k1pos = k1['pos']      #The position of the knot from the dict value 'pos'  
      k1col = k1['col']      #The color of the knot from the dict value 'col'  
            
      k2 = grad.GetKnot(k2)  #Get the second knot so we can read it's dictionary values  
      k2pos = k2['pos']      #The position of the knot from the dict value 'pos'  
      k2col = k2['col']      #The color of the knot from the dict value 'col'  
        
      k3 = grad.InsertKnot(col=k1col+k2col/2, pos=k1pos+k2pos/2) #Create a new knot using the other knot's values  
      
      
      
    # Now lets change the position of the first knot's handle(diamond shape attribute) to this new value  
      
      k1pos = 0.3              
      grad.SetKnot(index=0,pos=k1pos)        #Set the handle to this new value  
      
      grad.SetData(c4d.GRADIENT_INTERPOLATION, c4d.GRADIENT_INTERPOLATION_CUBICKNOT) #Change the interpolation  
      
      shdr[c4d.SLA_GRADIENT_GRADIENT] = grad #Update the gradient data we changed  
      mat.Message(c4d.MSG_UPDATE )           #Update the material changes  
      mat.Update( True, True )               #Update the material's icon image        
      
      c4d.EventAdd()                         #Update C4D so things update quickly  
      
    if __name__=='__main__':  
      main()
    

    -ScottA



  • On 18/03/2013 at 11:01, xxxxxxxx wrote:

    Thanks, Scott.

    Well, i am still not sure what to do.
    Do i have to delete all knots, then insert the new ones with InsertKnot and then change the knots attributes with SetKnots? I am only interested in the position of the knots.

    CoffeeCup



  • On 18/03/2013 at 12:12, xxxxxxxx wrote:

    Yes. That should work.

    You can get the existing knots by their index numbers and save their vector positions into variables or your own list.
    Then you flush all the existing knots and create new ones.
    Then you set their 'pos' values using the previously saved vectors.

    -ScottA



  • On 19/03/2013 at 14:22, xxxxxxxx wrote:

    Hi, Scott,

    i think i get it.
    Simply by inserting the knots with InsertKnot. But i am still not sure what SetKnot does acctually - i don't need it.  But who cares, it works.

    Thanks
    CoffeeCup


Log in to reply