Softimage SDK Programmer's Guide > C# Development > Programming with C# >

# Calling Object Model Members

## Calling Object Model Methods

Object model methods are quite straightforward to use in C# with only a few things to be aware of.

### Default Arguments

C# doesn't support default args, so all args must be supplied when calling OM methods from C#. For example:

    app.LogMessage(str, siSeverity.siInfo);

In scripting, the siInfo value is the default, but in C# it must be explicitly specified.

### Output Arguments

You can access output arguments from methods as long as you pass a variable that was declared with the generic C# Object class (equivalent to Variant) along with the out keyword (which flags it as an output vairable). After the method has executed, you simply cast the object to the correct Softimage class, as this example demonstrates:

    // Set up the scene
    CXSIApplicationClass app = new CXSIApplicationClass();
    object[] args = new object[2] { "", false };
    app.ExecuteCommand("NewScene", args);
    Model root = app.ActiveSceneRoot;
    X3DObject cube = root.AddGeometry("Cube", "MeshSurface", "MyCube");

    // Start with a Phong, then reconnect a Lambert using Parameter.ConnectFromFile
    Material mat = cube.AddMaterial("Phong", false, "MyPhong");
    Parameter surface = mat.Parameters["Surface"];
    app.LogMessage("currently connected shader: " + surface.Source.FullName, siSeverity.siInfo);

    // Declare output arguments as a generic object and use the 'out' keyword
    Object oldone;
    DataSource lambert = surface.ConnectFromFile("$SI_HOME\\Data\\DSPresets\\Shaders\\Material\\Lambert.Preset", out oldone);
    app.LogMessage("currently connected shader: " + surface.Source.FullName, siSeverity.siInfo);

    // To successfully retrieve output arguments, cast the generic object back to the correct class
    DataSource oldsrc = (DataSource)oldone;
    app.LogMessage("displaced shader: " + oldsrc.FullName, siSeverity.siInfo);

    // Output:
    // INFO : currently connected shader: MyCube.Material.MyPhong
    // INFO : currently connected shader: MyCube.Material.Lambert
    // INFO : displaced shader: Sources.Materials.DefaultLib.Material.MyPhong

### Generic Methods

Generic methods in the object model are converted to generic methods in C#:

    // GetAttribute returns a string Variant in the OM which maps to the generic Object class in C#
    Object obj = in_ctxt.GetAttribute("Button");

    // To access the string value, a type cast must be performed to String
    String str = (String)obj;

    // Everything in C# is an Object type, so if a method returns a long you still need to typecast
    long n = (long)in_ctxt.GetAttribute("LongAttribute");

### Geometry Interfaces

With most interfaces in the object model, you can access any method on an instance directly without having to cast. However, for geometry collection interfaces (for example, PolygonFaceCollection, NurbsSampleCollection, etc.), you need to explicitly cast the interface before calling methods:

    PolygonFaceCollection polygons = (PolygonFaceCollection)subcomp.ComponentCollection;
    Array aNodeIndexArray = (Array)polygons.PolygonNodePolygonFaceIndexArray;

    // Type cast a gain to access FacetCollection.IndexArray
    FacetCollection polyFacets = (FacetCollection)polygons;
    Array aPolyIndexArray = (Array)polyFacets.IndexArray;

## Calling Object Model Properties

The syntax to call properties in C# works is very similar to using JScript, besides the obvious difference in type declaration:

    //JScript
    var params = oObject.Kinematics.Global.Parameters;

    // C#
    ParameterCollection params = oObject.Kinematics.Global.Parameters;

However, there are some syntactic differences when dealing with collections and special workarounds for when you have to use the get- or set-accessors.

Tip

Each object model member displays a syntax section for C# which you can use to verify your code. In addition, the Visual C# ObjectBrowser and Visual Studio .NET's auto-complete are excellent tools to help understand some of the issues covered in this section.

### Accessing Collection Items

Collection items can be accessed with the [] syntax:

    Parameter posy = oObject.Kinematics.Global.Parameters["posy"];
    Parameter posx = oObject.Kinematics.Global.Parameters[0];

For iterating over a collection, the easiest and most reliable approach is to use the C# foreach loop:

    ParameterCollection params = oObject.Kinematics.Global.Parameters;
    foreach (Parameter p in params)
    {
    	app.LogMessage( p.Name + " is a " + p.ValueType.ToString() );
    }

### Implementation Differences for Properties

Some properties defined in the object model use different data types or classes for getting vs. setting. For example, the XSIApplication.ActiveProject property takes a String for setting and returns a Project object while getting:

    // Won't compile
    Project p = xsi.ActiveProject;

    // Last line causes a compiler error
    Preferences pref = xsi.Preferences;
    ProjectItemCollection proj_itms = pref.Categories;

In some cases, an alternative method or property exists that resolves the problem; for example, XSIApplication.ActiveProject2 is an alternative property which returns and sets a Property object:

    // Alternate version of above snippet:
    Project p = xsi.ActiveProject2;

If there is no alternative method or property, you can use special syntax where you prefix get_ or set_ to the name of the property and then treat it like a method:

    // Special syntax as a workaround
    ProjectItemCollection proj_itms = pref.get_Categories;
    pref.set_Categories( proj_itms );

When you use this special syntax you are actually using the get- and set-accessor methods which you can find by browsing the methods of the object in the Visual C# ObjectBrowser.

Tip

On each property page in the Commands and Scripting Reference, there is a special C# Syntax section which provides a basic C# syntax string for the get and set accessors. The data or class type is provided so you can see how to use the specific accessor. For example, here is the section on the Preferences.Categories page:

    // get accessor
    Object Preferences.get_Categories();

    // set accessor
    Preferences.set_Categories( [String pArrayVal] );

Compare this with the C# Syntax section on the GridData.ColumnCount page, which sets and returns an Int32 value:

    // get accessor
    Int32 GridData.ColumnCount();

    // set accessor
    GridData.ColumnCount( [Int32 out_Columns] );

### Properties with Input Arguments

Some object model properties take one or more input arguments, such as Primitive.Geometry, which allows you to get the geometry at a specific frame, or FCurveKey.Constraint, which tests whether the specified constraint is active on the FCurveKey or not. Many of these properties have C#-friendly method counterparts which you can find in the reference documentation by looking for Get prefixed to the name of the property and 2 suffixed to it (for example, Primitive.GetGeometry2 and FCurveKey.GetConstraint2).

In a few cases there is no corresponding C#-friendly method counterpart to use, so you can use the get- or set-accessor instead:

    // Get the geometry at the current frame
    Geometry geo = obj.ActivePrimitive.get_Geometry((int)-1);

These are the object model properties that take input arguments:

ClusterElementCollection.ItemsByIndex CollectionItem.IsA CollectionItem.Selected CommandCollection.Item Device.Channel DeviceCollection.Count DeviceCollection.Item Envelope.Elements Envelope.Weights FCurveEditor.EditorAttribute FCurveEditor.SelectedKeys FCurveKey.Constraint KinematicState.Transform NurbsSampleCollection.USamplingCount NurbsSampleCollection.VSamplingCount NurbsSurface.Knots Operator.Port PPGLayout.Item Parameter.Value | ParticleCollection.AgeArray ParticleCollection.AgeLimitArray ParticleCollection.AngularVelocityArray ParticleCollection.ColorArray ParticleCollection.DensityArray ParticleCollection.MassArray ParticleCollection.PathLengthArray ParticleCollection.PositionArray ParticleCollection.PressureArray ParticleCollection.RotationArray ParticleCollection.SeedArray ParticleCollection.SizeArray ParticleCollection.SpriteAngleArray ParticleCollection.SpriteIndexArray ParticleCollection.TypeIDArray ParticleCollection.UVWArray ParticleCollection.VelocityArray | Primitive.Geometry ProjectItem.Selected SIMatrix3.Value SIMatrix4.Value SIQuaternion.Value SIVector3.Value Selection.Item StaticKinematicState.Transform UserDataMap.IsEmpty UserDataMap.Item UserDataMap.ItemSize UserDataMap.ItemValue X3DObject.Models XSIApplication.InstallationPath