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

    Gradient Interpolation Error in 2024 release

    Cinema 4D SDK
    python 2024
    2
    3
    560
    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.
    • D
      danielsian
      last edited by

      With the new version 2024 I'm no longer able to set the interpolation knots in a gradient this way:

      knot[c4d.GRADIENTKNOT_INTERPOLATION] = c4d.GRADIENT_INTERPOLATION_SMOOTHKNOT
      

      as the console returns

      AttributeError: module 'c4d' has no attribute 'GRADIENT_INTERPOLATION_SMOOTHKNOT'
      

      But this way it works:

      knot[c4d.GRADIENTKNOT_INTERPOLATION] = 2
      

      However, from the new documentation, it should work as it always has been:
      https://developers.maxon.net/docs/py/2024_0_0/modules/c4d/CustomDataType/Gradient/index.html#Gradient.SetData

      Am I missing anything?

      BTW I'm experimenting with this example provided in the Extended Python SDK:

      """
      Copyright: MAXON Computer GmbH
      Author: Maxime Adam, Ferdinand Hoppe
      
      Description:
          - Showcases the usage of the custom data type `c4d.Gradient`.
          - Creates a material with a gradient shader in the color channel.
      
      Class/method highlighted:
          - c4d.BaseMaterial
          - c4d.BaseShader
          - c4d.Gradient
          - c4d.BaseContainer
      
      """
      
      import c4d
      
      def main():
          # Create a new material and a new gradient shader.
          material = c4d.BaseMaterial(c4d.Mmaterial)
          shader = c4d.BaseShader(c4d.Xgradient)
          
          # Get a copy of the c4d.Gradient data referenced by the gradient shader
          # and a copy of the knot data stored in the c4d.Gradient data. The knot
          # data is expressed as a c4d.BaseCoontainer.
          gradient = shader[c4d.SLA_GRADIENT_GRADIENT]
          knotData = gradient.GetData(c4d.GRADIENT_KNOT)
          
          # Iterate over all knots in the knot data container and set their 
          # interpolations to linear. Each knot in the knot data container is itself 
          # a c4d.BaseContainer, storing the data for a single knot.
          for _, knot in knotData:
              knot[c4d.GRADIENTKNOT_INTERPOLATION] = c4d.GRADIENT_INTERPOLATION_NONE
      
          # Items can also be retrieved by their index from a BaseContainer, here 
          # the first index, i.e., second item, in the container. In this case the 
          # position of the knot is written and then the knot container is being 
          # written back into the index its has been retrieved from.
          knot = knotData.GetIndexData(1)
      
          knot[c4d.GRADIENTKNOT_POSITION] = 0.5
          knotData.SetIndexData(1, knot)
          
          # After these modifications the knots must be written back into the 
          # c4d.Gradient data, because GetData() returned a copy above. This also
          # does apply to the shader and its gradient for the same reason.
          gradient.SetData(c4d.GRADIENT_KNOT, knotData)
          shader[c4d.SLA_GRADIENT_GRADIENT] = gradient
          
          # Aside from assigning the shader to the correct parameter of the 
          # material, it is also important to call BaseList2D.InsertShader(), as 
          # otherwise the setup will not work.
          material.InsertShader(shader)
          material[c4d.MATERIAL_COLOR_SHADER] = shader
      
          # Finally, the material is being inserted into the active document and an
          # update event is being pushed event to Cinema 4D, so that its GUI can 
          # catch up to our changes. 'doc' is a predefined module attribute in 
          # script manger scripts which points to the active document. It is
          # equivalent to c4d.documents.GetActiveDocument().
          doc.InsertMaterial(material)
          c4d.EventAdd()
      
      if __name__=='__main__':
          main()
      
      1 Reply Last reply Reply Quote 0
      • M
        m_adam
        last edited by

        Hi @danielsian, I we need to update this example and also the documentation about Gradient. Thanks for bringing that to our attention.
        Gradient handling is now different and heavily rely on the maxon API via the GradientInterface. The old c4d.Gradient is now just a mirror of the GradientInterface.
        Therefor all constants were moved to the maxon API. Find bellow the adapted example:

        import c4d
        import maxon
        
        def main():
            # Create a new material and a new gradient shader.
            material = c4d.BaseMaterial(c4d.Mmaterial)
            shader = c4d.BaseShader(c4d.Xgradient)
            
            # Get a copy of the c4d.Gradient data referenced by the gradient shader
            # and a copy of the knot data stored in the c4d.Gradient data. The knot
            # data is expressed as a c4d.BaseCoontainer.
            gradient = shader[c4d.SLA_GRADIENT_GRADIENT]
            knotData = gradient.GetData(c4d.GRADIENT_KNOT)
            
            # Iterate over all knots in the knot data container and set their 
            # interpolations to linear. Each knot in the knot data container is itself 
            # a c4d.BaseContainer, storing the data for a single knot.
            for _, knot in knotData:
                knot[c4d.GRADIENTKNOT_INTERPOLATION] = maxon.GRADIENT_INTERPOLATION_TYPE.SMOOTHKNOT
        
            # Items can also be retrieved by their index from a BaseContainer, here 
            # the first index, i.e., second item, in the container. In this case the 
            # position of the knot is written and then the knot container is being 
            # written back into the index its has been retrieved from.
            knot = knotData.GetIndexData(1)
        
            knot[c4d.GRADIENTKNOT_POSITION] = 0.5
            knotData.SetIndexData(1, knot)
            
            # After these modifications the knots must be written back into the 
            # c4d.Gradient data, because GetData() returned a copy above. This also
            # does apply to the shader and its gradient for the same reason.
            gradient.SetData(c4d.GRADIENT_KNOT, knotData)
            shader[c4d.SLA_GRADIENT_GRADIENT] = gradient
            
            # Aside from assigning the shader to the correct parameter of the 
            # material, it is also important to call BaseList2D.InsertShader(), as 
            # otherwise the setup will not work.
            material.InsertShader(shader)
            material[c4d.MATERIAL_COLOR_SHADER] = shader
        
            # Finally, the material is being inserted into the active document and an
            # update event is being pushed event to Cinema 4D, so that its GUI can 
            # catch up to our changes. 'doc' is a predefined module attribute in 
            # script manger scripts which points to the active document. It is
            # equivalent to c4d.documents.GetActiveDocument().
            doc.InsertMaterial(material)
            c4d.EventAdd()
        
        if __name__=='__main__':
            main()
        

        For other values please take a look at the C++ documentation of GRADIENT_INTERPOLATION_TYPE.

        Cheers,
        Maxime.

        MAXON SDK Specialist

        Development Blog, MAXON Registered Developer

        D 1 Reply Last reply Reply Quote 1
        • D
          danielsian @m_adam
          last edited by

          @m_adam
          Brilliant!
          Thanks a lot!

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