- Substance 3D home
- Home
- Getting Started
- Getting Started overview
- Activation and licenses
- System requirements
- Project creation
- Export
- Export overview
- Export window
- Export presets
- Export overview
- Glossary
- Performance
- Getting Started overview
- Interface
- Assets
- Substance 3D Assets
- Color picker
- Display settings
- History
- Layer stack
- Main menu
- Project configuration
- Properties
- Settings
- Shader settings
- Texture Set
- Toolbars
- Viewport
- Miscellaneous
- Assets
- Painting
- Painting overview
- Tool list
- Straight line
- Lazy mouse
- Symmetry
- Fill projections
- Presets
- Presets overview
- Creating and saving presets
- Creating particles presets
- Photoshop brush presets (ABR)
- Dynamic strokes
- Advanced channel painting
- Vector graphic (.svg & .ai)
- Text resource
- Effects
- Baking
- Content
- Creating custom effects
- Importing assets
- Creating custom effects
- Features
- Automatic UV Unwrapping
- Physical size
- Smart Materials and Masks
- Subsurface Scattering
- Dynamic Material Layering
- UV Reprojection
- UV Tiles
- Color Management
- Post Processing
- Iray Renderer
- Plugins
- Sparse Virtual Textures
- Custom Shaders
- SpaceMouse® by 3Dconnexion
- Universal Scene Description (USD)
- Send to
- Technical Support
- Performance Guidelines
- Configuring Pens and Tablets
- Exporting the log file
- Exporting a DXDiag
- Technical issues
- GPU Issues
- Crash when working with overclocked GPU
- Forcing the external GPU on Mac OS
- GPU drivers compatibility
- GPU drivers crash with long computations (TDR crash)
- GPU has outdated drivers
- GPU is not recognized
- GPU is not recognized and is mentionned as GDI Generic
- Issues with Nvidia GPUs on recent Mac OS versions
- Multi/Bi-GPU
- Running on integrated GPU
- Painter doesn't start on the right GPU
- Startup Issues
- Rendering Issues
- Stability Issues
- Miscellaneous Issues
- GPU Issues
- Workflow Issues
- Export Issues
- Tools Issues
- Project Issues
- Library Issues
- Viewport Issues
- Plugins Issues
- License Issues
- Pipeline and integration
- Installation and preferences
- Configuration
- Resource management
- Scripting and development
- Scripts and plugins
- Shader API Reference
- Shader API overview
- Changelog - Shader API
- Libraries - Shader API
- Lib Alpha - Shader API
- Lib Bayer - Shader API
- Lib Defines - Shader API
- Lib Emissive - Shader API
- Lib Env - Shader API
- Lib Normal - Shader API
- Lib PBR - Shader API
- Lib PBR Aniso - Shader API
- Lib Pom - Shader API
- Lib Random - Shader API
- Lib Sampler - Shader API
- Lib Sparse - Shader API
- Lib SSS - Shader API
- Lib Utils - Shader API
- Lib Vectors - Shader API
- Parameters - Shader API
- Shaders - Shader API
- Release notes
- Release notes overview
- All Changes
- Version 10.1
- Version 10.0
- Version 9.1
- Old versions
- Version 9.0
- Version 8.3
- Version 8.2
- Version 8.1
- Version 7.4
- Version 7.3
- Version 7.2
- Version 2021.1 (7.1.0)
- Version 2020.2 (6.2.0)
- Version 2020.1 (6.1.0)
- Version 2019.3
- Version 2019.2
- Version 2019.1
- Version 2018.3
- Version 2018.2
- Version 2018.1
- Version 2017.4
- Version 2017.3
- Version 2017.2
- Version 2017.1
- Version 2.6
- Version 2.5
- Version 2.4
- Version 2.3
- Version 2.2
Remote control with scripting
This page describes how to control the application remotely to execute Javascript or Python commands.
This requires a specific command line argument, then a simple Python script can execute any commands available from the existing Javascript and Python APIs.
Starting the application
In order to control remotely the application, Substance 3D Painter needs to be launched with the following command line:
"Adobe Substance 3D painter.exe" --enable-remote-scripting
Make sure the application is up and running with this command before running any scripts. Scripts may fail if the application is still starting up/not ready yet.
Remote control script
The following Python script can serve as a library to communicate with the application.
Save the following script in a file named lib_remote.py to make the examples below work properly.
import sys import json import base64 import subprocess if sys.version_info >= (3, 0): import http.client as http else: import httplib as http class RemotePainter() : def __init__(self, port=60041, host='localhost'): self._host = host self._port = port # Json server connection self._PAINTER_ROUTE = '/run.json' self._HEADERS = {'Content-type': 'application/json', 'Accept': 'application/json'} # Execute a HTTP POST request to the Substance Painter server and send/receive JSON data def _jsonPostRequest( self, route, body, type ) : connection = http.HTTPConnection(self._host, self._port, timeout=3600) connection.request('POST', route, body, self._HEADERS) response = connection.getresponse() data = response.read() connection.close() if type == "js" : data = json.loads( data.decode('utf-8') ) if 'error' in data: OutJson = json.loads( body.decode() ) print( base64.b64decode( OutJson["js"] ) ) raise ExecuteScriptError(data['error']) else : # Python can return nothing, so decoding can fail try: data = data.decode('utf-8').rstrip() except: pass return data def checkConnection(self): connection = http.HTTPConnection(self._host, self._port) connection.connect() # Execute a command def execScript( self, script, type ) : Command = base64.b64encode( script.encode('utf-8') ) if type == "js" : Command = '{{"js":"{0}"}}'.format( Command.decode('utf-8') ) else : Command = '{{"python":"{0}"}}'.format( Command.decode('utf-8') ) Command = Command.encode( "utf-8" ) return self._jsonPostRequest( self._PAINTER_ROUTE, Command, type ) class PainterError(Exception): def __init__(self, message): super(PainterError, self).__init__(message) class ExecuteScriptError(PainterError): def __init__(self, data): super(PainterError, self).__init__('An error occured when executing script: {0}'.format(data))
Examples
Below are two simple examples that shows how to run commands in both API supported by the application:
Running Javascript commands
Most Javascript function in the API return String or Json data which make them easy to manipulate within the Python script. There shouldn't be any major problems to send and receive data.
Create a python script file named example_js.py and add the following code:
import lib_remote Remote = lib_remote.RemotePainter() Remote.checkConnection() # Print the API version Version = Remote.execScript( "alg.version.painter", "js" ) print( Version ) # Get a list of all the files in the default shelf/library: Files = Remote.execScript( 'alg.resources.findResources("starter_assets", "*")', "js" ) for File in Files : print( File )
If the application is running with the command line, then running this script will make it execute commands and retrieve their results.
Running Python commands
Most Python functions may return objects which cannot be passed into the remote script, this means that in order receive data they need to be explicitly converted to strings or Json dictionaries.
To make things easier, it is possible to create custom python script that is loaded during the startup of the application and call functions that handle this kind of conversion without having to rely on inline conversions.
Create a python script file named example_py.py and add the following code:
import lib_remote Remote = lib_remote.RemotePainter() Remote.checkConnection() # import the substance_painter module to make # its API available to us Remote.execScript( "import substance_painter", "python" ) # Print the API version Version = Remote.execScript( "substance_painter.__version__", "python" ) print( Version ) # Get a list of all the files in the default shelf/library # Because the search function return objects, we have to convert # the information into a string within the same command (inline) Command = 'substance_painter.resource.search( "p:starter_assets/" )' Command = '"|||".join( [ x.identifier().url() for x in {0}] )'.format( Command ) Files = Remote.execScript( Command, "python" ) Files = Files.split( "|||" ) for File in Files : print( File )
If the application is running with the command line, then running this script will make it execute commands and retrieve their results.