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
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 ) ... }
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.
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.
// [ JScript ] oArgs.AddWithHandler("Arg","Collection"); // Examples MyCommand(); // Same as MyCommand( Application.Selection ); MyCommand( "cone,cube,sphere" ) MyCommand( "#model" ); // All models, incl. Scene_Root
// [ JScript ] oArgs.AddWithHandler("Arg","Collection"); // Examples MyCommand(); // Same as MyCommand( Application.Selection ); MyCommand( "sphere.pnt[1,7,8,13-15" )
// [ 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)
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; }
Except where otherwise noted, this work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License