Finding the camera used by a texture projection

When you use camera projections, you end up with a data hierarchy like this.

So, given a 3d object, how do you find the cameras used by the projections? This post on xsibase shows how to do it with “nasty loops” (that’s not me saying that, it’s the person who posted the script). Here’s an alternative approach in Python. I’m still using loops, but I don’t think it looks as nasty 😉 To try and make it less nasty, I used filters on the different lists returned by the XSI SDK methods.

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

# Filters
def fCameraTxt(x):
	return (not x.NestedObjects( 'CameraTxt' ) is None)

def fUvprojdef(x):
	return x.type == 'uvprojdef'

def fCamera(x):
	return x.type == 'camera'

# Get projection cameras for the selected object
cams = []
o = si.Selection(0)
if o.IsClassOf( C.siX3DObjectID ):
	for sample in o.ActivePrimitive.Geometry.Clusters.Filter( 'sample' ):
		for uvspace in filter( fCameraTxt, sample.LocalProperties.Filter( 'uvspace' ) ):
			for uvprojdef in filter(fUvprojdef, uvspace.NestedObjects):
				cams.append( filter(fCamera, uvprojdef.NestedObjects)[0] )

	if len(cams) > 0:
		print 'Projection cameras for {0}:'.format( si.Selection(0).Name )
		for c in cams:
			print '   {0}'.format( c.Name )