Finding shader nodes with no connections

Here’s a JScript snippet that finds render tree nodes that are not connected to anything in the render tree.

LogMessage( isConnected( Selection(0) ) );

function isConnected( o )
	var oDR = XSIUtils.DataRepository ;

	var strOpInfo = oDR.GetConnectionStackInfo( o )
//	LogMessage( strOpInfo );
	var oTopNode = ParseXML( strOpInfo ) ;

	var oConnections = oTopNode.childNodes ;
	if ( oConnections.length == 0 )
		return false;
	return true;

function ParseXML( strXML )
	var oXMLParser = new ActiveXObject("Microsoft.XMLDOM") 
	oXMLParser.async = false	
	oXMLParser.loadXML( strXML ) ;

	if (oXMLParser.parseError.errorCode != 0) 
		logmessage( "Invalid XML " + oXMLParser.parseError.reason , siError ) ;	
		return null ;

	// the xsi_file node
	// If this is NULL we must have failed to load the XML
	var oTopNode = oXMLParser.documentElement ;

	return oTopNode ;

Most of this JScript came from the SDK Explorer code in $XSI_HOME\Addons\sdkui\Application\Plugins\SDKExplorer.js, because I noticed that disconnected shaders would have an empty connection stack, and I didn’t want to go through all the parameters individually looking for connections.

Here’s a Python version that does a little more: it follows the output connections to check whether or not the shader is ultimately connected the material.

# Python Code
import xml.etree.ElementTree as etree

def is_connected( o ):
	if not o.IsClassOf( 52 ):
		print "Input is not a shader"
		return False
	sXML = XSIUtils.DataRepository.GetConnectionStackInfo( o )
	root = etree.fromstring( sXML )
	for connection in root:
		if connection.find('type').text == 'out':
			x = Application.Dictionary.GetObject( connection.find('object').text )
			return True if x.IsClassOf( 64 ) else is_connected( x )
	return False

print is_connected( Application.Selection(0) )

Missing shaders in the preset manager

If you find that you’re missing nodes in the render tree Preset Manager, then check the Softimage install folder. In particular, check

  • $XSI_HOME\Application\phenolib\spdl
  • $XSI_HOME\Application\phenolib\spdl\mibase

In a working Softimage installation, like mine , the content of the Preset Manager is determined by spdl/mi files in those folders (and perhaps others too).

For example, if I delete mia_lens_bokeh.spdl from $XSI_HOME\Application\phenolib\spdl\mibase, then Bokeh (mia) disappears from the render tree preset manager. If I put it back, and refresh the preset manager, the shader re-appears.

Getting a list of all shaders in a render tree

Here’s a Python snippet that gets all the shaders in the render tree for a specific material. As usual, I always feel that my Python snippet could be made more pythonic; for now, this will have to do…

PS The Shader reference page has a VBScript example, but that doesn’t work anymore because it was written before ShaderParameters were introduced.

from sipyutils import si		# win32com.client.Dispatch('XSI.Application')

import win32com.client
coll = win32com.client.Dispatch( "XSI.Collection" )

def doit( s, coll ):

	for p in s.Parameters:
		if p.Source and p.Source.IsClassOf( C.siShaderParameterID ):
			print p.Source.Parent.Name
			coll.Add( p.Source.Parent )
			doit( p.Source.Parent, coll )
	for l in s.TextureLayers:
		for y in l.Parameters:
			if y.Source and y.Source.IsClassOf( C.siShaderParameterID ):
				print y.Source.Parent.Name
				coll.Add( y.Source.Parent )
				doit( y.Source.Parent, coll )

# Get a material or shader to use as a starting point
mat = si.Dictionary.GetObject("Sources.Materials.DefaultLib.Architectural")
doit( mat, coll )

coll.Unique = True
coll.Add( mat.AllImageClips.GetAsText() )

This snippet worked for this [nonsensical test] render tree: