Introduction to RAYZ Plugins

The RAYZ API is as wide open as it is possible for us to make it. It is our intention that sophisticated users be able to use RAYZ as a platform for all kinds of image-related tasks, not just for compositing.

To that end, users can write plugins that are:

In addition, overlays can be attached to user-built nodes, or even to existing RAYZ nodes, to add interactive functionality.

Programmers can also build up complex node operations by chaining together internal RAYZ Image Operations - for example, a plugin which requires image scaling and rotation can use the internal routines for scaling and rotating its input, allowing the programmer to spend time on the parts of the plugin which are unique and interesting.

Finally, RAYZ plugins can read values from, and write values to, the user Preferences. And the plugins can create new Preferences for users to have access to, in order to completely customize RAYZ.

We hope the enclosed documentation and examples will allow you to push RAYZ to do the things you need; help is always available at support@sgrail.com.

If you have existing RAYZ plugins written for 1.0, you will have to modify and recompile them - the next section discusses the changes necessary.

Have fun.


Changes From RAYZ 2.0 to RAYZ 2.2

The plugin spec for RAYZ 2.2 has been enhanced to provide many more capabilities, such as interactive overlay creation, toolbars, and the ability to pass arbitrary blocks of data between a node and its image processing routine (IM).

In order to take advantage of these improvements, all 2.0 plugins will need to be recompiled, and most will also need to be edited at least slightly. Fortunately, in most cases these changes amount to mostly boilerplate cut & paste editing.

The major changes are noted here.

Node Parameter Handling / Metadata

Metadata as a mechanism for passing parameters from the Node to the IM has gone. Instead, there is a more generalized method of passing arbitrary data structures to the IM. There are two new calls for this, which are:
CPI_PrivateData  cpiCreatePrivateData( const char *opName );

CPI_Bool  cpiDestroyPrivateData( CPI_PrivateData data );
A quick example of how this works follows.

First, define the collection of parameters that you want to use:

typedef struct _gridState
{
    CPI_Int32    size[2];
    CPI_Int32    channels;
    CPI_Int32    bitdepth;
    CPI_Int32    lineWidth[2];
    CPI_Int32    lineGap[2];
    CPI_Float32  bgColor[4];
    CPI_Float32  lineColor[4];
} gridState;
Then, in the Exec routine, allocate one of these structures and fill it with parameters from the user.
static CPI_ImageOp
GridExec( CPI_PrivateData    handle,
          CPI_Float32        myTime,
          CPI_Uint8          quality,
          CPI_Uint32         nodeOutput,
          CPI_Bool           viewerOutput,
          CPI_Float32        scaleX,
          CPI_Float32        scaleY )
}
    <snip>

    // Allocate a parameter structure
    opData      = cpiCreatePrivateData( "grid" );
    gridData    = (gridState *)opData;

    if ( NULL != gridData )
        {
            // Get the user parameters and fill in the structure fields
            if ( cpiGetInteger( &gridData->size[0], "size.w", myTime ) &&
                 cpiGetInteger( &gridData->size[1], "size.h", myTime ) &&
                 cpiGetInteger( &channels, "chans", myTime ) &&
                 cpiGetInteger( &bitdepth, "bits", myTime) &&

                 etc
Next, you have to define the functions that allocate and deallocate the memory for the parameters. This is new code that was not present in 2.0.
// Allocate the storage
static CPI_PrivateData
GridCreateOpInstance( void )
{
    gridState *retval = (gridState *)cpiAlloc( sizeof( gridState ) );

    return (CPI_PrivateData)retval;
}

// Give back the storage when the node is destroyed
static CPI_Bool
GridDestroyOpInstance( CPI_PrivateData   handle )
{
    CPI_Bool     retval = CPI_FALSE;
    gridState   *state  = (gridState *)handle;

    if ( NULL != state )
    {
        cpiFree( state );
        retval = CPI_TRUE;
    }

    return retval;
}
Finally, you have to register these new functions in the ImageOpInfo structure, which now looks like this:
static RPI_ImageOpInfo opinfo =
{
    {
        "grid",             // op name
        "",                 // not used
        "Silicon Grail",    // author
        "1.0"               // version
    },
    GridCreateOpInstance,   // create op instance
    GridDestroyOpInstance,  // destroy op instance
    GridProcess,            // image execution process
    NULL,                   // InputRegion
    GridOutputRegion,       // output region
    NULL,                   // control processing
    NULL,                   // setup processing
    NULL,                   // cleanup processing
    0,                      // min inputs
    CPI_FALSE,              // does it multiproc?
    CPI_FALSE               // handle disjoint regions?
};

This also means that functions that took a metadata object containing parameters about your operation, now take a pointer to the parameter structure. For example, the ProcessImage function used to look like this:
static CPI_Bool
GridProcess( CPI_Image   *result,
             CPI_Image    inputs[],
             CPI_Uint32   numInputs,
             CPI_Metadata myParms )
{
This has now become
static CPI_Bool
GridProcess( CPI_PrivateData     handle,
             CPI_Image          *result,
             CPI_Image           inputs[],
             CPI_Uint32          numInputs )
{

 

New Node Functions

There are two new node functions you can register in the NodeInfo structure. These are NodeInputAdded() and NodeInputRemoved(); they allow you to provide a function to handle these particular cases. The signatures are:
void NodeInputAdded( CPI_PrivateData   handle,
                     CPI_Uint32        inputnum )

void NodeInputRemoved( CPI_PrivateData   handle,
                       CPI_Uint32        inputnum )

 

Overlays

Overlays can now have toolbars. There are new routines for creating and managing toolbars, which are:
void cpiStartToolbar( void );

void cpiEndToolbar( const char  *name,
                    const char  *desc,
                    CPI_Uint32   defAlignment,
                    CPI_Bool     allowHorizontal,
                    CPI_Bool     allowVertical );
The possible alignment values are
CPI_WINDOW_TOP
CPI_WINDOW_BOTTOM
CPI_WINDOW_LEFT
CPI_WINDOW_RIGHT
There is also a new function to register in the OverlayInfo structure, OverlayParmChanged(). The signature of this is
void OverlayParmChanged( CPI_PrivateData   handle,
                         const char       *parmname );
This allows a callback from the overlay.

There are also new overlay routines which allow you to get access to the image under the overlay, either before or after it has been processed by the node. This is useful for picking colors, for example:

CPI_Bool  cpiGetSourceImage( CPI_Uint32    buffer,
                             CPI_Image    *image );

CPI_Bool  cpiGetConvertedImage( CPI_Uint32     buffer,
                                CPI_Image     *image );

And of course, if picking is what you want to do, then you need a way to get the color under the cursor:
void  *cpiGetPixel( CPI_Image *image,
                    CPI_Int32  x,
                    CPI_Int32  y );

 

Node Parameters

There are several new widgets available for the node panel parameter area. These are:
Button Strip      - such as the RGBA button strip that all nodes have
Icon Toggle       - a toggle with an icon
Icon Button       - a button with an icon
Icon Button Strip - a button strip with icons for each button
Also, the signatures for some functions have changed, such as button callbacks and the Exec function itself.

Finally, there is a new parameter type, Binary, which allows a node to create (and save) arbitrary binary data. This is for nodes which need to save and restore large amounts of state information, such as some keyers. This parameter is not visible to the user; it is internal to the plugin.

 

Lookup Table Functions

Two of the LUT functions have changed signatures slightly; they now also come in with a pointer to the local private data, to make access to a LUT easier. The calls
LUTConfidence( CPI_ImageContext context )
PUTParmChanged( const char *parmname )
have now become
LUTConfidence( CPI_PrivateData  handle,
               CPI_ImageContext context )

PUTParmChanged(  CPI_PrivateData  handle,
                 const char *parmname )

 

Utility Functions

There are some new utility functions:

Routines for getting and setting the time.

CPI_Bool  cpiSetImageViewerTime( CPI_Float32 curTime );

CPI_Float32  cpiGetImageViewerTime( void );

CPI_Bool  cpiGetFlipbookRange( CPI_Float32 *start,
                               CPI_Float32 *end );
Routines for creating, executing, and handling the results of separate, user-driven execution lists. These are used in a new example node, Stats.C.
CPI_ImageOp  cpiCreateNewExecList( void );

CPI_Bool  cpiStartExecution( CPI_ExecCallBackFn cbFunc,
                              CPI_PrivateData    pData,
                              CPI_ImageOp        last );

void (*CPI_ExecCallBackFn)( CPI_Image        *result,
                            CPI_PrivateData   caller,
                            CPI_PrivateData   opData[],
                            CPI_Uint32        num,
                            CPI_Float32       time );

[Previous Page] [Next Page]
[Table of Contents] [Index]

Copyright © 2002 Silicon Grail Inc.
736 Seward Street, Hollywood, CA 90038