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

# What is a Custom Command?

A custom command is a reusable block of scripting or C++ code that performs a specific task. A custom command can be run by other commands and scripts, by menu items, by keyboard shortcuts, and by toolbar buttons.

In a self-installing plug-in, a custom command is implemented by two callbacks: Init and Execute. For custom commands implemented with the C++ API, you can also handle undoing and redoing changes to user data with the Undo, Redo, and TermUndoRedo callbacks.

JScript Example: Skeleton code for a custom command

    //------------------------------------------------------------------
    // Install callback for the plug-in
    //------------------------------------------------------------------
    function XSILoadPlugin( in_reg )
    {
    	in_reg.Author = "Command Wizard User";
    	in_reg.Name = "MyCommands";
    	in_reg.Major = 1;
    	in_reg.Minor = 0;
    	// Register a command named "MyCommand"
    	in_reg.RegisterCommand("MyCommand","MyCommand");
    	return true;
    }

    //------------------------------------------------------------------
    // Initialize the command named "MyCommand"
    //------------------------------------------------------------------
    function MyCommand_Init( ctxt )
    {
    	// Get the Command object from the Context object
    	var oCmd;
    	oCmd = ctxt.Source;

    	// Set some basic command properties
    	oCmd.Description = "A skeleton command";
    	oCmd.Tooltip = "My command";

    	// The command returns a value
    	oCmd.ReturnValue = true;

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

    	// Add an argument
    	oArgs.Add("Arg0",siArgumentInput);
    	return true;
    }

    //------------------------------------------------------------------
    // Implement the command named "MyCommand"
    //------------------------------------------------------------------
    function MyCommand_Execute( Arg0 )
    {
    // TODO: Put your command implementation here.
    	return true;
    }

C++ Example: Skeleton code for a C++ custom command

    #include <xsi_application.h>
    #include <xsi_context.h>
    #include <xsi_pluginregistrar.h>
    #include <xsi_status.h>
    #include <xsi_argument.h>
    #include <xsi_command.h>
    #include <xsi_menu.h>
    using namespace XSI;

    //------------------------------------------------------------------
    // Install callback for the plug-in
    //------------------------------------------------------------------
    XSIPLUGINCALLBACK CStatus XSILoadPlugin( PluginRegistrar& in_reg )
    {
    	in_reg.PutAuthor(L"Command Wizard User");
    	in_reg.PutName(L"MyNewCPPCommandPlugin");
    	in_reg.PutVersion(1,0);
    	// Register a command named "MyCPPCommand"
    	in_reg.RegisterCommand(L"MyCPPCommand",L"MyCPPCommand");
    	return CStatus::OK;
    }

    //------------------------------------------------------------------
    // Initialize the command named "MyCommand"
    //------------------------------------------------------------------
    XSIPLUGINCALLBACK CStatus MyCPPCommand_Init( CRef& in_ctxt )
    {
    	// Construct a Context from the CRef
    	Context ctxt( in_ctxt );
    	// Get the Command object from the Context
    	Command oCmd;
    	oCmd = ctxt.GetSource();

    	// Set some basic command properties
    	oCmd.PutDescription(L"My CPP Command");
    	oCmd.PutTooltip(L"MyCPPCommand");

    	// The command returns a value
    	oCmd.EnableReturnValue(true);

    	// Add an argument
    	ArgumentArray oArgs;
    	oArgs = oCmd.GetArguments();
    	oArgs.Add(L"Arg0");

    	return CStatus::OK;
    }

    //------------------------------------------------------------------
    // Implement the command named "MyCPPCommand"
    //------------------------------------------------------------------
    XSIPLUGINCALLBACK CStatus MyCPPCommand_Execute( CRef& in_ctxt )
    {
    	// Construct a Context from the CRef
    	Context ctxt( in_ctxt );

    	// Get the arguments from the Context
    	CValueArray args = ctxt.GetAttribute(L"Arguments");
    	CValue Arg0 = args[0];

    	// ...

    	// Put a return value in the Context
    	ctxt.PutAttribute( L"ReturnValue", Arg0 );

    	return CStatus::OK;
    }

Callbacks

Init

Softimage calls the Init callback when the plug-in is loaded. The Init callback is where you define the command:

- What capabilities does the command support? Can it be assigned a keyboard shortcut? Logged to the command history? Used in batch mode?

- Does the command return a value?

- What arguments does the command take?

    function MyNewCommand_Init( ctxt )
    {
    	var oCmd;
    	oCmd = ctxt.Source;
    	oCmd.Description = "A simple command";
    	oCmd.Tooltip = "Do nothing";

    	// Set the command capabilities
    	oCmd.SetFlag(siSupportsKeyAssignment,false);	// true by default
    	oCmd.SetFlag(siCannotBeUsedInBatch,true);	// false by default
    	oCmd.SetFlag(siNoLogging,true);			// false by default

    	// Allow the command to return values
    	oCmd.ReturnValue = true;

    	// Add a single argument
    	var oArgs;
    	oArgs = oCmd.Arguments;
    	oArgs.Add("Arg0",siArgumentInput);

    	return true;
    }

Execute

The Execute callback implements the command. Softimage calls Execute every time the command is invoked.

If you use a scripting language to implement the command, the Execute callback function has the same arguments and return value as the command:

    function MyNewCommand_Execute( Arg0 )
    {
    	Application.LogMessage("MyNewCommand_Execute");

    	// TODO: Implement the command

    	// Return something
    	return Arg0;
    }

In C++, the command arguments and return value are stored as attributes in the callback context:

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

    	// TODO: Implement the command

    	// Return a value
    	ctxt.PutAttribute( L"ReturnValue", Arg0 );

    	return CStatus::OK;
    }