Creating a 'Reload Image' button
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.
s_bach last edited by
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.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()
Thank you @s_bach The button is working great. However I'm getting the following error for this line:
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.
ferdinand last edited by ferdinand
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_COMMANDis not being sent from the main thread (to my suprise). Are you using the code provided by @s_bach ?
Ok, I was trying to call this from def main(): calling from def message(id, data):
is working! Thank you for the help!
s_bach last edited by s_bach
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).