GetAllTextures from materials only



  • Hi @zipit ,

    Cheers for your help! ☺

    @zipit said in GetAllTextures from materials only:

    AtomArrays are soley (although sometimes mentioned in the Python docs) a C++ thing.

    Thank you for clarifying! I was suspecting that it may be the case.

    It gives me the following TypeError:
    BaseDocument.GetAllTextures expected c4d.C4DAtom, not int

    Does it work fine on your end?

    I mean I can get all textures per material but it would take longer to process.

    Thanks again! :)

    Andre



  • Hi,

    oh, then you have actually to pass the types not the smybols.

    my_types = [c4d.BaseMaterial, c4d.BaseShader]
    

    Cheers
    zipit



  • Hi,

    @zipit said in GetAllTextures from materials only:

    oh, then you have actually to pass the types not the smybols.
    my_types = [c4d.BaseMaterial, c4d.BaseShader]

    Yes, I tried that as well before, it still looks for c4d.C4DAtom 😄
    It's a weird one, but like you said it may only work with C++. I can't see what objects to pass if types or symbols don't work.

    That's ok! I appreciate your time and help with this! 👍

    Andre



  • Hi,

    sorry for all the confusion. You have to pass actual instances of objects. The following code does what you want (and this time I actually tried it myself ;)).

    import c4d
    
    def main():
        """
        """
        bc = doc.GetAllTextures(ar=doc.GetMaterials())
        for cid, value in bc:
            print cid, value
    
    if __name__=='__main__':
       main()
    

    Cheers,
    zipit



  • Hi @zipit ,

    No need to apologise! ☺
    Thank you for figuring it out! It's actually clear, now that you explained.

    Do you have access to other render engines? Just to confirm I'm not being stupid (again 😄). It seems to return a list with texture paths from only Cinema materials.

    As a summary:

    • If I do not pass the Object Instances to doc.GetAllTextures() I will have a basecontainer with all of the textures paths from every scene object including materials that are Cinema and other type.
    • If we pass specific Object Instances list doc.GetAllTextures(ar=doc.GetMaterials()) I will have a basecontainer with all of the texture paths from Cinema materials.

    If this is correct it's a great workflow if only using Cinema materials, but rest not as much, still need to filter a lot of stuff out.

    Either way, you answer my questions!

    Thank you very much once again! 😃

    Andre



  • Hi,

    no, I do not have any external render engines here. But you can filter stuff, you just have to compose ar of objects you want to include.

    my_filter = [obj for obj in doc.GetMaterials()
                 if obj.CheckType(c4d.Mterrain)]
    for _, path in doc.GetAllTextures(ar=my_filter):
        print path, "is a texture path in a terrain material."
    

    You can throw everything that is a c4d.C4DAtom into ar. You could try some of the BaseObjects for example that have a texture path.

    For external renderer materials: have you confirmed that they are actually included in doc.GetMaterials()?

    Also writing a little script, that extracts all bitmap path attributes from a GeListNode (i.e. a shader tree) tree is not too hard either. I think someone asked a similar question in combination with Octane just recently.

    Cheers
    zipit



  • Hi,

    @zipit said in GetAllTextures from materials only:

    Hi,

    no, I do not have any external render engines here. But you can filter stuff, you just have to compose ar of objects you want to include.

    my_filter = [obj for obj in doc.GetMaterials()
                 if obj.CheckType(c4d.Mterrain)]
    for _, path in doc.GetAllTextures(ar=my_filter):
        print path, "is a texture path in a terrain material."
    

    You can throw everything that is a c4d.C4DAtom into ar. You could try some of the BaseObjects for example that have a texture path.

    That's a great example! Thank you!

    For external renderer materials: have you confirmed that they are actually included in doc.GetMaterials()?

    Yep, I've tried it and can confirm that the materials are included. Following your example:

    OCTANE_MAT_ID = 1029501
    
    my_filter = [obj for obj in doc.GetMaterials()
                 if obj.CheckType(OCTANE_MAT_ID)]
    
    for _, path in doc.GetAllTextures(ar=my_filter):
        print path, "is a texture path in an Octane material."
    

    Does not print anything.

    Also writing a little script, that extracts all bitmap path attributes from a GeListNode (i.e. a shader tree) tree is not too hard either. I think someone asked a similar question in combination with Octane just recently.

    It may have been me! I do have the script but was curious to understand the GetAllTextures function, which you explained to me really well.

    Thanks again!



  • Hi,

    the function is most likely just looking for c4d.Xbitmap nodes (the shader type cinema uses to wrap around a texture file). If Octane does use its own bitmap shader, the function will not work.

    Cheers
    zipit



  • Just to add some information GetAllTexture call the message MSG_GETALLASSETS to all passed BaseList2D.

    So even 3rd party BaseList2D are supported as long as the 3rd party developer supported MSG_GETALLASSETS.

    Cheers,
    Maxime.



  • Hi @m_adam,

    Thanks for letting me know! 😃

    Andre


Log in to reply