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! :relaxed:
Andre
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! :relaxed:
Andre
Here's my answer :relaxed:
https://plugincafe.maxon.net/topic/9920/13363_solvedhow-to-know-channel/7
Cheers! :+1:
Hey,
if I do understand your initial question correctly the linked post does not contain your answer. While both BaseShaders
and BaseMaterials
are GeListNodes
only BaseShaders
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 associated BaseShaders
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
MAXON SDK Specialist
developers.maxon.net
@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
zipit
Hi Zipit,
Thanks for your help and reply!
Yes you are absolutely correct in regards of the relationship between BaseShaders
and BaseMaterials
(and how the material system works ;)). Perhaps I should have explained it better above, before marking it as solved. So thank you for that! :+1:
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! :relaxed:
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 associated BaseMaterial
but you can of course retrieve all shaders associated with a BaseList2D
via .GetFirstShader
(which includes a BaseMaterial
).
Cheers
zipit
MAXON SDK Specialist
developers.maxon.net
@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
zipit
Hi Zipit,
Absolutely correct! Thank you! :+1:
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! :relaxed:
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.
MAXON SDK Specialist
@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! :relaxed:
Thank you Manuel!