User Guide Cancel

Basic manipulation | Substance 3D Automation ToolKit

  1. Substance 3D home
  2. Home
  3. Command Line Tools
    1. Command Line overview
    2. sbsbaker
      1. sbsbaker overview
      2. sbsbaker command line options
      3. sbsbaker Example Command Lines
    3. sbscooker
      1. sbscooker overview
      2. sbscooker command line options
      3. sbscooker pattern variables
    4. sbsmtools
      1. sbsmtools overview
      2. sbsmtools command line options
    5. sbsmutator
      1. sbsmutator overview
      2. sbsmutator command line options
      3. sbsmutator Example Command Lines
    6. sbsrender
      1. sbsrender overview
      2. sbsrender base parameters and pattern variables
      3. sbsrender command line options
      4. sbsrender example command lines
    7. sbsupdater
      1. sbsupdater overview
      2. sbsupdater command line options
  4. Pysbs - Python API
    1. Pysbs - Python API overview
    2. Getting started
    3. General topics
      1. Basic manipulation
      2. Substance creation
      3. Substances modification
      4. Dependencies management
      5. PySbs batchtools module
      6. metadata manipulation
      7. SAT demos
      8. Edit sbsar with SBSARManager
      9. Spot Colors
      10. Thumbnail creation with SAT
    4. Examples
      1. demohelloworld
      2. demos
      3. demos_batchtools
      4. script_update_with_sbsupdater
    5. API Content
      1. API Content overview
      2. Substance definitions
        1. Common interfaces
          1. basegraph
          2. package
          3. sbsarobject
          4. sbsobject
        2. compnode
          1. compnode overview
          2. common
          3. compimplementation
          4. paramgraph
        3. context projectmgr
        4. graph
          1. graph overview
          2. function
          3. inputparameters
          4. output
        5. mdl
          1. mdlannotation
          2. mdlcommon
          3. mdldictionaries
          4. mdlenum
          5. mdlgraph
          6. mdllibclasses
          7. mdlmanager
          8. mdlnode
          9. mdlnodeimpl
          10. mdloperand
          11. mdlsbsbridge
        6. modelgraphindex
          1. modelannotationnames
          2. modelgraph
          3. modelgraphgenerator
          4. modelgraphimplementation
          5. modelnodenames
          6. modeloperand
          7. modulegraphindex
          8. moduleannotation
          9. moduleconnection
          10. modulegraph
          11. modulegraphgenerator
          12. modulegraphimplementation
          13. modulegraphlibrary
          14. modulegraphregister
          15. modulenode
          16. modulenodeimplementation
          17. modulenodeinstance
          18. moduleoperand
          19. moduleoutputbridging
          20. moduleparaminput
        7. params
          1. params overview
          2. dynamicvalue
          3. paramnode
        8. projectmgrdoc
        9. sbsarchive
          1. sbsarchive overview
          2. sbsarenum
          3. sbsargraph
          4. sbsargui
          5. sbsarguiwidgets
          6. sbsarmanager
        10. sbscommon
          1. connections
          2. gui
          3. nodes
          4. values
        11. sbspreset
        12. sbsproject
        13. substance
          1. substance overview
          2. content
          3. resource
      3. Libraries
        1. sbsenum
        2. sbslibrary
          1. sbslibrary overview
          2. sbsdictionaries
          3. sbsfilters
          4. sbsfunctions
          5. sbsfxmapnodes
          6. sbslibclasses
          7. sbswidgets
        3. sbsbakerslibrary
          1. sbsbakerslibrary overview
          2. sbsbakersdef
          3. sbsbakersdefaultprops
          4. sbsbakersdictionaries
          5. sbsbakersenum
          6. sbsbakingconverter
          7. sbsbakingconverterparam
          8. sbsbakingparameters
          9. sbsdialogstate
          10. sbsscenedata
        4. Helpers
          1. sbscleaner
          2. sbsexporter
          3. sbsgenerator
          4. sbsparser
          5. sbswriter
          6. qtclasses
            1. qtclasses overview
            2. qtvariantreader
            3. qtvariantwriter
          7. psdparser
          8. sbsimpactmanager
          9. batchtools
          10. autograph
            1. ag_functions
            2. ag_layout
            3. ag_types
          11. info_mesh_parser
          12. sbsbaker_info_handlers
          13. sbsrender_render_handlers
          14. output_handlers
          15. spotcolorinfo_handler
          16. thumbnail
          17. batchtools overview
        5. Execution context
          1. context
          2. functions
        6. API Change log
  5. Samples
    1. Samples overview
    2. Texturing Template Demo
    3. Batch Tools Demo
    4. Variations
    5. Texture Mat
    6. Pixel Processor Ray tracer
  6. Setup and Getting Started
    1. Setup and Getting Started overview
    2. Compatibility
    3. Frequently asked Questions
    4. Known issues
    5. SAT Cookbook
    6. Use Pysbs in different python interpreter (maya, sd, blender...)
  7. Integrations
    1. Substance Maya toolset
      1. Substance Maya Toolset overview
      2. Installing
      3. Launching
      4. Baking
        1. Baking overview
        2. Export parameters
        3. Baker parameters
        4. Mesh setup
        5. Using a template
      5. Changelog
  8. Changelog overview

Basic manipulation

Opening and writing a substance

The API offers the ability to parse a .sbs or a .sbsar file to retrieve its content as a hierarchical object structure.

A .sbs file is parsed using a substance.SBSDocument object, whereas a .sbsar file is parsed using a sbsarchive.SBSArchive object.

Only a .sbs file can be created or modified through the API, so only the substance.SBSDocument has a writeDoc() function:

from pysbs import substance, sbsarchive 
 
# Creation of a SBSArchive object from an existing .sbsar file, and parsing: 
sbsarDoc = sbsarchive.SBSArchive(aContext, aSBSARFileAbsPath) 
sbsarDoc.parseDoc()        # Parse the .sbsar file and put into sbsarDoc the object structure contained in the substance 
 
# Creation of a SBSDocument object from an existing .sbs file, parsing and writing 
sbsDoc = substance.SBSDocument(aContext, aSBSFileAbsPath) 
sbsDoc.parseDoc()          # Parse the .sbs file and put into sbsDoc the object structure contained in the substance 
sbsDoc.writeDoc()          # Write back the object structure into the same .sbs file on disk

Requesting information on a Substance

The API can also be used to simply request information on a Substance (.sbs or .sbsar), to get information on the graphs it contains and their inputs and outputs.

Some common interfaces exists for SBSObject and SBSARObject, they are defined in the module common_interfaces.package:

The following functions are available on both sbs and sbsar packages:

# Getting all the graphs of a package 
aGraphList = aDoc.getSBSGraphList() 
 
# Getting the outputs of a graph 
aOutputList = aGraph.getGraphOutputs()                                        # Get all the output of a graph 
aOutput = aGraph.getGraphOutput(aOutputIdentifier='MyOutput')                 # Get a particular output 
aOutput = aGraph.getGraphOutputWithUsage(aUsage=sbsenum.UsageEnum.ROUGHNESS)  # Get a particular output given its usage 
aOutput = aGraph.getGraphOutputWithUsage(aUsage='MyCustomUsage')              # Same but with a custom usage 
 
# Getting the inputs of a graph 
aInputList = aGraph.getAllInputs()                         # Get all the inputs (images and parameters) 
aInputList = aGraph.getAllInputsInGroup(aGroup='MyGroup')  # Get all the inputs of a particular GUI group named 'MyGroup' 
aParamList = aGraph.getInputParameters()                   # Get only the input parameters 
aImageList = aGraph.getInputImages()                       # Get only the input images 
 
# Or get a particular input: 
aInput = aGraph.getInput(aInputIdentifier='MyInput') 
aParam = aGraph.getInputParameter(aInputParamIdentifier='MyInputParam') 
aImage = aGraph.getInputImage(aInputImageIdentifier='MyInputImage') 
aImage = aGraph.getInputImageWithUsage(aUsage=sbsenum.UsageEnum.ROUGHNESS) 
 
# Get the parameter definition: 
aParam.getWidget() 
aParam.getDefaultValues() 
aParam.getMinValue() 
aParam.getMaxValue() 
aParam.getClamp() 
aParam.getStep() 
aParam.getLabels() 
aParam.getDropDownList() 
 
# Getting the attributes of a graph, an input or an output 
aGraph.getAttribute(aAttributeIdentifier=sbsenum.AttributeEnum.Author) 
aInput.getAttribute(aAttributeIdentifier=sbsenum.AttributeEnum.Description) 
aOutput.getAttribute(aAttributeIdentifier=sbsenum.AttributeEnum.Label) 
 
# Getting the parameter presets defined on a Graph 
aPresetList = aGraph.getAllPresets()                                                      # Get all the presets defined on the graph 
aPreset = aGraph.getPreset(aPresetLabel='MyPresetLabel')                                  # Get one particular preset from its label 
aPresetInputList = aPreset.getPresetInputs()                                              # Get all the preset inputs of a preset 
aPresetInput = aPreset.getPresetInput(aInputParam=aParam)                                 # Get the preset input associated to a graph parameter 
aPresetInput = aPreset.getPresetInputFromIdentifier(aInputParamIdentifier='MyInputParam') # Get the preset input associated to a graph parameter identifier

On a SBSDocument only, more information can be retrieved, such as its dependencies and resources, which could be helpful to build the dependency graph of a Substance, for version control purpose for instance:

# Get the list of dependencies directly included in the package, as SBSDependency objects: 
aDepdendencyList = sbsDoc.getSBSDependencyList() 
 
# Get the list of resources directly included in the package, as SBSResource objects: 
aResourceList = sbsDoc.getSBSResourceList() 
 
# Get the list of dependency paths recursively referenced by the package, as strings: 
aDependencyPathList = sbsDoc.getDependencyPathList(aRecurseOnPackages = True) 
 
# Get the list of resource paths recursively referenced by the package, as strings: 
aResourcePathList = sbsDoc.getResourcePathList(aRecurseOnPackages = True)

On a SBSGraph, these lines allow to retrieve different lists of compositing nodes (SBSCompNode):

# List all Input nodes 
inputNodes = aGraph.getAllInputNodes() 
 
# List all Output nodes 
outputNodes = aGraph.getAllOutputNodes() 
 
# List all Bitmap Filter nodes 
bitmapNodes = aGraph.getAllFiltersOfKind(sbsenum.FilterEnum.BITMAP) 
 
# List all CompInstance nodes 
instanceNodes = aGraph.getAllFiltersOfKind(sbsenum.FilterEnum.COMPINSTANCE) 
 
# List all CompInstance nodes that reference the Substance 'curvature.sbs' in the default package folder 
instanceOfCurvatureNodes = aGraph.getAllNodeInstancesOf(sbsDoc, 'sbs://curvature.sbs') 
 
# List all nodes connected to/from a node (on a particular input/output or not) 
connectedNodes = aGraph.getNodesConnectedTo(aRightNode=myNode) 
connectedNodes = aGraph.getNodesConnectedTo(aRightNode=myNode, aRightNodeInput=sbsenum.InputEnum.MASK) 
connectedNodes = aGraph.getNodesConnectedFrom(aLeftNode=myNode) 
connectedNodes = aGraph.getNodesConnectedFrom(aLeftNode=myNode, aLeftNodeOutput='myOutput')

Working with MDL graph (MDLGraph) is done with almost the same functions:

# Getting all the MDL graphs of a package 
aMDLGraphList = aDoc.getMDLGraphList() 
 
# Getting the output/root node of a MDL graph 
aOutput = aMdlGraph.getGraphOutput() 
 
# Getting the input nodes of a graph (e.g. the Constant nodes that has been exposed) 
aInputList = aMdlGraph.getAllInputs()                         # Get all the inputs (images and parameters) 
aInputList = aMdlGraph.getAllInputsInGroup(aGroup='MyGroup')  # Get all the inputs of a particular GUI group named 'MyGroup' 
aParamList = aMdlGraph.getInputParameters()                   # Get only the input parameters 
aImageList = aMdlGraph.getInputImages()                       # Get only the input of kind textures 
 
# Or get a particular input node: 
aInput = aMdlGraph.getInput(aInputIdentifier='MyInput') 
aParam = aMdlGraph.getInputParameter(aInputParamIdentifier='MyInputParam') 
aImage = aMdlGraph.getInputImage(aInputImageIdentifier='MyInputImage') 
aImage = aMdlGraph.getInputImageWithUsage(aUsage=sbsenum.UsageEnum.ROUGHNESS)   # A custom string can be used 
 
# List all the nodes by category 
# - Constants 
nodeList = mdlGraph.getAllMDLConstants() 
nodeList = mdlGraph.getAllMDLConstantsOfType('mdl::float') 
nodeList = mdlGraph.getAllMDLConstantsWithName('roughness') 
# - Selectors 
nodeList = mdlGraph.getAllMDLSelectors() 
nodeList = mdlGraph.getAllMDLSelectorsWithName('tint') 
nodeList = mdlGraph.getAllMDLSelectorsOfType('mdl::color') 
# - MDL instances 
nodeList = mdlGraph.getAllMDLInstances() 
nodeList = mdlGraph.getAllMDLInstancesOf('mdl::operator*') 
nodeList = mdlGraph.getAllMDLInstancesOf('mdl::operator*(float,float)') 
# - MDL Graph instances 
nodeList = mdlGraph.getAllMDLGraphInstances() 
nodeList = mdlGraph.getAllMDLGraphInstancesOf(aSBSDocument=aDoc, aPath=aDoc.buildAbsPathFromRelToMePath('myMDL.sbs/MDL_Material')) 
# - Substance Graph instances 
nodeList = mdlGraph.getAllSBSInstances() 
nodeList = mdlGraph.getAllSBSInstancesOf(aSBSDocument=aDoc, aPath='pkg:///myGraph') 
nodeList = mdlGraph.getAllSBSInstancesOf(aSBSDocument=aDoc, aPath='sbs://perlin_noise_1.sbs')

Many objects in a .sbs file has a unique identifier (uid), accessible through the member ‘mUID’.

Some objects can be requested from their parent given their uid, that can be found either by reading the .sbs file, or, in the case of the nodes,

through Substance Designer user interface, by right clicking on a particular node and selecting: ‘Copy info to clipboard’

# Get a particular node from its uid 
myNode = aGraph.getNode(aNode='1289992758')

To know the signature, or definition, of a compositing node (SBSCompNode) of any kind (e.g. Filter, Input, Output, Instance), the function SBSCompNode.getDefinition() is helpful as it returns a CompNodeDef object, which is the definition of a compositing node and contains:

The same function exists for the other types of node:

  • SBSParamNode.getDefinition() the Function nodes (SBSParamNode)
  • SBSParamsGraphNode.getDefinition() for the FxMap nodes (SBSParamsGraphNode)
  • MDLNode.getDefinition() for the nodes of a MDL graph (MDLNode)
# Get the definition of a node 
nodeDef = myNode.getDefinition() 
 
# Get a particular input / output / parameter 
aInput = nodeDef.getInput(aInput=sbsenum.InputEnum.MASK)                # Standard filter input 
aInput = nodeDef.getInput(aInput='MyInput')                             # Custom input name 
aOutput = nodeDef.getOutput(aOutput=sbsenum.InputEnum.MASK)             # Standard filter output 
aOutput = nodeDef.getOutput(aOutput='MyOutput')                         # Custom output name 
aParam = nodeDef.getParameter(aParameter=sbsenum.InputEnum.MASK)        # Standard filter parameter 
aParam = nodeDef.getParameter(aParameter='MyParam')                     # Custom parameter name 
 
# Get all inputs / outputs / parameters or their identifiers 
inputList = nodeDef.getAllInputs() 
inputIdentifierList = nodeDef.getAllInputIdentifiers() 
outputList = nodeDef.getAllOutputs() 
outputIdentifierList = nodeDef.getAllOutputIdentifiers() 
paramList = nodeDef.getAllParameters() 
paramIdentifierList = nodeDef.getAllParameterIdentifiers()

Comments, Frames and Navigation Pin can also be requested (SBSGUIObject), on a SBSGraph, SBSFunction or SBSParamsGraph:

# List all comments, frames, or navigation pin 
guiComments = aGraph.getAllComments() 
guiFrames   = aGraph.getAllFrames() 
guiNavPin   = aGraph.getAllNavigationPins() 
 
# All the nodes included in a frame can be requested using: 
inFrameNodes = aGraph.getNodesInFrame(myFrame) 
 
# The node associated to a comment can be requested with: 
aNode = aGraph.getNodeAssociatedToComment(aComment=myComment) 
 
# Or the opposite: 
commentList = aGraph.getCommentsAssociatedToNode(aNode=myNode)

Get help faster and easier

New user?