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
    • Register
    • Register
    • Login

    Creating a 'Reload Image' button

    Cinema 4D SDK
    3
    6
    1.1k
    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.
    • G
      glasses
      last edited by

      I have a python Generator with a Texture path in its UserData.

      I place a photoshop file in my texture path and I want to reload the shader image every time I make a change to the photoshop file. How can I recreate the 'Reload Image...' button (see pic) to refresh the shader? Thanks mates for any thoughts.
      Screen Shot 2019-11-19 at 12.21.34 AM.png

      1 Reply Last reply Reply Quote 0
      • S
        s_bach
        last edited by

        Hello,

        as always, please use the Q&A system to mark your post as a question.

        just to be sure: do you have a "Texture Path" parameter or a "shader" parameter in your user data?

        Cinema does some image caching, so it seems that only the BitmapShader really knows how to re-load that image.

        You can simply add a user data button to the Python Generator. In the generator, you can implement a message() function to check when the button was pressed (you find an related example here: Creating a material and applying to BaseObject within Python Generator😞

        def message(id, data):
            if id == c4d.MSG_DESCRIPTION_COMMAND:
                buttonId = data['id']
        
                # check button ID 1
                if buttonId[1].id == 1:
                    print("button pressed")
        

        Now you can use CallButton() to press the "Reload Image..." button of the shader

                    # assume user data parameter 4 is a shaderlink with a BitmapShader
                    texID = [c4d.ID_USERDATA, 4]
        
                    bitmapShader = op[texID]
                    c4d.CallButton(bitmapShader, c4d.BITMAPSHADER_RELOADIMAGE)
        
        
                    c4d.EventAdd()
        

        best wishes,
        Sebastian

        MAXON SDK Specialist

        Development Blog, MAXON Registered Developer

        1 Reply Last reply Reply Quote 1
        • G
          glasses
          last edited by

          Thank you @s_bach The button is working great. However I'm getting the following error for this line:

          c4d.CallButton(bitmapShader, c4d.BITMAPSHADER_RELOADIMAGE)
          

          RuntimeError: illegal operation, invalid cross-thread call

          Yikes, sounds serious. Maybe I need to stop the threads?

          To be more clear I am using a Texture path in my user data.

          Alternatively, there must there must be a way to empty the cache on the Texture Path and then load the image again.

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

            Hi,

            You have to ensure that you are in the main thread when invoking c4d.CallButton(). You can use c4d.threading.GeIsMainThread() for that. It seems that c4d.MSG_DESCRIPTION_COMMAND is not being sent from the main thread (to my suprise). Are you using the code provided by @s_bach ?

            Cheers
            zipit

            MAXON SDK Specialist
            developers.maxon.net

            1 Reply Last reply Reply Quote 0
            • G
              glasses
              last edited by

              Ok, I was trying to call this from def main(): calling from def message(id, data):
              is working! Thank you for the help!

              1 Reply Last reply Reply Quote 0
              • S
                s_bach
                last edited by s_bach

                Hello,

                if in doubt, one can always call c4d.StopAllThreads() before editing the active document from some user interaction in the main thread. This call will terminate other threads that may also currently use the active document (e.g. viewport rendering).

                best wishes,
                Sebastian

                MAXON SDK Specialist

                Development Blog, MAXON Registered Developer

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