Writing a Sequence Plugin

Relevant to Blender v2.31

In this Section we will write a basic sequence plugin and then go through the steps use a sequence plugin. The basics behind a sequence plugin are you are given some inputs; 1-3 input image buffers as well as some other information and you output a resulting image buffer.

All the files necessary to develop plugins as well as a few sample plugins can be found in the blender/plugins directory. You can alternately get a bunch of plugins from http://www.cs.umn.edu/~mein/blender/plugins

Specification:

Relevant to Blender v2.31

ImBuf image structure

The ImBuf structure always contains 32 bits ABGR pixel data.

ImBuf structs are always equal in size, indicated by the passed x and y value.

User Interaction

There is no way for Blender to know how many inputs a plugin expects, so it is possible for a user to attach only one input to a plugin that expects two. For this reason it is important to always check the buffers your plugin uses to make sure they are all valid. Sequence plugins should also include a text label describing the number of inputs required in the buttons interface.

Generic Sequence Plugin:

#include "plugin.h"
char name[24]= "";

/* structure for buttons,
 * butcode name default min max 0
 */

VarStruct varstr[]= {
 { LABEL, "In: X strips", 0.0, 0.0, 0.0, ""},
};


/* The cast struct is for input in the main doit function
 Varstr and Cast must have the same variables in the same order */

typedef struct Cast {
 int dummy; /* because of the 'label' button */
} Cast;

/* cfra: the current frame */

float cfra;

void plugin_seq_doit(Cast *, float, float, int, int,
 ImBuf *, ImBuf *, ImBuf *, ImBuf *);

int plugin_seq_getversion(void) {
 return B_PLUGIN_VERSION;
}

void plugin_but_changed(int but) {
}

void plugin_init() {
}

void plugin_getinfo(PluginInfo *info) {
 info->name= name;
 info->nvars= sizeof(varstr)/sizeof(VarStruct);
 info->cfra= &cfra;

 info->varstr= varstr;

 info->init= plugin_init;
 info->seq_doit= (SeqDoit) plugin_seq_doit;
 info->callback= plugin_but_changed;
}

void plugin_seq_doit(Cast *cast, float facf0, float facf1, int xo, int yo,
 ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *outbuf, ImBuf *use) {
 char *in1= (char *)ibuf1->rect;
 char *out=(char *)outbuf->rect;

} 

Our Modifications:

The first step is to come up with a game plan. What is this plugin going to do, how are the users going to interact with it. For this example we will create a simple filter that will have a slider for intensity from 0-255. If any of the R,G, or B components of a pixel in the source image are less then our chosen intensity, it will return black and alpha, otherwise it will return whatever is in the image. Now we'll copy our generic plugin to simpfilt.c and will fill in the gaps.

Its always a good idea to add some comments. First off tell users what the plugin does, where they can get a copy, who they should contact for bugs/improvments, and any licensing restrictions on the code. When using comments make sure you use /* */ style comments. The plugins are in c and some c compilers do not accept // style comments.

/*
Description: This plugin is a sample sequence plugin that filters out lower
intensity pixels.  I works on one strip as input.
Author: Kent Mein (mein@cs.umn.edu)
Website: http://www.cs.umn.edu/~mein/blender/plugins
Licensing: Public Domain
Last Modified: Sun Sep  7 23:41:35 CDT 2003
*/
    

Next we need to fill in the Name, you should really keep this the same as your .c file. Preferably descriptive, less than 23 chars, no spaces, and all lowercase.

char name[24]= "simpfilt.c";

The Cast and varstr need to be in sync. We want one slider so we'll do the following:


varStruct varstr[]= {
   { LABEL,     "In: 1 strips", 0.0, 0.0, 0.0, ""},
   { NUM|INT,     "Intensity", 10.0, 0.0, 255.0, "Our threshold value"},
};

typedef struct Cast {
        int dummy;                      /* because of the 'label' button */
	int intensity;
} Cast;

Now we need to fill in plugin_seq_doit. We basically want to loop through each pixel and if RGB are all less than intensity set the output pixel to: 0,0,0,255 else set it to the input values for that position.


   int x,y;

   for(y=0;y cast->intensity) &&
             (in1[1] > cast->intensity) &&
	     (in1[2] > cast->intensity)) {
            out[0] = out[1] = out[2] = 0;
            out[3] = 255;
         } else {
            out[0] = in1[0];
            out[1] = in1[1];
            out[2] = in1[2];
            out[3] = in1[3];
         }
      }
   }

    

So we wind up with simpfilt.c

Compiling:

bmake is a simple utility (shell script) to aid in the compilation and development of plugins, and can be found in the plugins/ sub-directory of the Blender installation directory. It is invoked by: bmake (plugin_name.c) and will attempt to link the proper libraries and compile the specified C file properly for your system. If you are trying to develop plugins on a windows machine, bmake may not work for you. In that case you should look into using lcc. You can use the following to compile a plugin with lcc: Assuming you have your plugins in c:\blender\plugins. Here is an example of how you would compile the sequence plugin sweep.c Open a dos prompt and do the following: (Note: You'll want to make sure the lcc\bin directory is in your path).

 cd c:\blender\plugins\sequence\sweep
 lcc -Ic:\blender\plugins\include sweep.c
 lcclnk -DLL sweep.obj c:\blender\plugins\include\seq.def
 implib sweep.dll