Command

Object Hierarchy | Related C++ Class: Command

Inheritance

SIObject

Command

Introduced

v2.0

Description

Represents a Softimage command (either built-in or custom). This object encapsulates information on a command such as the name, category, arguments, where it is implemented etc. Custom commands behave just like built-in Softimage commands--they are logged in the history window and can be exposed to scripting.

The XSIApplication.Commands property provides access to all the built-in and custom commands installed in the system. For example, to get the definition of the Translate command, you can use 'set oCmd = Commands( "Translate" )'.

Note that the Commands property finds commands by SIObject.Name, not by Command.ScriptingName. You can find the Name of a command by running it and then checking the Edit menu (where the Name of the last executed command always appears after 'Repeat' and 'Undo'). You can also iterate over the entire collection of commands (see the first example below).

To find a command by its scripting name, use XSIApplication.GetCommandByScriptingName. You can find the ScriptingName of a command by running it and then checking the command log.

Commands are primarily called from scripts, in which case they are invoked by calling the Command.ScriptingName with the scripting syntax for calling a function, in effect they appear as if they are "helper functions" available to the script writer. For example to call the custom command "Foo" from jscript the syntax is "Foo( arg1, arg2 );" For scripts embedded inside Netview pages this syntax does not work, however all commands can be called as methods on the Application object (for example oApplication.Foo( arg1, arg2 ) ;). It is also possible to invoke a command through the Command.Execute method.

You can also place commands in toolbars (see CreateToolbarButton). And there are two ways to place custom commands in Softimage menus. The first is through the command category (see siCommandCategory) and the second, more powerful approach, is through the Menu API.

The Arguments that a command accepts is part of its definition. All commands have a fixed number of arguments, and they are passed to the callback implementing the command in the order that they are defined in the ArgumentCollection. It is possible to define a default value and an ArgumentHandler for each argument, so commands are often invoked without specifying each argument value explicitly.

Softimage supports three possible ways to define a custom command: the embedded command, the plug-in based command and the v1.5 command. They are all based on the same Command object API but they have some subtle differences.

The embedded approach, which is new with v4.0, involves storing the implementation code of the command directly inside the definition. (See Command.Code). This approach is convenient for simple commands and is the approach demonstrated widely in the examples under the Command and Argument objects. The command definition is persisted in a .DSDynamicCommandMap file and can also be transferred to other machines by packaging it inside a xsiaddon file. Commands of this sort can be created interactively with CreateAndEditCommand. The command definition can be changed interactively by calling EditCommand. It can be destroyed by calling XSIApplication.RemoveCommand.

The plug-in based approach, also new with v4.0, involves implementing the definition and implementation of the custom command inside a self-installed plug-in (see PluginRegistrar.RegisterCommand, the example in Command.Enabled and the SimpleCommand example that is part of the installation). This approach is ideal for complex scripts and supports the C++ API. Because multiple commands, Menus, CustomProperty objects and other elements can all be implemented inside the same Plugin module it is often possible to write an entire sophisticated tool inside a single script file or dll. A command defined in this fashion is not persisted inside the .DSDynamicCommandMap file, instead its definition is regenerated by calling the Init callback each time the application is started. To edit the command definition, change the code inside the Init callback and reload the plug-in. To remove the custom command, remove the plug-in script or dll.

The older workflow, which was introduced in v1.5, is still fully supported. The steps to defining a custom command with this approach are the following:

(1) Create a command object with XSIApplication.CreateCommand

(2) Define the properties of the Command object using its properties. For example, Command.Language, Command.ReturnValue, Command.SetFlag, etc.

(3) Add any arguments you want to specify with ArgumentCollection.Add or ArgumentCollection.AddObjectArgument For example, myCommand.Arguments.Add "myArgName", siArgumentInput, true, siBool.

(4) Create the script file on disk (Command.FileName) and create a function (Command.Handler). This function takes the same number of arguments as were specified in the ArgumentCollection and it can return a value if Command.ReturnValue is true.

(5) Register the command in Softimage by using XSIApplication.AddCommand.

(6) The command is now available to be invoked. Softimage automatically stores the command definition so the command remains available in future Softimage sessions.

(7) To change the definition of the command either call XSIApplication.RemoveCommand and follow steps 2-5 again, or else call Command.Update.

(8) To remove the command from Softimage, use XSIApplication.RemoveCommand.

Note: For instructions on how to package a custom command as an add-on, see Add-on Packages.

Methods

Execute GetFlag IsClassOf operator IsEqualTo operator
SetFlag Update    
       

Properties

Application Arguments Builtin CannotBeUsedInBatch
Categories Category Code Description
Enabled FileName FullName operator Handler
Help IsNotLogged Language Name operator
NestedObjects Origin OriginPath Parent
ReturnValue ScriptingName SupportsKeyAssignment Tooltip
Type operator UID    
       

Examples

1. JScript Example

// JScript Custom Command overview - Embedded Approach
InstallCommands();
DemoCommands() ;
// Comment out this line if you want to experiment with the 
// commands created in this example
CleanupCommands();
function InstallCommands()
{
	// Remove any existing copies of the demo commands
	CleanupCommands() ;
	// each command needs to be defined.
	// (Softimage will not forget this information
	// until they are removed with a call to CleanupCommands() ;
	//
	// Define Command #1 : CommandHelloWorld
	//
	var cmd = Application.CreateCommand( "CommandHelloWorld" )
	cmd.ScriptingName = "CommandHelloWorld" ;
	cmd.Language = "JScript" ;
	cmd.ReturnValue = false ;
	cmd.Handler = "HelloWorld" ; 
	cmd.Code = HelloWorld.toString() ; // Embed the code directly in the definition
	Application.AddCommand( cmd ) ;
	//
	// Define Command #2 : CommandSimple
	//
	cmd = Application.CreateCommand( "CommandSimple" )
	cmd.ScriptingName = "CommandSimple" ;
	cmd.Language = "JScript" ;
	cmd.ReturnValue = true ;
	cmd.Handler = "Simple" ; 
	cmd.Code = Simple.toString() ; // Embed the code directly in the definition
	// You must mention the arguments you want.
	// The name is not important but must be unique
	cmd.Arguments.Add("a")
	cmd.Arguments.Add("b")	
	Application.AddCommand( cmd )
	//
	// Define Command #3 : CommandSimpleObjectArg
	//
	cmd = Application.CreateCommand( "CommandSimpleObjectArg" )
	cmd.ScriptingName = "CommandSimpleObjectArg" ;
	cmd.Language = "JScript" ;
	cmd.ReturnValue = true ;
	cmd.Handler = "SimpleObjectArg" ; 
	cmd.Code = SimpleObjectArg.toString() ; // Embed the code directly in the definition
	cmd.Arguments.AddObjectArgument("obj");
	Application.AddCommand( cmd )
}
function DemoCommands()
{
	// It is simple to execute a custom command, especially one
	// like this with no return value or arguments.
	// Will log "Hello World"
	CommandHelloWorld() ;
	// Will log "15"
	logmessage( CommandSimple( 5, 10 ) );
	// Will log "concat"
	logmessage( CommandSimple( "con","cat" ) ) ;
	newscene( null, false ) ;
	var oSphere = ActiveSceneRoot.AddGeometry("Sphere", "NurbsSurface") ;
	//Will log:
	//INFO : "Name of the input object sphere"
	//INFO : "grid"		
	logmessage( CommandSimpleObjectArg( oSphere ) ) ;
	//Softimage can also turn an string to an object:
	//INFO : "Name of the input object grid"
	//INFO : "grid1"
	logmessage( CommandSimpleObjectArg( "grid" ) ) ;
}
function CleanupCommands()
{
	Application.RemoveCommand( "CommandHelloWorld" ) ;
	Application.RemoveCommand( "CommandSimple" ) ;
	Application.RemoveCommand( "CommandSimpleObjectArg" ) ;	
}
// Implementation of CommandHelloWorld
// The name of this function matches the string we provided as cmd.Handler
function HelloWorld()
{
	LogMessage( "Hello World" ) ;
}
function Simple( in_a, in_b )
{
	return in_a + in_b ;
}
function SimpleObjectArg( in_obj )
{
	logmessage( "Name of the input object " + in_obj.Name ) ;	
	// return a different object
	return ActiveSceneRoot.AddGeometry("Grid", "MeshSurface") ;		
}

2. JScript Example

// JScript Custom Command overview - Self-Installed Approach
//
// This example relies on a script on disk so you need to
// follow an important step first before running this example:
//
// SAVE the following commented out code into commandexample.js 
// inside your %XSI_USERHOME%\Application\Plugins directory.
//
// Once you have saved the file you can run the script
/*
// BEGINNING OF CODE TO SAVE IN FILE
function XSILoadPlugin( in_reg )
{
	in_reg.Author = "Softimage SDK Team" ;
	in_reg.Name = "SDK Example - Custom Commands" ;
	in_reg.Major = 1 ;
	in_reg.Minor = 1 ;
	in_reg.RegisterCommand( "CommandHelloWorld", "CommandHelloWorld" );
	in_reg.RegisterCommand( "CommandSimple", "CommandSimple" );
	in_reg.RegisterCommand( "CommandSimpleObjectArg", "CommandSimpleObjectArg" );
	return true ;
}
//
// Define Command #1 : CommandHelloWorld
//
function CommandHelloWorld_Init(in_oCtxt)
{
	var cmd = in_oCtxt.Source ;
	cmd.ReturnValue = false ;
	// We don't need to set cmd.Language, cmd.Handler, cmd.Code
	// or cmd.FileName because this is automatically determined.
	// Application.AddCommand is not called
	// This command takes no arguments
}
//
// Define Command #2 : CommandSimple
//
function CommandSimple_Init(in_oCtxt)
{
	var cmd = in_oCtxt.Source ;
	cmd.ReturnValue = true ;
	// You must mention the arguments you want.
	// The name is not important but must be unique
	cmd.Arguments.Add("a")
	cmd.Arguments.Add("b")	
}
//
// Define Command #3 : CommandSimpleObjectArg
//
function CommandSimpleObjectArg_Init(in_oCtxt)
{
	var cmd = in_oCtxt.Source ;
	cmd.ReturnValue = true ;
	// You must mention the arguments you want.
	// The name is not important but must be unique
	cmd.Arguments.AddObjectArgument("obj");
}
// Implementation of CommandHelloWorld
function CommandHelloWorld_Execute()
{
	LogMessage( "Hello World" ) ;
}
function CommandSimple_Execute( in_a, in_b )
{
	return in_a + in_b ;
}
function CommandSimpleObjectArg_Execute( in_obj )
{
	logmessage( "Name of the input object " + in_obj.Name ) ;	
	// return a different object
	return ActiveSceneRoot.AddGeometry("Grid", "MeshSurface") ;		
}
// END OF CODE TO SAVE IN FILE
*/
// This loads the newly created file, which will define the commands inside Softimage.
// It is unnecessary if you restart Softimage or use the Plugin Manager view
Application.LoadPlugin( Application.InstallationPath( siUserPath ) + 
		"/Application/Plugins/commandexample.js" ) ;
// Demonstrate the custom commands that are defined in the plug-in
DemoCommands() ;
function DemoCommands()
{
	// It is simple to execute a custom command, especially one
	// like this with no return value or arguments.
	// Will log "Hello World"
	CommandHelloWorld() ;
	// Will log "15"
	logmessage( CommandSimple( 5, 10 ) );
	// Will log "concat"
	logmessage( CommandSimple( "con","cat" ) ) ;
	newscene( null, false ) ;
	var oSphere = ActiveSceneRoot.AddGeometry("Sphere", "NurbsSurface") ;
	//Will log:
	//INFO : "Name of the input object sphere"
	//INFO : "grid"		
	logmessage( CommandSimpleObjectArg( oSphere ) ) ;
	//Softimage can also turn an string to an object:
	//INFO : "Name of the input object grid"
	//INFO : "grid1"
	logmessage( CommandSimpleObjectArg( "grid" ) ) ;
}

3. JScript Example

// JScript Custom Command overview - v1.5 Approach
//
// This example relies on a script on disk so you need to
// follow an important step first before running this example:
//
// SAVE the following commented out code as
// %XSI_USERHOME%\Data\Scripts\commandexample.js
//
// Once you have saved the file you can run the script
/*
// BEGINNING OF CODE TO SAVE IN FILE
// Implementation of CommandHelloWorld
// The name of this function matches the string we provided as cmd.Handler
function HelloWorld()
{
	LogMessage( "Hello World" ) ;
}
function Simple( in_a, in_b )
{
	return in_a + in_b ;
}
function SimpleObjectArg( in_obj )
{
	logmessage( "Name of the input object " + in_obj.Name ) ;	
	// return a different object
	return ActiveSceneRoot.AddGeometry("Grid", "MeshSurface") ;		
}
// END OF CODE TO SAVE IN FILE
*/
InstallCommands();
DemoCommands() ;
// Comment out this line if you want to experiment with the 
// commands created in this example
CleanupCommands();
function InstallCommands()
{
	// Remove any existing copies of the demo commands
	CleanupCommands() ;
	// each command needs to be defined.
	// (Softimage will not forget this information
	// until they are removed with a call to CleanupCommands() ;
	var fileNameWithPath = Application.InstallationPath( siUserPath ) + "/Data/Scripts/commandexample.js"
	//
	// Define Command #1 : CommandHelloWorld
	//
	var cmd = Application.CreateCommand( "CommandHelloWorld" )
	cmd.ScriptingName = "CommandHelloWorld" ;
	cmd.Language = "JScript" ;
	cmd.ReturnValue = false ;
	cmd.Handler = "HelloWorld" ; 
	cmd.FileName = fileNameWithPath;
	Application.AddCommand( cmd ) ;
	//
	// Define Command #2 : CommandSimple
	//
	cmd = Application.CreateCommand( "CommandSimple" )
	cmd.ScriptingName = "CommandSimple" ;
	cmd.Language = "JScript" ;
	cmd.ReturnValue = true ;
	cmd.Handler = "Simple" ; 
	cmd.FileName = fileNameWithPath;
	// You must mention the arguments you want.
	// The name is not important but must be unique
	cmd.Arguments.Add("a")
	cmd.Arguments.Add("b")	
	Application.AddCommand( cmd )
	//
	// Define Command #3 : CommandSimpleObjectArg
	//
	cmd = Application.CreateCommand( "CommandSimpleObjectArg" )
	cmd.ScriptingName = "CommandSimpleObjectArg" ;
	cmd.Language = "JScript" ;
	cmd.ReturnValue = true ;
	cmd.Handler = "SimpleObjectArg" ; 
	cmd.FileName = fileNameWithPath;
	cmd.Arguments.AddObjectArgument("obj");
	Application.AddCommand( cmd )
}
function DemoCommands()
{
	// It is simple to execute a custom command, especially one
	// like this with no return value or arguments.
	// Will log "Hello World"
	CommandHelloWorld() ;
	// Will log "15"
	logmessage( CommandSimple( 5, 10 ) );
	// Will log "concat"
	logmessage( CommandSimple( "con","cat" ) ) ;
	newscene( null, false ) ;
	var oSphere = ActiveSceneRoot.AddGeometry("Sphere", "NurbsSurface") ;
	//Will log:
	//INFO : "Name of the input object sphere"
	//INFO : "grid"		
	logmessage( CommandSimpleObjectArg( oSphere ) ) ;
	//Softimage can also turn an string to an object:
	//INFO : "Name of the input object grid"
	//INFO : "grid1"
	logmessage( CommandSimpleObjectArg( "grid" ) ) ;
}
function CleanupCommands()
{
	Application.RemoveCommand( "CommandHelloWorld" ) ;
	Application.RemoveCommand( "CommandSimple" ) ;
	Application.RemoveCommand( "CommandSimpleObjectArg" ) ;	
}

4. VBScript Example

' --------------------------------------------------------------
'
'	This VBScript example demonstrates how to find a built-in 
' 	(or native) Softimage command using its scripting name.
'
' --------------------------------------------------------------
' Loop through the Softimage command collection looking for a name match
for each c in Application.Commands
	if c.ScriptingName = "FreezeObj" then
		' At this point, you could either... 
		' ...get its name to use elsewhere ...
		sScpName = c.Name
		' ...use it to create a Command object...
		set oCmd = c
		' ...or perform whatever action you want on it, like demonstrating 
		'    the difference between the Name and ScriptingName properties
		Application.LogMessage "FreezeObj info......." & vbLf _
			& vbTab & "Name          = " & c.Name & vbLf _
			& vbTab & "ScriptingName = " & c.ScriptingName
	end if
next
' With the new command pointer, we can access command information
Application.LogMessage oCmd.Name & ": Belongs to the " & oCmd.Category & " category/menu."
' Now that we know the command's full name, we can access the command using 
' the name as the key in the command collection
set oCommand = Application.Commands( sScpName )
Application.LogMessage oCommand.Name & ": " & oCommand.Description
' --------------------------------------------------------------------------
' Output of above script:
'INFO : "FreezeObj info.......
'	Name          = Freeze Operator Stack
'	ScriptingName = FreezeObj"
'INFO : "Freeze Operator Stack: Belongs to the Edit category/menu."
'INFO : "Freeze Operator Stack: Freeze all the operators of the selected object(s)"

5. JScript Example

/* --------------------------------------------------------------
	Hello World example, based on v1.5 workflow for defining a command
	This JScript example creates and registers a custom
	command and then demonstrates how you can find it in
	the Softimage command collection using the Builtin property.
----------------------------------------------------------- */
// Start off with a clean slate
Application.RemoveCommand("Howdy");
// Get the factory (installation) path and use it to build the filename & path
var sFileName = InstallationPath( siUserPath ) + "\\Data\\Scripts\\HelloWorld.js";
// Create a standard hello world script file
var fso = new ActiveXObject( "Scripting.FileSystemObject" );
var fHWFile = fso.CreateTextFile( sFileName  );
fHWFile.WriteLine( "function SayHi()" );
fHWFile.WriteLine( "{" );
fHWFile.WriteLine( "\tApplication.LogMessage( \"Hello, World!\" );" );
fHWFile.WriteLine( "}" );
fHWFile.Close();
// Add it to the command map in Softimage
var oCmd = Application.CreateCommand( "Howdy", siExportCategory );
oCmd.Description = "Display the traditional greeting";
oCmd.ScriptingName = "Howdy";
oCmd.Handler = "SayHi";
oCmd.FileName = sFileName;
oCmd.Language = "JScript";
Application.AddCommand( oCmd );
// Run it just to make sure it's working
oCmd.Execute();
// Now loop through the command collection and print the name and
// scripting name of each custom command
// (Tip: It is faster to use CommandCollection.Filter("Custom") to
// find all custom commands)
var eCmdList = new Enumerator( Application.Commands );
eCmdList.moveFirst();
var c;
for (; !eCmdList.atEnd(); eCmdList.moveNext() )
{
	c = eCmdList.item();
	if(!(c.Builtin))
	{
		LogMessage( c.Name + "(" + c.ScriptingName + ") is a custom command." );
	}
}
// Restore everything back to normal
Application.RemoveCommand("Howdy");
fso.DeleteFile( sFileName, true );
// --------------------------------------------------------------
// Output of the above script is:
//
//INFO : "Hello, World!"
//Howdy();
//Followed by a list of all custom commands installed, including:
//INFO : "Howdy is a custom command."

See Also

XSIApplication.CreateCommand Application.ExecuteScript CreateScriptCommand Argument ArgumentHandler EditCommand CreateAndEditCommand Menu.AddCommandItem XSIApplication.GetCommandByScriptingName