Adding Arguments

 
 
 

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

// [ 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;
}