Migrating Legacy Plug-ins

Softimage continues to support legacy C++ commands, but because of the rich feature set and the improved workflow associated with self-installed custom commands you should really take the time to port them to the new mechanism. The good news is that the actual implementation of your code does not need to change significantly.

One way to port your Custom Command to Softimage is to create a new command using the SDK Command Wizard (see Custom Command Wizard for more information) and then copy and paste your actual implementation into the new dll. However it is also easy to do this manually. For the purpose of this example, assume that your command in called Foo.

To port a legacy C++ command to a self-installed plugin.

1. Back up your source files.

2. In Softimage make sure that any old version of the command has been removed by running the following code snippet in the Script Editor:

       // JScript
       Application.RemoveCommand( "Foo" );

3. For Windows, instead of using a .def file to export functions, add the XSIPLUGINCALLBACK macro to the function definition:

       XSIPLUGINCALLBACK CStatus XSILoadPlugin( PluginRegistrar& in_reg )

4. In your .cpp file add a XSILoadPlugin callback function similar to this:

       #ifdef unix
       extern "C"
       #endif
       XSIPLUGINCALLBACK CStatus XSILoadPlugin( PluginRegistrar& in_reg )
       {
           in_reg.PutAuthor(L"My Name");
           in_reg.PutName(L"foo Plug-in");
           in_reg.PutVersion(1,0);
           in_reg.RegisterCommand(L"Foo",L"Foo");

           return CStatus::OK;
       }

| For more information on this callback and more about self-installing plug-ins in general, see Self-Installing Plug-ins.

5. Add another callback function called Foo_Init. This function replaces your old installation script which probably looked like this.

       'OBSOLETE:
       SUB InstallFooDemo( dllDir, ext )
           Module="Foo"
           filename = dllDir & "/" & Module & ext

           Application.RemoveCommand "Foo"
           SET oCmd = Application.CreateCommand("Foo",siNoCategory)
           oCmd.ScriptingName = "Foo"
           oCmd.FileName = filename
           oCmd.Language = "CPP"

           oCmd.arguments.add "Arg0", siArgumentInput
           oCmd.arguments.addObjectArgument "Arg1"

           ' Add the new command
           Application.AddCommand oCmd
       END SUB

The new Foo_Init function is where you define the arguments and the flags for your command. The C++ API for defining a command is very similar to the Object Model API that you used in your install script so porting your code should not be too difficult. See the Argument and Command classes for more details.

Here is an example of what your Foo_Init function could look like:

       #ifdef unix
       extern "C"
       #endif
       XSIPLUGINCALLBACK CStatus Foo_Init( CRef& in_ctxt )
       {
           Context ctxt( in_ctxt );
           Command oCmd;
           oCmd = ctxt.GetSource();
           oCmd.PutDescription(L"Foo does important stuff");
           oCmd.EnableReturnValue(true);

           ArgumentArray oArgs;
           oArgs = oCmd.GetArguments();
           oArgs.Add(L"Arg0");
           oArgs.AddObjectArgument(L"Arg1");
           return CStatus::OK;
       }

6. Once you are done writing your Foo_Init function, remove the old install script code.

7. Now you need to replace the old XSIOnCommandCPP callback with the new Foo_Execute callback function. Your old code:

       #ifdef unix
       extern "C"
       #endif
       XSI::CStatus XSIOnCommandCPP
       (
           const XSI::CString& in_strCmdName, // name of the command
           XSI::CValueArray& args, // array of arguments
           XSI::CValue& io_retVal // return value
       )
       {
           ...
       }

becomes:

       #ifdef unix
       extern "C"
       #endif
       XSIPLUGINCALLBACK CStatus foo_Execute( CRef& in_ctxt )
       {
           Context ctxt( in_ctxt );
           CValueArray args = ctxt.GetAttribute(L"Arguments");
           ...
       }

| There is no io_retVal argument anymore, instead you can return a value like this:
       CValue returnValue ;
       //...set a value in returnValue ;
       ctxt.PutAttribute( L"ReturnValue", returnValue );

8. Compilation time. You may find that you need to add some new C++ API include statements. For example:

       #include <xsi_context.h>
       #include <xsi_pluginregistrar.h>
       #include <xsi_argument.h>
       #include <xsi_command.h>

9. Now you just need to make sure your dll is in the correct path, for example in the "\Application\Plugins" directory on your workgroup. You can use the Plugin Manager to load/reload the dll without restarting Softimage (see Working with the Plug-in Manager for more information).

10. Invoke your command in the Script Editor to test it and that’s it!

Multiple commands

The preceding procedure only covers the case of a single command in a .dll or .so. However you can easily have multiple commands implemented in your self-installing plug-in dll. Just register them in your XSILoadPlugin implementation, and add an Init and Execute function for each one.

You can use the Command Wizard to add commands to a plug-in. In the script editor, right-click and choose Tools > Add Command.

Autodesk Softimage v7.5