Scripting – Finding all cameras in a scene


In scripting, there’s several ways to find all the cameras in a scene.

I put together a little script to do some timing of the different ways of finding cameras.
Here’s a quick summary (using a scene with about 10k 3d objects). YMMV.

See this related thread on the XSI list. If you need to find scenes cameras frequently, then one suggestion (from Matt Lind) was to tag the scene cameras with a custom property, and then use FindObjects/FindObjects2 on that.

import time
si = Application
log = si.LogMessage
from win32com.client import constants as C

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

si.SetValue("preferences.scripting.cmdlog", False, "")

#
# From http://www.softimageblog.com/archives/357
#
def timeExecution(func):
    def closure(*args, **kwargs):
        startTime = time.time()
        try:
            ret = func(*args, **kwargs)
        except Exception, e:
            delta = time.time() - startTime
            log('Failed in %f seconds' % delta)
            raise
        delta = time.time() - startTime
        log('%s finished in %f seconds' % (func.__name__, delta))
        return ret
    return closure 

@timeExecution
def getCameras_Application_FindObjects2():
	c = si.FindObjects2( C.siCameraID )
	return c.Count

@timeExecution
def getCameras_Application_FindObjects2_w_Filter():
	cams = si.FindObjects2( C.siCameraID )
	oCameraColl.Items = cams
	oCameraColl.RemoveItems( cams.Filter( "", "", "CopyPaste*" ) )
	oCameraColl.RemoveItems( cams.Filter( "", "", "View*" ) )

	return oCameraColl.Count


@timeExecution
def getCameras_FindChildren2():
	cams = si.ActiveSceneRoot.FindChildren2("", "camera")
	return cams.Count

@timeExecution
def getCameras_SelectAllUsingFilter():
	cams = si.SelectAllUsingFilter("Camera", "siIgnoreComponentVisibility", False, "")
	return cams.Count

@timeExecution
def getCameras_FindObjects():
	cams = Application.FindObjects( "", "{5FC0CCAE-3DC8-11D0-9449-00AA006D3165}" )

	# That GUID returns lots of other objects besides cameras
	cams = si.SIFilter( cams, 'camera' )

	# Unfortunately, XSICollection doesn't have a Filter method
#	oCameraColl.Items = cams
#	oCameraColl.RemoveItems( cams.Filter( "", "", "CopyPaste*" ) )
#	oCameraColl.RemoveItems( cams.Filter( "", "", "View*" ) )
	return cams.Count

# This finds cameras directly under a model only
@timeExecution
def getCameras_Model_FindObjects():
	cams = si.ActiveSceneRoot.FindObjects( C.siCameraID )
	return cams.Count


log( 'Found %d cameras' % getCameras_FindObjects() )
log( 'Found %d cameras' % getCameras_Application_FindObjects2() )
log( 'Found %d cameras' % getCameras_Application_FindObjects2_w_Filter() )
log( 'Found %d cameras' % getCameras_FindChildren2() )
log( 'Found %d cameras' % getCameras_SelectAllUsingFilter() )

Here’s some numbers from a scene with 9857 objects

# INFO : getCameras_FindObjects finished in 0.034000 seconds
# INFO : Found 68 cameras

# INFO : getCameras_FindObjects2 finished in 0.002000 seconds
# INFO : Found 68 cameras

# INFO : getCameras_FindObjects2_w_Filter finished in 0.005000 seconds
# INFO : Found 24 cameras

# INFO : getCameras_FindChildren2 finished in 0.153000 seconds
# INFO : Found 24 cameras

# INFO : getCameras_SelectAllUsingFilter finished in 0.034000 seconds
# INFO : Found 24 cameras

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 )

Connecting to %s