Get shader's parent ID
-
Hi all,
Is it possible to get the parent ID of a shader?
For example have a image texture and want to know if is in the diffuse or opacity channel, etc?Cheers!
Andre
-
Here's my answer
https://developers.maxon.net/forum/topic/9920/13363_solvedhow-to-know-channel/7Cheers!
-
Hey,
if I do understand your initial question correctly the linked post does not contain your answer. While both
BaseShaders
andBaseMaterials
areGeListNodes
onlyBaseShaders
that are attached to each other (a noise shader in a fusion shader for example) are in child - parent relationship.BaseMaterials
do not carry their associatedBaseShaders
as children.While it is possible to figure out the hosting material for a shader by walking over all materials in the document, actually implementing that will be probably more work than you expect as you have to accommodate the mess that is Cinemas material system under the hood: reflectance channel, layer shader, multiple material types, and the list goes on.
Let me clarify this (before an angry maxon employee points out that this all follows a bigger plan :)): I always felt that dealing with the material system is a bit of mess
Cheers
zipit -
@zipit said in Get shader's parent ID:
Hey,
if I do understand your initial question correctly the linked post does not contain your answer. While both
BaseShaders
andBaseMaterials
areGeListNodes
onlyBaseShaders
that are attached to each other (a noise shader in a fusion shader for example) are in child - parent relationship.BaseMaterials
do not carry their associatedBaseShaders
as children.While it is possible to figure out the hosting material for a shader by walking over all materials in the document, actually implementing that will be probably more work than you expect as you have to accommodate the mess that is Cinemas material system under the hood: reflectance channel, layer shader, multiple material types, and the list goes on.
Let me clarify this (before an angry maxon employee points out that this all follows a bigger plan :)): I always felt that dealing with the material system is a bit of mess
Cheers
zipitHi Zipit,
Thanks for your help and reply!
Yes you are absolutely correct in regards of the relationship betweenBaseShaders
andBaseMaterials
(and how the material system works ;)). Perhaps I should have explained it better above, before marking it as solved. So thank you for that!The solution I linked seems to be doing the opposite, where it checks the channel first and if enabled and have a shader, returns the channel. (Think this is what is written, but please correct me if i'm wrong! :))
In my case, I have a specific attribute I want to change with all of the Octane materials. The Image Texture node has a type attribute that need changing to float for specific channels. This is reduce to memory when Octane is loading and rendering textures.
Have to think of a different solution and come back...
Thanks for your help again!
Andre
-
Hi,
ah, ok, that was indeed a misunderstanding then. I was just pointing out that you cannot go (easily) from a
BaseShader
instance to its associatedBaseMaterial
but you can of course retrieve all shaders associated with aBaseList2D
via.GetFirstShader
(which includes aBaseMaterial
).Cheers
zipit -
@zipit said in Get shader's parent ID:
Hi,
ah, ok, that was indeed a misunderstanding then. I was just pointing out that you cannot go (easily) from a
BaseShader
instance to its associatedBaseMaterial
but you can of course retrieve all shaders associated with aBaseList2D
via.GetFirstShader
(which includes aBaseMaterial
).Cheers
zipitHi Zipit,
Absolutely correct! Thank you!
I've actually end up hardcoding it a bit. To be honest it works for now and if needed to be changed, it's just a matter of changing the channels list. As such:
import c4d count = 0 total_size = 0.00 def change_to_float(mat): """ If channel contains linked textures, change attribute type to Float. """ channels = [c4d.OCT_MATERIAL_ROUGHNESS_LINK, c4d.OCT_MATERIAL_SPECULAR_LINK, c4d.OCT_MAT_SPECULAR_MAP_LINK, c4d.OCT_MATERIAL_BUMP_LINK, c4d.OCT_MATERIAL_DISPLACEMENT_LINK, c4d.OCT_MIXMATERIAL_DISPLACEMENT_LINK, c4d.BLENDMAT_DISPLACEMENT_LINK, c4d.OCT_MATERIAL_OPACITY_LINK, c4d.OCT_MAT_REFLECTION_LINK, c4d.MIXMATERIAL_AMOUNT_LNK] for channel in channels: if mat[channel]: linked = mat[channel] if channel == c4d.OCT_MATERIAL_DISPLACEMENT_LINK or \ channel == c4d.BLENDMAT_DISPLACEMENT_LINK or \ channel == c4d.OCT_MIXMATERIAL_DISPLACEMENT_LINK: linked = linked[c4d.DISPLACEMENT_INPUT] if linked is not None and linked[c4d.IMAGETEXTURE_MODE] == 0: linked[c4d.IMAGETEXTURE_MODE] = 1 # Float path = linked[c4d.IMAGETEXTURE_FILE] bmp = c4d.bitmaps.BaseBitmap() bmp.InitWith(path) x, y = bmp.GetSize() # Gets the X and Y dimensions of the image size_bmp = (x * y) / 1024 global total_size total_size += size_bmp global count count += 1 return count, total_size def main(): """ Main function for textureTypeFloat(). """ mat = DOC.GetFirstMaterial() c4d.gui.SetMousePointer(c4d.MOUSE_NORMAL) if not mat: c4d.gui.MessageDialog("No material(s) in the scene!") c4d.StatusSetText("No material(s) in the scene!") return False while mat: c4d.gui.SetMousePointer(c4d.MOUSE_BUSY) if mat.GetTypeName() == 'Octane Material' or \ mat.GetTypeName() == 'Octane Mix Material' or \ mat.GetTypeName() == 'Octane Blend Material': count, total_size = change_to_float(mat) print("{0} Checked!".format(mat.GetName())) mat = mat.GetNext() c4d.EventAdd() c4d.gui.SetMousePointer(c4d.MOUSE_NORMAL) c4d.gui.MessageDialog("{0} Shaders Changed! Saving {1:.2f} Mb!".format(count, (total_size / 1024))) if __name__ == '__main__': main()
Thank you very much for your help!
Andre
-
hello,
thanks @zipit ^^just one thing, in the context of the script manager, you don't need DOC = c4d.documents.GetActiveDocument() there is already
doc
.cheers,
Manuel. -
@m_magalhaes said in Get shader's parent ID:
hello,
thanks @zipit ^^just one thing, in the context of the script manager, you don't need DOC = c4d.documents.GetActiveDocument() there is already
doc
.cheers,
Manuel.Corrected!
Thank you Manuel!