Compare Gradients -> only update if changed
-
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.
-
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_comparethis 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"
-
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"
-
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.
-
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
-
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"