Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python 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

    Compare Gradients -> only update if changed

    Scheduled Pinned Locked Moved PYTHON Development
    6 Posts 0 Posters 1.1k Views
    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 Offline
      Helper
      last edited by

      On 14/02/2018 at 01:05, xxxxxxxx wrote:

      Hi all,

      I am scripting a simple photostudio Helper which has a simple color gradient as backdrop.

      Anyway my userdata has a gradient controller which is copied into a material channnel.

      The Problem: hence of the event update its updating everytime.

      Question: Can i copy the existing gradient and compare it to the userdata and only update if something has changed ?

      i tried this with no luck.

      if op[c4d.ID_USERDATA,53] != sha[c4d.SLA_GRADIENT_GRADIENT]:
      

      any idea how to manag this "update"

      here is the function:

      def insertshader (op) :       
          if doc.SearchMaterial('ops Backdrop Gradient') != None: # Falesafe if somebody renames or deletes the shader   
              gra = op[c4d.ID_USERDATA,53]   
              sha = c4d.BaseShader(c4d.Xgradient)   
              sha[c4d.SLA_GRADIENT_GRADIENT] = gra #c4d.SLA_FRESNEL_GRADIENT   
              mat = doc.SearchMaterial('ops Backdrop Gradient')   
              mat.InsertShader(sha)   
              mat[c4d.MATERIAL_COLOR_SHADER] = sha   
              mat.Message(c4d.MSG_UPDATE)   
              mat.Update(True, True)   
          else:   
              print "Did not find shader named: ops Backdrop Gradient"
      

      thanks for your time.

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

        On 14/02/2018 at 02:42, xxxxxxxx wrote:

        After reading this
        https://developers.maxon.net/docs/Cinema4DCPPSDK/html/page_manual_baseshader.html#page_manual_baseshader_compare

        this seems to work. crossing fingers.

        def insertshader (op) :       
            if doc.SearchMaterial('ops Backdrop Gradient') != None: # Falesafe if somebody renames or deletes the shader   
                mat = doc.SearchMaterial('ops Backdrop Gradient')   
                existingshader = mat[c4d.MATERIAL_COLOR_SHADER].GetClone()   
                  
                gra = op[c4d.ID_USERDATA,53]   
                sha = c4d.BaseShader(c4d.Xgradient)   
                sha[c4d.SLA_GRADIENT_GRADIENT] = gra #c4d.SLA_FRESNEL_GRADIENT   
                  
                if existingshader.Compare(sha) == False:   
                    mat.InsertShader(sha)   
                    mat[c4d.MATERIAL_COLOR_SHADER] = sha   
                    mat.Message(c4d.MSG_UPDATE)   
                    mat.Update(True, True)   
                else :   
                    print "same same"         
            else:   
                print "Did not find shader named: ops Backdrop Gradient"
        
        1 Reply Last reply Reply Quote 0
        • H Offline
          Helper
          last edited by

          On 14/02/2018 at 06:04, xxxxxxxx wrote:

          Ok, you seem to have already found what you need.

          Your first attempt failed, because you compared the acttual instances of the gradient shaders and as those are two individual shaders (even though with possibly identical parameters), the comparison ended with always being false.

          A few additions, you may already know, but maybe interesting for future readers:
          Use of above mentioned Compare() function to compare shaders, is indeed the way to go.
          As the manual mentions, this is basically a comparison of the BaseContainer, so it's more or less equal to:

              shdColor = mat[c4d.MATERIAL_COLOR_SHADER]
              shdTransp = mat[c4d.MATERIAL_TRANSPARENCY_SHADER]
              bcShdColor = shdColor.GetDataInstance()
              bcShdTransp = shdTransp.GetDataInstance()
              if bcShdColor == bcShdTransp:
                  print "Shaders are equal"
          

          Please note, this does not only compare the gradient, but also the other shader parameters (like e.g. Turbulence).
          In order to compare just the gradients:

              shdColor = mat[c4d.MATERIAL_COLOR_SHADER]
              shdTransp = mat[c4d.MATERIAL_TRANSPARENCY_SHADER]
              grdColor = shdColor[c4d.SLA_GRADIENT_GRADIENT]
              grdTransp = shdTransp[c4d.SLA_GRADIENT_GRADIENT]
              if hash(grdColor) == hash(grdTransp) :
                  print "Gradients are equal"
          
          1 Reply Last reply Reply Quote 0
          • H Offline
            Helper
            last edited by

            On 14/02/2018 at 07:36, xxxxxxxx wrote:

            Thanks i chnaged my script to just compare the gradients seems to work, but my brute shader insert of course overwrites the hole "gradient shader" ,

            is there an option just to paste the gradient into th gradient shader ?

            Thanks for your supoort Andreas.

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

              On 15/02/2018 at 03:00, xxxxxxxx wrote:

              You can simply do:

                  shdColor = mat[c4d.MATERIAL_COLOR_SHADER]
                  shdTransp = mat[c4d.MATERIAL_TRANSPARENCY_SHADER]
                  grdColor = shdColor[c4d.SLA_GRADIENT_GRADIENT]
                  shdTransp[c4d.SLA_GRADIENT_GRADIENT] = grdColor
              
              1 Reply Last reply Reply Quote 0
              • H Offline
                Helper
                last edited by

                On 15/02/2018 at 04:50, xxxxxxxx wrote:

                Thanks Andreas, I am a fan of doing things right even when my coding abilities are limited.

                Here is the updated version of my function if anybody gets confused and wants to analyse a working version. (of course tailored to my needs)

                def insertshader (op) :       
                    if doc.SearchMaterial('ops Backdrop Gradient') != None: # Falesafe if somebody renames or deletes the shader   
                        mat = doc.SearchMaterial('ops Backdrop Gradient')   
                        gra = op[c4d.ID_USERDATA,53] #   
                          
                        if mat[c4d.MATERIAL_COLOR_SHADER] != None:   
                            existingshader = mat[c4d.MATERIAL_COLOR_SHADER].GetClone()   
                            sha = c4d.BaseShader(c4d.Xgradient)   
                            sha[c4d.SLA_GRADIENT_GRADIENT] = gra   
                            shdColor = mat[c4d.MATERIAL_COLOR_SHADER]      # only compare gradients https://developers.maxon.net/forum/topic/10634/14081_compare-gradients--only-update-if-changed   
                            grdColor = shdColor[c4d.SLA_GRADIENT_GRADIENT]   
                               
                            if hash(grdColor) != hash(gra) :   
                                    existingshader = mat[c4d.MATERIAL_COLOR_SHADER]   
                                    existingshader[c4d.SLA_GRADIENT_GRADIENT] = gra   #insert only the gradient into the existing shader   
                                    mat.Message(c4d.MSG_UPDATE)   
                                    mat.Update(True, True)   
                                        
                        else: #blantly insert a color gradient if the user delete it   
                            gui.MessageDialog('Please leave the Color Gradient intact. You can change everything else. If needed make your own Material.')   
                            sha = c4d.BaseShader(c4d.Xgradient)   
                            mat.InsertShader(sha)   
                            mat[c4d.MATERIAL_COLOR_SHADER] = sha               
                            sha[c4d.SLA_GRADIENT_GRADIENT] = gra #c4d.SLA_FRESNEL_GRADIENT   
                  
                    else:   
                        # to do create the shader fom scratch by script   
                        print "Did not find shader named: ops Backdrop Gradient"
                
                1 Reply Last reply Reply Quote 0
                • First post
                  Last post