Scripting: Finding all materials that contain a specific shader


Given a shader, it’s not too hard to find all materials that use (aka “own”) an instance of that shader. Here’s a Python snippet that does just that.

Note that I don’t check whether or not the shader is actually used. This snippet finds all instances, whether they are used or not (last week I posted another snippet for checking whether a shader instances was ultimately connected to the material).

from sipyutils import si			# win32com.client.Dispatch('XSI.Application')
from sipyutils import disp		# win32com.client.Dispatch
from sipyutils import C			# win32com.client.constants
si = si()

def get_materials_that_use_shader( s ):	
	mats = disp( "XSI.Collection" )	
	oShaderDef = si.GetShaderDef( s.ProgID )
	for i in oShaderDef.ShaderInstances:
		try:
			mats.Add( i.Owners(0) )
		except Exception:
			pass

	mats.Unique = True
	return mats

#
# Find all materials that use a specific shader
#
s = si.Selection(0)
if s.IsClassOf( C.siShaderID ):
	mats = get_materials_that_use_shader( s )
	for m in mats:
		print( "%s in %s" % (m.Name, m.Owners(0)) )
else:
	si.LogMessage( "Cannot find shader instances. Please select a shader." )

# Material in Sources.Materials.DefaultLib
# Material1 in Sources.Materials.DefaultLib
# Material2 in Sources.Materials.DefaultLib
# Material3 in Sources.Materials.DefaultLib
# Material7 in Sources.Materials.DefaultLib
# Material6 in Sources.Materials.DefaultLib
# Material5 in Sources.Materials.DefaultLib
# Material4 in Sources.Materials.DefaultLib

5 thoughts on “Scripting: Finding all materials that contain a specific shader

  1. I’m eager to try this script. I gave the ProgID of the shader I’m looking for I suppose in the first part of the script;

    oShaderDef = si.GetShaderDef( “Softimage.BA_color_switcher.1.0” )

    Second Part of the script I entered in the material I want to search for in all objects, in my case all the objects that are within a model object.

    mats = get_materials_that_use_shader( “material.BA_color_switcher1” )

    The end result an error;

    # ERROR : Traceback (most recent call last):
    # File “”, line 25, in
    # for m in mats:
    # NameError: name ‘mats’ is not defined
    # – [line 25]

  2. All the materials in my model are selected. I then open the render tree, select the shader node that I want the script to find within all the materials in the model, the script gives me an error “Cannot find shader instance”. What exactly is a shader instance, probably simple !

    I assume the script won’t check if it’s actually plugged into the material or simple lying randomly in the render tree, unplugged.

    • Hi

      Select a shader in the Explorer, then run the script.

      This script doesn’t check whether or not the shader instance (shader instance = a node in a render tree) is connected.

  3. I originally selected a shader node in explorer, ran the script, there was no result, I assumed I did something wrong.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s