Calling Commands from C++

 
 
 

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:

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 );
    
    Note

    Note that this array has size 9 but only the items at index0 and index3 actually get a real value; the rest are left with empty CValues. This is the short version of explicitly initializing each null argument with CValue() as in the first snippet above.

    // 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.