Randomize all seeds in a project
This example adds an action in the Edit menu to randomize all the random seed properties from the Substance present in the current project.
To use this example:
- Go to your Python plugin folder (see this page to know where)
- Create a folder named blending_mode
- Create a file named init.py
- Copy the code below inside the file.
Copied to your clipboardimport osimport reimport sysimport mathimport jsonimport randomfrom datetime import datetimeimport substance_painter as spimport substance_painter_plugins as spp# Qt5 vs Qt6 checkIsQt5 = sp.application.version_info() < (10,1,0)if IsQt5 :from PySide2 import QtGuifrom PySide2 import QtCorefrom PySide2 import QtWidgetselse :from PySide6 import QtGuifrom PySide6 import QtCorefrom PySide6 import QtWidgetsWIDGETS = []ValidNodeTypes = (sp.layerstack.NodeType.FillLayer,sp.layerstack.NodeType.FillEffect,sp.layerstack.NodeType.FilterEffect,sp.layerstack.NodeType.GeneratorEffect)def GetSourceMode( Source ) :try:return Source.source_modeexcept:return Nonedef CheckForRandomseed( CurrentSource, Sources ) :if type( CurrentSource ) == sp.source.SourceSubstance :Parameters = CurrentSource.get_parameters()# Check if the Substance has a random seedif "$randomseed" in Parameters :Sources.append( CurrentSource )# Check if any of the inputs of the Substance has another# Substance with a random seed toofor Name in CurrentSource.image_inputs :InputSource = CurrentSource.get_source( Name )CheckForRandomseed( InputSource, Sources )def FindSources( Node, Sources ) :if Node.get_type() in ValidNodeTypes :Source = []Mode = GetSourceMode( Node )if Mode == sp.source.SourceMode.Material :Source.append( Node.get_material_source() )elif Mode == sp.source.SourceMode.Split :for Channel in Node.active_channels :Source.append( Node.get_source( Channel ) )else :Source.append( Node.get_source() )for CurrentSource in Source :CheckForRandomseed( CurrentSource, Sources )def IterateLayer( Parent, Sources ) :if Parent.get_type() == sp.layerstack.NodeType.FillLayer :FindSources( Parent, Sources )if Parent.get_type() == sp.layerstack.NodeType.FillLayer \or Parent.get_type() == sp.layerstack.NodeType.GroupLayer \or Parent.get_type() == sp.layerstack.NodeType.PaintLayer :for Effect in Parent.content_effects() :FindSources( Effect, Sources )for Effect in Parent.mask_effects() :FindSources( Effect, Sources )if Parent.get_type() == sp.layerstack.NodeType.GroupLayer :for Layer in Parent.sub_layers() :IterateLayer( Layer, Sources )def RandomizeSeed() :if not sp.project.is_open():sp.logging.warning( "No project open" )return# Sources listSources = []# List all stacks and gather their resourcesfor TextureSet in sp.textureset.all_texture_sets() :for Stack in TextureSet.all_stacks() :for Layer in sp.layerstack.get_root_layer_nodes( Stack ) :IterateLayer( Layer, Sources )# Setup parametersParameters = { "$randomseed" : random.getrandbits(16) }# Batchwith sp.layerstack.ScopedModification( "Randomize all the seeds" ) :for Source in Sources :Source.set_parameters( Parameters )def start_plugin():ActionBuilder = Noneif IsQt5 :ActionBuilder = QtWidgets.QActionelse :ActionBuilder = QtGui.QActionAction = ActionBuilder("Randomize all seeds",triggered=RandomizeSeed)sp.ui.add_action(sp.ui.ApplicationMenu.Edit,Action)WIDGETS.append( Action )def close_plugin():for Widget in WIDGETS :sp.ui.delete_ui_element( Widget )if __name__ == "__main__":start_plugin()