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

    GetAllTextures from materials only

    Cinema 4D SDK
    3
    12
    2.2k
    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.
    • A
      AndreAnjos
      last edited by AndreAnjos

      Hi all,

      Following this post: https://developers.maxon.net/forum/topic/10645/14093_getalltextures-not-working

      Where if we want to get the textures from specific objects (in my case just the material objects), you need to add them to an AtomArray. Unfortunately, I cannot understand how to append this list to it, so I can can pass it to GetAlltextures. So I'm missing something here.

      BaseDocument.GetAllTextures(isNet=True, ar=None)
      ar (List[c4d.C4DAtom]) – An atom array to get the textures for. If None (default), all used textures in the document will be returned.

      Thank you in advance! 😃

      Andre

      1 Reply Last reply Reply Quote 0
      • ferdinandF
        ferdinand
        last edited by

        Hi,

        AtomArrays are soley (although sometimes mentioned in the Python docs) a C++ thing. C4d expects you to pass a list of type symbols for ar, which will define the filter for the objects that will be returned.

        I never used this method, but something like the following should do what you want. But you might have to fine tune the type symbols, depending on what you want to do.

        my_types = [c4d.Mmaterial, c4d.Xbase]
        tex_filenames = my_document.GetAllTextures(ar=my_types)
        

        Cheers
        zipit

        MAXON SDK Specialist
        developers.maxon.net

        1 Reply Last reply Reply Quote 1
        • A
          AndreAnjos
          last edited by

          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

          1 Reply Last reply Reply Quote 0
          • ferdinandF
            ferdinand
            last edited by

            Hi,

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

            my_types = [c4d.BaseMaterial, c4d.BaseShader]
            

            Cheers
            zipit

            MAXON SDK Specialist
            developers.maxon.net

            1 Reply Last reply Reply Quote 0
            • A
              AndreAnjos
              last edited by

              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

              1 Reply Last reply Reply Quote 0
              • ferdinandF
                ferdinand
                last edited by

                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

                MAXON SDK Specialist
                developers.maxon.net

                1 Reply Last reply Reply Quote 3
                • A
                  AndreAnjos
                  last edited by AndreAnjos

                  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

                  1 Reply Last reply Reply Quote 0
                  • ferdinandF
                    ferdinand
                    last edited by ferdinand

                    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

                    MAXON SDK Specialist
                    developers.maxon.net

                    1 Reply Last reply Reply Quote 2
                    • A
                      AndreAnjos
                      last edited by

                      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!

                      1 Reply Last reply Reply Quote 0
                      • ferdinandF
                        ferdinand
                        last edited by

                        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

                        MAXON SDK Specialist
                        developers.maxon.net

                        1 Reply Last reply Reply Quote 1
                        • M
                          m_adam
                          last edited by

                          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.

                          MAXON SDK Specialist

                          Development Blog, MAXON Registered Developer

                          A 1 Reply Last reply Reply Quote 1
                          • A
                            AndreAnjos @m_adam
                            last edited by

                            Hi @m_adam,

                            Thanks for letting me know! 😃

                            Andre

                            1 Reply Last reply Reply Quote 0
                            • First post
                              Last post