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

    SetKnot to a gradient does not work properly

    PYTHON Development
    0
    5
    538
    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.
    • H
      Helper
      last edited by

      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

      1 Reply Last reply Reply Quote 0
      • H
        Helper
        last edited by

        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

        1 Reply Last reply Reply Quote 0
        • H
          Helper
          last edited by

          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

          1 Reply Last reply Reply Quote 0
          • H
            Helper
            last edited by

            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

            1 Reply Last reply Reply Quote 0
            • H
              Helper
              last edited by

              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

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