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

    images for the material shaders not assigned to the specified shader

    Cinema 4D SDK
    python 2023 windows
    2
    6
    868
    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.
    • L
      lednevandrey
      last edited by ferdinand

      Hello everyone.

      I am new to C4D scripts.
      I may have posted this message in the wrong section of this forum, please let me know if that happened.

      I want to create a script to get a material with certain properties and assign it to an object selected in the scene.
      For the Brightness and Displacement channels, images from the disk are added.

      import c4d
      from c4d import storage
      
      def main():
      
          # doc = c4d.documents.BaseDocument
      
          # Step 1: Create a new material
          material = c4d.BaseMaterial(c4d.Mmaterial)  # Creating new material
          material.SetName("MyMat")  # Assigning a name to a material
          doc.InsertMaterial(material)  # type: ignore # Adding material to a document
      
          # Step 2: Disable the Color Channel
          material[c4d.MATERIAL_USE_COLOR] = False
      
          # Step 3: Disable the Reflectivity channel
          material[c4d.MATERIAL_USE_REFLECTION] = False
      
           #Step 4: Enable the Brightness channel
          material[c4d.MATERIAL_USE_LUMINANCE] = True
          
          # Step 5: Select a texture file for the Brightness channel
          luminance_texture_path = storage.LoadDialog(type=c4d.FILESELECTTYPE_IMAGES, title="Select a texture for the Brightness channel")
          if luminance_texture_path:  # Checking if the user has selected a file
              luminance_shader = c4d.BaseShader(c4d.Xbitmap)  # Create a shader for the image
              luminance_shader[c4d.BITMAPSHADER_FILENAME] = luminance_texture_path  # Assigning a path to a file
              material[c4d.MATERIAL_LUMINANCE_SHADER] = luminance_shader  # Assigning a shader to a material
              
          # Step 6: Enable the DISPLACEMENTt channel
          material[c4d.MATERIAL_USE_DISPLACEMENT] = True
      
          # Step 7: Select a texture file for the Displacement channel
          displacement_texture_path = storage.LoadDialog(type=c4d.FILESELECTTYPE_IMAGES, title="Select a texture for the Displacement channel")
          if displacement_texture_path:  # Checking if the user has selected a file
              displacement_shader = c4d.BaseShader(c4d.Xbitmap)  # Create a shader for the image
              displacement_shader[c4d.BITMAPSHADER_FILENAME] = displacement_texture_path  # Assigning a path to a file
              material[c4d.MATERIAL_DISPLACEMENT_SHADER] = displacement_shader # Assigning a path to a file
      
          # Updating the material to apply the changes
          material.Update(True, True)
      
          # Step 8: Assign material to selected objects
          selected_objects = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_0)  # type: ignore # Get a list of selected objects
          if selected_objects:  # Checking if objects are selected
              for obj in selected_objects:
                  texture_tag = c4d.TextureTag()  # Create a new texture tag
                  texture_tag.SetMaterial(material)  # Assigning the material to the tag
                  obj.InsertTag(texture_tag)  # Add a tag to the object
      
          # Updating the scene
          c4d.EventAdd()
      
      # Script running
      if __name__ == '__main__':
          main()
      

      Why are the selected images for the material shaders not assigned to the specified shader?


      edit (@ferdinand):
      @lednevandrey said:

      Script for S4D 2023.2

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

        Hello @lednevandrey,

        Welcome to the Maxon developers forum and its community, it is great to have you with us!

        Getting Started

        Before creating your next postings, we would recommend making yourself accustomed with our forum and support procedures. You did not do anything wrong, we point all new users to these rules.

        • Forum Overview: Provides a broad overview of the fundamental structure and rules of this forum, such as the purpose of the different sub-forums or the fact that we will ban users who engage in hate speech or harassment.
        • Support Procedures: Provides a more in detail overview of how we provide technical support for APIs here. This topic will tell you how to ask good questions and limits of our technical support.
        • Forum Features: Provides an overview of the technical features of this forum, such as Markdown markup or file uploads.

        It is strongly recommended to read the first two topics carefully, especially the section Support Procedures: Asking Questions.

        About your First Question

        The issue with your script is that you never insert your bitmap shaders. A shader must be inserted into a scene graph just like any other node before it can be used. Referencing a shader in a shader parameter does not replace inserting a shader. While for shaders this might be a bit surprising for beginners, one can look at it from an generator object angle to gain clarity. You would not expect to be able to link a that cube object into the document first. From this angle it is a bit more obvious that shaders are not any different and must be inserted before being linked anywhere.

        In most cases shaders are owned by the material which use them and inserted with c4d.BaseList2D.InsertShader(). But there is some complexity to how shaders are structured when shaders own shaders. See Base Shader Manual: Access and Structure (C++) for details. The manual is for C++ but also applies to Python.

        So, for the displacement part it should be for example something like this.

        import c4d
        import mxutils
        
        # ...
        path: str = storage.LoadDialog(type=c4d.FILESELECTTYPE_IMAGES, title="Select a texture for the Displacement channel")
        if path:
            # The mxutils.CheckType call is here so that we can be sure that allocation did not fail. Then
            # we insert the shader into the document by attaching it to the material which itself
            # is being inserted into the document.
            shader: c4d.BaseShader = mxutils.CheckType(c4d.BaseShader(c4d.Xbitmap)
            material.InsertShader(shader)
            
            # Now we can link the file in the shader, and shader in the material. A shader can only
            # be linked/used once by a material in the classic APU of Cinema 4D. So, if we wanted
            # to use #path twice, we would have insert a second shader for the second usage.
            shader[c4d.BITMAPSHADER_FILENAME] = path
            material[c4d.MATERIAL_DISPLACEMENT_SHADER] = shader
        

        Cheers,
        Ferdinand

        MAXON SDK Specialist
        developers.maxon.net

        1 Reply Last reply Reply Quote 0
        • L
          lednevandrey
          last edited by

          Hi Ferdinand!

          Thank you for your attention to my problem.
          I took into account your comments and reworked the script. But when I run it, the console shows an error:

          ModuleNotFoundError:No module named 'mxutils'

          How to install a module 'mxutils' in the C4D environment?

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

            Hey @lednevandrey,

            Oh, my bad, I did not see that you were using 2023. mxutils is a feature of Cinema 4D 2024 and onwards. You cannot install it on 2023. Just replace lines like:

            shader: c4d.BaseShader = mxutils.CheckType(c4d.BaseShader(c4d.Xbitmap)
            material.InsertShader(shader)
            

            with

            shader: c4d.BaseShader = c4d.BaseShader(c4d.Xbitmap)
            if shader is None:
                raise MemoryError("Failed to allocate shader.")
            material.InsertShader(shader)
            

            you technically also can write just

            shader: c4d.BaseShader = c4d.BaseShader(c4d.Xbitmap)
            material.InsertShader(shader)
            

            when you are fine with a bit cryptic error when shader allocation fails; BaseList2D.InsertShader will then complain that it cannot deal with being passed a NoneType for its shader argument. Type checking only exists in Python for code to fail more gracefully. mxutils.CheckType just makes this just a little bit less cumbersome to do.

            Cheers,
            Ferdinand

            MAXON SDK Specialist
            developers.maxon.net

            1 Reply Last reply Reply Quote 1
            • L
              lednevandrey
              last edited by

              Hi Ferdinand!
              Thank you. It worked.

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

                Great to hear that you found your solution! Do not hesitate to ask more questions when you run into problems while exploring our Python API. But just as a heads up, we prefer users opening new topics for new questions. For details see the Support Procedures linked above.

                Cheers,
                Ferdinand

                MAXON SDK Specialist
                developers.maxon.net

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