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')
si=si()

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:

Context matters: point versus polygon


Since the introduction of ICE modeling, you may have hit context mismatches like this:

or this:

That’s because compounds like Test in Geometry and Randomize Around Value are built to work with points/particles. For example, if you look inside Test Inside Geometry, you’ll see it is getting the point position.

So, when you want to use these convenience compounds in a different context, you’ll have adapt them.

Keyboard shortcuts for adding nodes to ICE trees


A customer recently asked me how to write a command that adds a node to an ICE tree. His ultimate goal was to assign a keyboard shortcut to the command, so that he could quickly insert commonly-used nodes.

Unlike menus, which can easily get the current ICE tree view, commands have to do a bit more work. A command has to find the ICE tree view in the active desktop layout (and there’s no way the command can figure which view is the “active” view).

So, here’s a Python snippet that finds an ICE Tree view and adds a Get Data node. If you make this into a command, then you can assign a shortcut key to it. I look first for a docked ICE Tree view, and if I don’t find that, I look for a floating view.

si = Application
views = si.Desktop.ActiveLayout.Views

# Find docked ICE Tree views
oICETreeViews = views.Filter( "View Manager" )(0).Views.Filter( "ICE Tree" )

# If no docked ICE Tree view, then look for floating
if oICETreeViews.Count == 0:
    oICETreeViews = views.Filter( "ICE Tree" )

if oICETreeViews.Count > 0:
    # Get the ICE tree that is loaded into the view
    sICETree = oICETreeViews(0).GetAttributeValue( "container" )

    si.AddICENode("$XSI_DSPRESETS\\ICENodes\\GetDataNode.Preset", sICETree )