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