Custom ICENode Wizard

The Custom ICENode Wizard is used to generate a fully functioning custom ICENode plug-in code, including:

• the project file (for both Windows or Linux platorms)

• the required registration code based on the port definition

• skeleton callback code

The implementation of the evaluation algorithm is left to the ICENode developer.

| You can get your Custom ICENode to appear in the Preset Manager with a special icon (thumbnail). See Customizing Icons for Custom ICENodes for more information.

To create a custom ICENode using the SDK ICENode Wizard

1. Click File > Plug-ins to open the Plug-in Manager. (In the Tools Development Environment layout, you can click the Plug-ins tab to switch to the Plug-in Manager view)

2. Do one of the following:

- To create the ICENode in the User location, click File > New > ICENode.

- To create the ICENode in a different location (such as a workgroup or an Add-on directory), expand the location in the Plug-in Tree, right-click the Plugins folder and click New > ICENode.

The ICENode wizard appears.

3. In the ICENode Name box, type a name for the node.

The first character in an ICENode name should be a letter. Subsequent characters can be letters, numbers, or underscore (_) characters.

The wizard automatically replaces spaces with underscores.

4. Type a category of your ICENode in the ICENode Category textbox. The category is used to classify and list the new ICENode in the ICE graph view toolbar.

5. You can optionally change the Output Directory where the new plug-in will be generated.

6. Click on Use single-threading model option to enable the support for single-thread processing.

7. Click the Input Ports tab. Here you can specify the input port definitions.

8. Click the Output Ports tab. Here you can specify the output port definitions.

9. Click the Generate Code tab. Here you can add optional callbacks or debug features.

Ports

The Input Ports and Output Ports tabs allow you to set up ports and portgroups.

For convenience each port is added to a different group. You can change this by editing the Group ID directly in the grid table.

Name

Use this text box to specify a new name for your port.

Data Type

Select one of the supported data types from the drop-down list. These values correspond to the siICENodePortDataType enum.

Structure Type

Select one of the supported structure types from the drop-down list. These values correspond to the siICENodePortStructureType enum.

Context Type

Select one of the supported context types from the drop-down list. These values correspond to the siICENodeEvaluationContextType enum.

Constraint Port Type

Check this option to constrain the new port with other ports in your ICENode. For more information on using constraint maps in your plug-in, see Handling Port Polymorphism.

Group ID

Ports IDs are generated by the wizard and added to the group specified by the Group ID slider. For more information on using port instances in your plug-in, see Multiple Port Connections.

Add button

Once you are done filling the fields, click Add to save the port definition in the Port grid located in the bottom section of the tab. All values are editable, so you can change any of them if you're not satisfied with your initial choices.

Remove Selected button

Select a port from the grid to and click Remove Selected to remove it.

Generate Code

The ICENode registration and Evaluate callback code are generated by default. Several check box options are offered to let you generate more code to suit your needs.

BeginEvaluate callback

Generates the skeleton code for the optional BeginEvaluate callback.

EndEvaluate callback

Generates the skeleton code for the optional EndEvaluate callback.

Init callback

Generates the skeleton code for the optional Init callback.

Term callback

Generates the skeleton code for the optional Term callback.

Add Sample Code

Adds extra code to get you started for each function. This includes helpful comments explaining how to code the blocks.

Add Debug Trace

Inserts a call to print the location at the beginning of each function. For example:

    Application().LogMessage(L"MyCustomICENode_EndEvaluate called",siVerboseMsg);

Generate button

The wizard will generate code that looks similar to the following snippet:

    // MyCustomICENode Plugin
    // Initial code generated by Softimage SDK Wizard
    // Executed Wed Feb 13 13:57:32 EST 2008 by amgreen
    //
    //
    // Tip: You need to compile the generated code before you can load the plug-in.
    // After you compile the plug-in, you can load it by clicking Update All in the Plugin Manager.
    #include <xsi_application.h>
    #include <xsi_context.h>
    #include <xsi_pluginregistrar.h>
    #include <xsi_status.h>

    #include <xsi_icenodecontext.h>
    #include <xsi_icenodedef.h>
    #include <xsi_command.h>
    #include <xsi_factory.h>
    #include <xsi_math.h>
    #include <xsi_vector2f.h>
    #include <xsi_vector3f.h>
    #include <xsi_vector4f.h>
    #include <xsi_matrix3f.h>
    #include <xsi_matrix4f.h>
    #include <xsi_rotationf.h>
    #include <xsi_quaternionf.h>
    #include <xsi_color4f.h>
    #include <xsi_shape.h>
    #include <xsi_indexset.h>
    #include <xsi_dataarray.h>
    #include <xsi_dataarray2D.h>

    // Defines port, group and map identifiers used for registering the ICENode
    enum IDs
    {
       ID_IN_InPort = 0,
       ID_IN_InPort2 = 1,
       ID_G_100 = 100,
       ID_OUT_OutPort = 200,
       ID_G_300 = 300,
       ID_TYPE_CNS = 400,
       ID_STRUCT_CNS,
       ID_CTXT_CNS,
       ID_UNDEF = ULONG_MAX
    };

    XSI::CStatus RegisterMyCustomICENode( XSI::PluginRegistrar& in_reg );

    using namespace XSI;

    XSIPLUGINCALLBACK CStatus XSILoadPlugin( PluginRegistrar& in_reg )
    {
       in_reg.PutAuthor(L"amgreen");
       in_reg.PutName(L"MyCustomICENode Plugin");
       in_reg.PutEmail(L"");
       in_reg.PutURL(L"");
       in_reg.PutVersion(1,0);

       RegisterMyCustomICENode( in_reg );

       //RegistrationInsertionPoint - do not remove this line

       return CStatus::OK;
    }

    XSIPLUGINCALLBACK CStatus XSIUnloadPlugin( const PluginRegistrar& in_reg )
    {
       CString strPluginName;
       strPluginName = in_reg.GetName();
       Application().LogMessage(strPluginName + L" has been unloaded.",siVerboseMsg);
       return CStatus::OK;
    }

    CStatus RegisterMyCustomICENode( PluginRegistrar& in_reg )
    {
       ICENodeDef nodeDef;
       nodeDef = Application().GetFactory().CreateICENodeDef(L"MyCustomICENode");

       CStatus st;

       // Add input ports and groups.
       st = nodeDef.AddPortGroup(ID_G_100);
       st.AssertSucceeded( ) ;

       st = nodeDef.AddInputPort(ID_IN_InPort,ID_G_100,siICENodeDataFloat,siICENodeStructureSingle,siICENodeContextAny,L"InPort",L"InPort",1.0f,ID_UNDEF,ID_STRUCT_CNS,ID_CTXT_CNS);
       st.AssertSucceeded( ) ;

       st = nodeDef.AddInputPort(ID_IN_InPort2,ID_G_100,siICENodeDataFloat,siICENodeStructureArray,siICENodeContextAny,L"InPort2",L"InPort2",1.0f,ID_UNDEF,ID_UNDEF,ID_CTXT_CNS);
       st.AssertSucceeded( ) ;

       // Add output ports and groups.
       st = nodeDef.AddPortGroup(ID_G_300);
       st.AssertSucceeded( ) ;

       st = nodeDef.AddOutputPort(ID_OUT_OutPort,ID_G_300,siICENodeDataFloat,siICENodeStructureSingle,siICENodeContextAny,L"OutPort",L"OutPort",ID_UNDEF,ID_UNDEF,ID_CTXT_CNS);
       st.AssertSucceeded( ) ;

       PluginItem nodeItem = in_reg.RegisterICENode(nodeDef);
       nodeItem.PutCategories(L"Custom ICENode");

       return CStatus::OK;
    }

    XSIPLUGINCALLBACK CStatus MyCustomICENode_Evaluate( ICENodeContext& in_ctxt )
    {
       // The current output port being evaluated...
       ULONG out_portID = in_ctxt.GetEvaluatedOutputPortID( );

       switch( out_portID )
       {
           case ID_OUT_OutPort:
           {
              // Get the output port array ...
              CDataArrayFloat outData( in_ctxt );

              // Get the input data buffers for each port
              CDataArrayFloat InPortData( in_ctxt, ID_IN_InPort );
              CDataArray2DFloat InPort2Data( in_ctxt, ID_IN_InPort2 );

              // We need a CIndexSet to iterate over the data
              CIndexSet indexSet( in_ctxt );
              for(CIndexSet::Iterator it = indexSet.Begin(); it.HasNext(); it.Next())
              {
                  Application().LogMessage( CString( InPortData[it] ) );

                  CDataArray2DFloat::Accessor InPort2SubArray = InPort2Data[it];

                  for (ULONG i=0; i<InPort2SubArray.GetCount( ); i++)
                  {
                     Application().LogMessage( CString( InPort2SubArray[i] ) );
                  }

                  // Set the output data buffer, etc...
              }
           }
           break;

           // Other output ports...

       };

       return CStatus::OK;
    }

Customizing Icons for Custom ICENodes

In the Preset Manager, each custom ICENode appears with the default node icon ( ), but you can specify your own thumbnail to use:

1. Add a new Thumbnails subfolder to the directory where your custom node library is installed (for example, <userpath>/Application/Plugins/ABCPlugin).

2. Drop the file(s) you want to use for a thumbnail in that folder:

You can use the usual graphics file formats (BMP, JPG, GIF, PNG, PIC, etc.) without having to convert or resize them.

3. Make sure the filename matches the name of the plug-in or plug-in item exactly (capitalization, spaces, etc.). You can set one thumbnail for the entire plug-in or individual thumbnails for each plug-in item.

| Softimage tries to match the graphic to each plug-in item and if not found, then looks for a plug-in to match instead.

Autodesk Softimage v7.5