Softimage SDK Programmer's Guide > Customizing Softimage using the SDK > Custom Commands >

# Adding Arguments

The Init callback is where you add arguments to a custom command. For example, the following Init callback adds two arguments:

- Arg0 uses an argument handler named "Collection". This argument handler converts strings like "Cube*,sphere*" or "*#model" into collections of objects, and provides the current selection as the default argument value.

- Arg1 is a boolean flag that is false by default. The ArgumentCollection.Add or ArgumentArray::Add method has an optional fourth parameter that specifies that data type, but Softimage is able to determine the data type of most arguments on their default values.

    // [ JScript ]
    function MyCommand_Init( ctxt )
    {
    	// Get the Command object from the callback context
    	var oCmd;
    	oCmd = ctxt.Source;

    	// Get the ArgumentCollection
    	var oArgs;
    	oArgs = oCmd.Arguments;

    	// Arg0 is a collection of Softimage objects
    	// By default, Softimage passes in the current selection
    	oArgs.AddWithHandler("Arg0","Collection");

    	// Arg1 is a boolean flag that is false by default
    	oArgs.Add( "Arg1", siArgumentInput, false );
    	return true;
    }

The Execute callback has the same arguments as the command. When you add a new argument to a command, you have to update the Execute callback signature.

    // [ JScript ]
    function MyCommand_Execute( Arg0, Arg1 )
    {
    	// ...
    }

Using argument handlers and default values make custom commands behave like built-in commands:

    // [ JScript ]
    MyCommand();// same as MyCommand( Application.Selection, false )
    MyCommand( null, true );// same as MyCommand( Application.Selection, true )
    MyCommand( "*" );// Arg0=all objects; Arg1=false
    MyCommand( "#3dobject*", true );// Arg0=3d objects only, no models; Arg1=true

## Adding Simple-Type Arguments

To add boolean, string, and number arguments, you can use the ArgumentCollection.Add or ArgumentArray::Add method and specify a default value. Softimage can determine the data type from the default value, so you can omit the final parameter to Add.

    // [ JScript ]
    oArgs.Add( "bFlag", siArgumentInput, false );		// boolean
    oArgs.Add( "bFlag", siArgumentInput, false, siBool );// Same as above

    oArgs.Add( "sName", siArgumentInput, "Custom" );// string
    oArgs.Add( "nParam", siArgumentInput, 4 );// number

When Softimage knows the argument type, it tries to convert argument values to the specified type. If you do not specify a default value or argument type when you add an argument, then the command will accept any type of value as an argument.

    // [ C++ ]
    XSIPLUGINCALLBACK CStatus MyCommand_Init( CRef& in_ctxt )
    {
    	Context ctxt( in_ctxt );
    	Command oCmd;
    	oCmd = ctxt.GetSource();
    	...
    	ArgumentArray oArgs;
    	oArgs = oCmd.GetArguments();
    	oArgs.Add(L"Arg0");// No default value

    	return CStatus::OK;
    }
    // Arg0 can be any type of value.
    // JScript examples:
    //	MyCommand( "arg" );
    //	MyCommand( true );
    //	MyCommand( 35 );
    //
    // var a3 = new Array(10, "Hello", Date());
    //	MyCommand( a3 );

For a C++ command, you'll have to check the type of the argument value in the Execute callback:

    // [ C++ ]
    XSIPLUGINCALLBACK CStatus MyCommand_Execute( CRef& in_ctxt )
    {
    	Context ctxt( in_ctxt );
    	CValueArray args = ctxt.GetAttribute(L"Arguments");
    	CValue Arg0 = args[0];

    	if( args[0].m_t == CValue::siBool )
    	...
    }

## Adding Array and Object Arguments

For array arguments, how you add the argument depends on how you intend to use the command. If you want to call the command from other scripting languages or from C++, you need to let Softimage convert the array argument to a safe array. In the Execute callback, you'll have to convert the safe array to a JScript array.

    oArgs.Add( "safeArray", siArgumentInput );// safe array

If you intend to use the command only from JScript code, you can get better performance by specifying siDispatch as the argument type. This prevents Softimage from converting the input array to a safe array.

    oArgs.Add( "jsArray", siArgumentInput, 0, siDispatch );// JScript array

To be able to pass JScript objects to a command, specify siDispatch as the argument type (to prevent Softimage from converting the argument to a safe array).

    oArgs.Add( "jsObject", siArgumentInput, 0, siDispatch );	// JScript object

See the ArgumentCollection.Add reference page for an example.

## Using Argument Handlers

Argument handlers make it easy to write custom commands that get collections, objects, and marked parameters as arguments. You can also use argument handlers to get the current frame number, or the frame rate, as arguments.

Argument handlers take care of validating argument values, converting strings such as "*" to object lists, and supplying default values.

### To get a collection of objects, or the current selection:

    // [ JScript ]
    oArgs.AddWithHandler("Arg","Collection");

    // Examples
    MyCommand();	// Same as MyCommand( Application.Selection );
    MyCommand( "cone,cube,sphere" )
    MyCommand( "#model" );	// All models, incl. Scene_Root

### To get a collection of subcomponents, or the current selection of subcomponents:

    // [ JScript ]
    oArgs.AddWithHandler("Arg","Collection");
    // Examples
    MyCommand();	// Same as MyCommand( Application.Selection );
    MyCommand( "sphere.pnt[1,7,8,13-15" )

### To get an object:

    // [ JScript ]
    oArgs.AddWithHandler( "Arg", "SingleObj" );

    // Shortcut adding args with the SingleObj argument handler
    oArgs.AddObjectArgument( "Arg" );

    // Examples
    MyCommand( Application.Selection.Item(0) );
    MyCommand( "cone" );
    MyCommand();	// Same as MyCommand(null)

### To get the current frame number and the frame rate:

    // [ JScript ]
    oArgs.AddWithHandler("currentFrame","Frame");
    oArgs.AddWithHandler("frameRate","FrameRate");

### To get the marked parameters on the currently selected objects:

    // [ JScript ]
    // All marked parameters, both animatable and non-animatable
    oArgs.AddWithHandler("Arg5","MarkedParameters");

    // Only the animatable marked parameters
    oArgs.AddWithHandler("Arg0","AnimatableParameters");

## Adding Arguments to C++ Commands

Adding arguments in C++ is pretty much the same as in scripting. You can add simple-type arguments like booleans or strings or arrays using ArgumentArray::Add, or add arguments with specialized handlers using ArgumentArray::AddWithHandler.

One difference is that the C++ Add method has two parameters only: the name of the argument and a default value. There is no parameter for specifying the type of the argument value.

    // [ C++ ]
    XSIPLUGINCALLBACK CStatus MyCommand_Init( CRef& in_ctxt )
    {
    	Context ctxt( in_ctxt );
    	Command oCmd;
    	oCmd = ctxt.GetSource();
    	oCmd.EnableReturnValue(true);
    	ArgumentArray oArgs;
    	oArgs = oCmd.GetArguments();

    	// Add some simple-type args.
    	oArgs.Add( L"bFlag", false );		// siBool
    	oArgs.Add( L"sString", L"someString" );	// siString
    	oArgs.Add( L"nNumber", 0l );		// siInt4
    	oArgs.Add( L"Float", 0.0f );	// siFloat
    	oArgs.Add( L"Arg" );		// No default value, so can be any type

    	// Default value is the current selection
    	oArgs.AddWithHandler( L"cloObjects", L"Collection" );

    	// Default value is the all marked animatable parameters
    	oArgs.AddWithHandler( L"Arg0", L"AnimatableParameters" );
    	return CStatus::OK;
    }