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