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.
- Application.FindObjects2 took 0.002 seconds, but that includes the View cameras too
- Application.FindObjects2 with filtering out of View cameras took 0.005 seconds
- SelectAllUsingFilter took 0.034 seconds. Note that this does not actually select anything, it just returns the objects that passed the filter
- FindChildren2 took 0.153 seconds
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