## FindObjects

### Introduced

v1.0

### Description

Finds objects by their type

### Scripting Syntax

    oReturn = FindObjects( [Path], [Type] );

### Return Value

Returns an XSICollection object that contains the found objects.

### Parameters

Parameter | Type | Description
--- | --- | ---
Path | String | Object path name - NOT IMPLEMENTED
Type | String | The Class ID of the Object. This is GUID which uniquely identifies each type of object. For example, each instance of a Phong shader has the same Class ID, which is different from the Class ID of a Lambert shader. You can determine the Class ID from the Reference line of the SPDL file or via DataRepository.GetIdentifier. Note: To find Self-Installed Custom Operators use "{72936430-9B0C-4167-8CA7-C30FC2188BB9}" and to find Self-Installed Custom Properties use "{76332571-D242-11d0-B69C-00AA003B3EA6}".

### Examples

#### 1. JScript Example

    /*
            Demonstrates how to use FindObjects to get all models
    */
    NewScene( null, false ) ;
    var oModel = ActiveSceneRoot.AddModel(null, "MyModel" ) ;
    var oNestedModel = oModel.AddModel(null, "Nested1" ) ;
    var oNestedModel = oModel.AddModel(null, "Nested2" ) ;
    var oNotAModel = oModel.AddNull() ; // Won't be found
    var classIDOfModels = XSIUtils.DataRepository.GetIdentifier( oModel, siObjectCLSID ) ;
    var oColl = FindObjects( null, classIDOfModels ) ;
    Application.LogMessage( "FindObjects found " + oColl.GetAsText() ) ;
    // An alternative way to find models is with the Model property
    var oModelsUnderSceneRootModel =  ActiveSceneRoot.Models ;
    for ( var i = 0 ; i < oModelsUnderSceneRootModel.count ; i++ )
    {
            Application.LogMessage( oModelsUnderSceneRootModel.Item( i ) ) ;
    }
    //Expected results:
    //
    //INFO : FindObjects found MyModel,Nested1,Nested2,Scene_Root
    //INFO : MyModel
    //INFO : Nested1
    //INFO : Nested2

#### 2. JScript Example

    SetupDemoScene() ;
    DemoSearchFunctions();
    // General function to find all custom properties. This returns a XSICollection and includes all custom properties
    // that are part of the scene, or installed as custom preferences or "free-floating"
    function FindAllCustomProperties( oParent )
    {
            // All Custom Properties are registered with this GUID
            return FindObjects( null, "{76332571-D242-11d0-B69C-00AA003B3EA6}" ) ;
    }
    // Function to only find the "CustomColor" Custom Property
    function FindCustomColorProperties()
    {
            var oAllCustomProperties = FindObjects( null, "{76332571-D242-11d0-B69C-00AA003B3EA6}" ) ;
            var oFilteredList = new ActiveXObject( "XSI.Collection" ) ;
            for ( var i = 0 ; i < oAllCustomProperties.Count ; i++ )
            {
                    if ( oAllCustomProperties(i).Type == "CustomColor" )
                    {
                            oFilteredList.Add( oAllCustomProperties(i) ) ;
                    }
            }
            return oFilteredList ;
    }
    // Function to find all psets under a particular 3dobject
    function FindNestedCustomProperties( oParent )
    {
            var oAllCustomProperties = FindObjects( null, "{76332571-D242-11d0-B69C-00AA003B3EA6}" ) ;
            var oFilteredList = new ActiveXObject( "XSI.Collection" ) ;
            for ( var i = 0 ; i < oAllCustomProperties.Count ; i++ )
            {
                    // This will be null for free floating custom properties,
                    // custom preferences, objects nested under a shader etc
                    o3DObjectOfCustomProperty = oAllCustomProperties(i).Parent3DObject ;
                    if ( o3DObjectOfCustomProperty  != null &&
                            o3DObjectOfCustomProperty.FullName == oParent.FullName )
                    {
                            oFilteredList.Add( oAllCustomProperties(i) ) ;
                    }
            }
            return oFilteredList ;
    }
    // Build a scene with Custom Properties at various places
    function SetupDemoScene()
    {
            NewScene( null, false ) ;
            ActiveSceneRoot.AddProperty( "CustomColor", false, "MyColor" ) ;
            ActiveSceneRoot.AddProperty( "CustomColor", false, "MyColor2" ) ;
            ActiveSceneRoot.AddProperty( "CustomProperty", false, "MyEmptyCustomProp" ) ;
            oSphere = ActiveSceneRoot.AddGeometry( "Sphere", "MeshSurface" ) ;
            oSphere.AddProperty( "CustomColor", false, "ColorUnderSphere" ) ;
            oCls = oSphere.ActivePrimitive.Geometry.AddCluster( "edge", "MyCluster" ) ;
            oCls.AddProperty( "CustomColor", false, "MyColor" ) ;
            oSphere.AddMaterial( "Phong" ) ;
            var oPhongShader = oSphere.Material.Shaders(0)
            oPhongShader.AddProperty( "CustomProperty", false, "EmptyNestedProp" ) ;
            oPhongShader.AddProperty( "CustomProperty", false, "MyColor" ) ;
            var oModel = ActiveSceneRoot.AddModel(null, "MyModel" ) ;
            oModel.AddProperty( "CustomColor", false, "MyColor3" ) ;
            oModel.AddProperty( "CustomProperty", false, "EmptyProperty" ) ;
            oModel.AddNull().AddProperty( "CustomColor", false, "MyColor4" ) ;
            // Create a PSet that doesn't belong anywhere in the scene
            // It's fullname will be something like "CustomColor<yyyy>"
            // where yyyy is a number.
            var oFreeFloatingPSet = XSIFactory.CreateObject( "CustomColor" ) ;
    }
    // Show the result of calling the Find functions
    // with the demo scene
    function DemoSearchFunctions()
    {
            // All Custom Properties
            //
            //Example output (in this case a Custom Preference called
            //XSI_UserNormalEditing is installed):
            //INFO : ------------------------------------------------
            //INFO : All Custom Properties
            //INFO : ------------------------------------------------
            //INFO : sphere.polymsh.cls.MyCluster.MyColor
            //INFO : Sources.Materials.DefaultLib.Material.Phong.EmptyNestedProp
            //INFO : MyEmptyCustomProp
            //INFO : MyColor2
            //INFO : preferences.XSI_UserNormalEditing
            //INFO : CustomColor<1068>
            //INFO : MyColor
            //INFO : MyModel.EmptyProperty
            //INFO : Sources.Materials.DefaultLib.Material.Phong.MyColor
            //INFO : sphere.ColorUnderSphere
            //INFO : MyModel.null.MyColor4
            //INFO : MyModel.MyColor3
            var oAllCustomProperties = FindAllCustomProperties() ;
            PrintCollection( oAllCustomProperties, "All Custom Properties" ) ;
            // Find only the Custom Properties that come from the "Custom Color"
            // Self-installed Property
            //
            //Example output:
            //INFO : ------------------------------------------------
            //INFO : Custom Color Properties
            //INFO : ------------------------------------------------
            //INFO : sphere.polymsh.cls.MyCluster.MyColor
            //INFO : MyColor2
            //INFO : CustomColor<1068>
            //INFO : MyColor
            //INFO : sphere.ColorUnderSphere
            //INFO : MyModel.null.MyColor4
            //INFO : MyModel.MyColor3
            var oCustomColorOnly = FindCustomColorProperties() ;
            PrintCollection( oCustomColorOnly , "Custom Color Properties" ) ;
            // Find all the custom properties nested under the sphere
            // Note: It does not include custom properties that are part
            // of the material of the Sphere.
            //
            //Example output:
            //INFO : ------------------------------------------------
            //INFO : Custom Properties Under Sphere
            //INFO : ------------------------------------------------
            //INFO : sphere.polymsh.cls.MyCluster.MyColor
            //INFO : sphere.ColorUnderSphere
            var oSphereCustomProps = FindNestedCustomProperties( GetValue( "Sphere" ) ) ;
            PrintCollection( oSphereCustomProps , "Custom Properties Under Sphere" ) ;
            // These are custom properties directly under the scene root (not
            // including those nested inside X3DObjects)
            //
            //Example output:
            //INFO : ------------------------------------------------
            //INFO : Custom Properties Under Scene Root
            //INFO : ------------------------------------------------
            //INFO : MyEmptyCustomProp
            //INFO : MyColor2
            //INFO : MyColor
            var oSceneRootCustomProps = FindNestedCustomProperties( ActiveSceneRoot ) ;
            PrintCollection( oSceneRootCustomProps, "Custom Properties Under Scene Root" ) ;
    }
    // Show contents of a XSICollection object in the Script history
    function PrintCollection( in_col, in_title )
    {
            LogMessage( "------------------------------------------------" ) ;
            LogMessage( in_title ) ;
            LogMessage( "------------------------------------------------" ) ;
            for ( var i = 0 ; i < in_col.Count ; i++ )
            {
                    LogMessage( in_col(i).FullName ) ;
            }
    }

#### 3. JScript Example

    /*
            This example demonstrates how FindObjects can be used to quickly find all instances of a particular type of shader.
            This approach can be faster than doing a recursive search through all the scene shader trees.
    */
    SetupDemoScene() ;
    LogMessage( DiscoverCloudClassID() ) ;
    //INFO : {A85CBE5F-DDD7-11D1-804A-00A0C906835D}
    LogMessage( DiscoverImageClassID() ) ;
    //INFO : {1C500B61-023C-11D3-8C03-00A0243E3672}
    var oAllClouds = FindCloudShaders() ;
    PrintCollection( oAllClouds, "All Cloud Shaders" ) ;
    //INFO : ------------------------------------------------
    //INFO : All Cloud Shaders
    //INFO : ------------------------------------------------
    //INFO : Sources.Materials.DefaultLib.Material.Phong.Cloud1
    //INFO : Sources.Materials.DefaultLib.Material.Phong.Cloud1.Cloud2
    //INFO : Sources.Materials.DefaultLib.Material1.Lambert.Cloud3
    //INFO : Sources.Materials.DefaultLib.Material1.Lambert.Cloud3.Cloud4
    //INFO : Sources.Materials.DefaultLib.Material1.Lambert.Cloud5
    var oAllImages = FindImageShaders() ;
    PrintCollection( oAllImages, "All Image Shaders" ) ;
    //INFO : ------------------------------------------------
    //INFO : All Image Shaders
    //INFO : ------------------------------------------------
    //INFO : Sources.Materials.DefaultLib.Material.Phong.Image
    function FindCloudShaders()
    {
            // This GUID was determined by calling DiscoverCloudClassID().
            // Because it never changes it can be hardcoded rather than
            // being re-discovered each time the script is run
            return FindObjects( null, "{A85CBE5F-DDD7-11D1-804A-00A0C906835D}" ) ;
    }
    function FindImageShaders()
    {
            // Using GUID returned by DiscoverImageClassID()
            return FindObjects( null, "{1C500B61-023C-11D3-8C03-00A0243E3672}" ) ;
    }
    // Function to determine the ClassID of the Cloud Shader
    // Similar code can work for custom shaders, and the GUID can also
    // be read from the SPDL file and is visible in the SDK Explorer
    function DiscoverCloudClassID()
    {
            var oTempCloud = XSIFactory.CreateObjectFromPreset(
                            "Cloud",
                            "Texture Shaders" ) ;
            var oCloudGUID = GetClassID( oTempCloud ) ;
            // Delete the shader right away so it doesn't appear when we search
            DeleteObj( oTempCloud ) ;
            return oCloudGUID ;
    }
    function DiscoverImageClassID()
    {
            var oTempImageNode = XSIFactory.CreateObjectFromPreset(
                            "Image",
                            "Texture Shaders" ) ;
            var oImageGUID = GetClassID( oTempImageNode ) ;
            DeleteObj( oTempImageNode ) ;
            return oImageGUID ;
    }
    // Determine the ClassID GUID of a particular object.
    // All other instances of this object have this same GUID
    // and it never changes.
    function GetClassID( in_ExampleObject )
    {
            oDataRepository = XSIUtils.DataRepository ;
            return oDataRepository.GetIdentifier( in_ExampleObject, siObjectCLSID ) ;
    }
    // Build some render trees with the Object Model
    // They don't make any sense in terms of rendering
    // a nice texture, but show nodes connected in various ways
    function SetupDemoScene()
    {
            NewScene( null, false ) ;
            // First render tree
            oSphere = ActiveSceneRoot.AddGeometry( "Sphere", "MeshSurface" ) ;
            oSphere.AddMaterial( "Phong" ) ;
            var oPhongShader = oSphere.Material.Shaders(0) ;
            ImageFile1 = XSIUtils.BuildPath( Application.InstallationPath(siFactoryPath),
                                            "Data",
                                            "XSI_SAMPLES",
                                            "Pictures",
                                            "jaiqua_face.jpg" ) ;
            var oImageClip1 = SICreateImageClip2( ImageFile1 ).Item(0) ;
            var oAmbientParam = oPhongShader.Parameters( "ambient" )
            var oImageNode1 = oAmbientParam.connectfrompreset("Image", siTextureShaderFamily) ;
            oImageNode1.Parameters( "tex" ).Connect( oImageClip1 ) ;
            var oDiffuseParam = oPhongShader.Parameters( "diffuse" )
            var oCloud1 = oDiffuseParam.connectfrompreset("Cloud", siTextureShaderFamily) ;
            oCloud1.Name = "Cloud1" ;
            var oCloud1Color1 = oCloud1.Parameters("color1") ;
            var oCloud2 = oCloud1Color1.connectfrompreset("Cloud", siTextureShaderFamily) ;
            oCloud2.Name = "Cloud2" ;
            //Second render tree
            oCone = ActiveSceneRoot.AddGeometry( "Cone", "MeshSurface" ) ;
            oCone.AddMaterial( "Lambert" ) ;
            var oLamberShader = oCone.Material.Shaders(0) ;
            oDiffuseParam = oLamberShader.Parameters( "diffuse" ) ;
            var oCloud3= oDiffuseParam.connectfrompreset("Cloud", siTextureShaderFamily);
            oCloud3.Name = "Cloud3" ;
            oCloud3Color2 = oCloud3.Parameters( "color2" ) ;
            oCloud4= oCloud3Color2.connectfrompreset("Cloud", siTextureShaderFamily);
            oCloud4.Name = "Cloud4"
            // Fractal is connected twice. This can provide a tricky
            // scenario for recursive scans of a shader tree, because the
            // same shaders can appear multiple times.
            // But FindObjects() would have not trouble finding just one instance
            // of this object
            oCloud3Color1 = oCloud3.Parameters( "color1" ) ;
            oCloud3Color1.Connect( oCloud4 ) ;
            oAmbientParam = oLamberShader.Parameters( "ambient" ) ;
            oCloud5 = oAmbientParam.connectfrompreset("Cloud", siTextureShaderFamily) ;
            oCloud5.Name = "Cloud5" ;
    }
    // Show contents of a XSICollection object in the Script history
    function PrintCollection( in_col, in_title )
    {
            LogMessage( "------------------------------------------------" ) ;
            LogMessage( in_title ) ;
            LogMessage( "------------------------------------------------" ) ;
            for ( var i = 0 ; i < in_col.Count ; i++ )
            {
                    LogMessage( in_col(i).FullName ) ;
            }
    }

#### 4. JScript Example

    // Demonstration of how to use FindObjects to
    // find Runtime scripted operators in the scene.
    //
    // This technique does not find SPDL-based custom operators
    // because once a Custom Operator is stored inside a SPDL file
    // it is assigned its own GUID, which is found as the Reference
    // value at the top of the file.
    function GetAllRuntimeCustomOperators()
    {
            var siScriptedOperatorID = "{CCECD9D9-10A3-11d4-879F-00A0C983050D}"
            var oItems = FindObjects(null,siScriptedOperatorID)
            // For convenience to the caller,
            // always return a collection even if nothing was found
            if ( oItems == null )
                    oItems = new ActiveXObject( "XSI.Collection") ;
            return oItems ;
    }
    // Simple usage of GetAllRuntimeCustomOperators
    function SelectAllRuntimeOperators()
    {
            SelectObj( GetAllRuntimeCustomOperators() ) ;
    }
    //
    // Demonstration of GetAllRuntimeCustomOperators
    //
    function BuildDemoScene()
    {
            var oNull = Application.ActiveSceneRoot.AddNull() ;
            var oPosX = oNull.Kinematics.Global.Parameters( "posx" ) ;
            var oRotX = oNull.Kinematics.Local.Parameters( "rotx" ) ;
            AddSimpleOp( oPosX ) ;
            AddSimpleOp( oRotX ) ;
    }
    function AddSimpleOp( in_param )
    {
            // Build a runtime operator that drives in_param
            var oOp = XSIFactory.CreateScriptedOp(
                                    "FindMe",
                                    FindMe_Update.toString(),
                                    "JScript" ) ;
            oOp.AlwaysEvaluate = true ;
            oOp.AddOutputPort( in_param ) ;
            oOp.Connect() ;
    }
    function FindMe_Update(ctx,out)
    {
            // Just set the output parameter
            // to current frame value
            out.Value = ctx.CurrentFrame ;
    }
    BuildDemoScene() ;
    var oOps = GetAllRuntimeCustomOperators() ;
    for ( var i = 0 ; i < oOps.Count ; i++ )
    {
            Application.LogMessage( oOps(i).FullName )  ;
    }
    //Expected output:
    //INFO : null.kine.global.FindMe
    //INFO : null.kine.local.FindMe

### See Also

DataRepository.GetIdentifier X3DObject.FindChildren XSIFactory.CreateObject XSIFactory.CreateObjectFromPreset SIObject.NestedObjects