You can call Softimage native and custom commands from inside a C++ API project, using the Application::ExecuteCommand function. The ExecuteCommand function takes three obligatory arguments:
in_name—an input CString value representing the name of the command (for example, L"Translate")
in_args—an input CValueArray containing the list of arguments for that command (in the same order as they appear in the Commands and Scripting Reference)
io_val—an output CValue which will hold any return value from the command
More About Command's Arguments
Most of the time it is a relatively straightforward procedure to specify the command's arguments with the in_args array. Here are a few tricks to remember:
Never use an ArgumentArray, as tempting or logical as it may seem. ArgumentArrays are only for creating or editing custom Commands.
You can use null or empty arguments in the array, to force the default value argument value, but you must respect the original order of the command's arguments. For example, here are three ways to use default values:
// NewScene command using an empty CValue to force the default CValue outArg; CValueArray inArgs; inArgs.Add( CValue() ); // ProjectPathName inArgs.Add( false );// Confirm app.ExecuteCommand( L"NewScene", inArgs, outArg ); // SaveShapeKey command using undefined values to force the default CValueArray args3(9); CValue out3; args3[0] = target; args3[3] = CValue(1.0); app.ExecuteCommand( L"SaveShapeKey", args3, out3 );
// AddClip command adding only the first three arguments // NOTE: here 'root' is a reference to the Scene_Root and 'src' // is a reference to an ActionSource created previously CValueArray inArgs; CValue outArg; inArgs.Add( root.GetFullName() ); inArgs.Add( src.GetFullName() ); inArgs.Add( root.GetFullName() ); app.ExecuteCommand( L"AddClip", inArgs, outArg );
If you need to specify an enum value as one of the arguments, you need to cast it first as a LONG and then as a CValue. This is because you can't cast directly from an enum to a CValue so you first need to convert it to a LONG:
// Using the Translate command with the C++ API. This is a good demonstration of both how to // use enums and how to force the default arguments (ie., using undefined argument values) CValue outArg; CValueArray inArgs(19); // initialize with the 19 arguments inArgs[0] = obj.GetFullName(); inArgs[1] = CValue(0.0); inArgs[2] = CValue(-2.0); inArgs[3] = CValue(0.0); inArgs[4] = CValue((LONG)siAbsolute);// double cast for the enums inArgs[5] = CValue((LONG)siPivot); inArgs[6] = CValue((LONG)siObj); inArgs[7] = CValue((LONG)siY); inArgs[17] = CValue((LONG)siConstructionModePrimaryShape); app.ExecuteCommand( L"Translate", inArgs, outArg );// note the 'L' indicating wide character
If the command uses output arguments, you still need to access them through the io_val output argument. Passing pointers as part of the input argument arrays does not work: the pointers are still unintialized after the command executes. For information on how to extract output arguments from the io_val, see Dealing with Output Arguments.