Copy link to clipboard
Copied
Hello,
I was hoping someone could tell me how I could run/trigger python scripts without using the start and close definitions shown in the examples.
Currently, I am launching painter via an external python script using subprocess.call([substance_painter_path])
What I would like to do now is run/trigger my other python scripts for painter directly from that external python script (Open Project, Rebake Textures, Export etc.)
But so far I have only been able to run those kind of scripts via the Python drop down, and using start/close plugin definitions.
If someone could explain this to me I would really appreciate it!
Thank you!
Copy link to clipboard
Copied
Hi there.
You should be able to run any script on start up as long as it goes through the start_plugin function. Also you can have multiple python files with start_plugin defined and substance will run them all on startup as long as they are in the proper search path.
For example if I have a python script that opens a project, bakes textures, and exports called rebake_and_export.py, then in my main py file I could do:
from rebake_and_export import run
def start_plugin():
run()
Then this will be run whenever substance starts up.
If you only want to run this SOMETIMES and not every time substance starts up, then you can alter the environment variable SUBSTANCE_PAINTER_PLUGINS_PATH right before you call substance painter:
import subprocess, os
my_env = os.environ.copy()
my_env["SUBSTANCE_PAINTER_PLUGINS_PATH"] = f"/path/to/custom/start/script.py:{my_env['SUBSTANCE_PAINTER_PLUGINS_PATH']}"
subprocess.Popen(substance_painter_path, env=my_env)
Keep in mind I have used Popen rather than call.
Does this make sense?
Copy link to clipboard
Copied
Sorry the SUBSTANCE_PAINTER_PLUGINS_PATH env variable wouldn't point to a python file but rather a directory that contains a "plugins" sub directory, and in the sub directory would be the custom script to run.
Copy link to clipboard
Copied
Thank you again for all the great information, I really appreciate you taking the time to share your knowledge with me!
I certainly wouldnt have thought of this, and I think that will be great for opening a specific project when opening Painter via my external python script.
But what about just general running of scripts though? - like if painter was allready open, but I wanted to trigger a python script from outside of the standard python dropdown section (and just to execute when called, rather than it toggling on and off as a plugin?)
Thank you again for your time!
Copy link to clipboard
Copied
Apologies, I seem to have miss read some of your previous post - I will read through it again, as I missed a paragraph I think
!
Copy link to clipboard
Copied
There is a Python console where you can run one time python code. Windows --> Python Comsole (or something like that)
I have tried using the exec() method to run a file but it gives me strange errors so I would have to paste lines of code manually.
Copy link to clipboard
Copied
Ah thats a shame, I was hoping there would just be an easy answer I was missing.
I had seen the Python Console, and as you say, it works okay for single lines. But it would be far better for automation to just be able to execute full python scripts.
Sadly im having some trouble with the alternate statup plugins folder method you mentioned, when I try to read or write to...
my_env["SUBSTANCE_PAINTER_PLUGINS_PATH"]
I just get a KeyError, im not sure why that wouldnt be defined for me though.
Printing just 'my_env' I can see that it seems to doing what it should outside of that.
Copy link to clipboard
Copied
my_env["SUBSTANCE_PAINTER_PLUGINS_PATH"] = f"C:\Users\GraemePalmer\Documents\Adobe\Adobe Substance 3D Painter\python\Alt_Path:{my_env['SUBSTANCE_PAINTER_PLUGINS_PATH']}"
subprocess.Popen(substance_painter_path, env=my_env)
Sorry, but is this the correct format? - perhaps I just misunderstood.
So Alt_Path contains three folders for the plugins, modules and startup.
Copy link to clipboard
Copied
That is correct.
I believe this part is causing the KeyError. It means the variable isn't defined already so this part isn't needed and you can remove it. This is basically to append any previous values written to the environment variable, as to not overwrite it.
:{my_env['SUBSTANCE_PAINTER_PLUGINS_PATH']}
You can also write some script to check if it exists first before adding it.
Copy link to clipboard
Copied
Ah okay, thats great to know! - I need to head to bed, but I will give that a go in the morning.
Thanks for all the help, you're the best!
Copy link to clipboard
Copied
Yes, this was the issue as you suggested! - I also had to change my backslashes to double backslashes.
I added a check too, which all seems to be working great now. Thanks for the great advice! - Im still hoping to find some way of triggering alternate scripts directly while painter is running, but this certainly gives me enough to start putting all the parts together.
try:
value = my_env["SUBSTANCE_PAINTER_PLUGINS_PATH"]
my_env["SUBSTANCE_PAINTER_PLUGINS_PATH"] = f"C:\\Users\\GraemePalmer\\Documents\\Adobe\\Adobe Substance 3D Painter\python\\Alt_Path:{my_env['SUBSTANCE_PAINTER_PLUGINS_PATH']}"
except KeyError:
my_env["SUBSTANCE_PAINTER_PLUGINS_PATH"] = f"C:\\Users\\GraemePalmer\\Documents\\Adobe\\Adobe Substance 3D Painter\\python\\Alt_Path"
Copy link to clipboard
Copied
Btw, I noticed you said you were using this to open a project too?
Have you had issues with substance_painter.project.open("c:/Documents/project.spp") as shown in the documentation?
When I include a path like that into my script, I get stuck with a "loading scene" progess spinner that never ends.
Copy link to clipboard
Copied
I also tried this with backslashes and double backslashes since I had that issue earlier - but I seem to get the same result with each sadly.
Copy link to clipboard
Copied
Im having some success working around this with -
Copy link to clipboard
Copied
I haven't tried it yet but thanks for the update, good to know! Please keep posting, I'd love to have the scripting forum more active.
Copy link to clipboard
Copied
Will do! - You have been a life saver.
I always find stumbling on threads like these are where I get the most information too, so hopefully it will help someone else later.
Im having issues with duplicate calls of ShelfCrawlingEnded btw, but il update back when I find a workaround to that or a better solution.
I was hoping to just do it with a counter perhaps (if there are always two calls instead of one for example.) But I havnt been able to get a simple incrementor to work yet Painter Python - 'Count = Count + 1' etc.
The other thing I wondered is if maybe I could dissable the even listener, so Id only get the first call.
No real plan yet, but fingers crossed there is a workaround!
Copy link to clipboard
Copied
I couldnt get dissconnect events to work, and it doesnt seem like its valid to store global vars in these python scripts, so instead I have worked around this for now by just saving and loading variables to text file on the pc, and using that as global storage.
The first time a listen event is triggered, I add a line, then on any future calls of that event it will be ignored because that line existed.
And the file gets wiped on startup, so I know it will always be blank. Seems to be working okay on this for now!
Copy link to clipboard
Copied
Here is some info that might be helpful to run your external python scripts:
You can submit multiple commands/lines to python console, just separate them with a semicolon.
For example I use pycharm, and when testing code I don't want to constantly copy files to painters plugin folder. Here is what I do:
- In painters python console set the path to pycharm folder such as
path = r"D:\_WORK\PycharmProject1\code\"
- Then I have this line ready that I simply copy paste:
import sys; sys.path.append(path); import substance_functions as funcs;
- This adds my pycharm project directory to painters system path (only valid for current session) and allows me to import and run any python script from that folder
Then I can call functions like this:
funcs.some_function()
If I you make some changes to substance_functions.py, you need to reload it in painter by using
imp.reload(funcs)
Copy link to clipboard
Copied
Ah this is a great method! - Thanks for sharing this with me!
Find more inspiration, events, and resources on the new Adobe Community
Explore Now