Sophie

Sophie

distrib > Arklinux > devel > i586 > media > main > by-pkgid > 2c46997be5021ee3173c5af9332905d7 > files > 875

blender-manual-2.49a-1ark.i586.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML
><HEAD
><TITLE
>Writing a Sequence Plugin</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+
"><LINK
REL="HOME"
TITLE="Blender Documentation Volume I - User Guide"
HREF="book1.html"><LINK
REL="UP"
TITLE="Blender's Plugins System"
HREF="c10609.html"><LINK
REL="PREVIOUS"
TITLE="Compiling:"
HREF="x10808.html"><LINK
REL="NEXT"
TITLE="Beyond Blender"
HREF="p10940.html"></HEAD
><BODY
CLASS="section"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Blender Documentation Volume I - User Guide: Last modified April 29 2004 S68</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x10808.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Blender's Plugins System</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="p10940.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="section"
><H1
CLASS="section"
><A
NAME="section_plugin_sequence"
></A
>Writing a Sequence Plugin</H1
><P
>&#13;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. 
    </P
><P
>&#13;
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 <A
HREF="http://www.cs.umn.edu/%7Emein/blender/plugins"
TARGET="_top"
>&#13;http://www.cs.umn.edu/~mein/blender/plugins</A
>
    </P
><DIV
CLASS="section"
><H2
CLASS="section"
><A
NAME="section_plugin_sequence_specs"
></A
>Specification:</H2
><P
></P
><UL
><LI
><P
>&#13;          <I
CLASS="emphasis"
>#include &#60;plugin.h&#62;</I
>
        </P
><P
>&#13;  Every Blender plugin should include this header
 file, which contains all of the structures and
 defines needed to properly work with Blender.
        </P
></LI
><LI
><P
>&#13;          <I
CLASS="emphasis"
>char name[]="Blur";</I
>
        </P
><P
>&#13;  A character string containing the plugin name,
 this value will be displayed for the texture's title
 in the Texture Buttons window. 
        </P
></LI
><LI
><P
>&#13;          <I
CLASS="emphasis"
>VarStruct varstr[]= {...};</I
>
        </P
><P
>&#13; The varstr contains all of the information
 Blender needs to display buttons for a plugin.
 Buttons for plugins can be numerical for
 input data, or text for comments and other
 information. Plugins are limited to a maximum
 of 32 variables. 
        </P
><P
>&#13;Each VarStruct entry consists of a type, name,
 range information, and a tool tip. 
        </P
><P
>&#13;          <I
CLASS="emphasis"
>The type</I
> defines the data type for each button
 entry, and the way to display the button. For number 
 buttons this value should be a combination (ORed) of INT
 or FLO for the number format, and NUM, NUMSLI, or
 TOG, for the button type. Text buttons should have
 a type of LABEL. 
        </P
><P
>&#13;          <I
CLASS="emphasis"
>The name</I
> is what will be 
 displayed on (or beside)
 the button. This is limited to 15 characters. 
        </P
><P
>&#13;          <I
CLASS="emphasis"
>The range information</I
> consists of three floats
 that define the default, minimum, and maximum values
 for the button. For TOG buttons the minimum is
 set in the pressed state, and the maximum is set
 in the depressed state. 
        </P
><P
>&#13;          <I
CLASS="emphasis"
>The tip</I
> is a string that will be displayed 
 when the mouse is over this button (if the user has 
 tool tips on). This has a limit of 80 characters, and 
 should be set to the NULL string ("") if unused.
        </P
></LI
><LI
><P
>&#13;          <I
CLASS="emphasis"
>typedef struct Cast {...};</I
>
        </P
><P
>&#13; The cast structure is used in calling the
 doit function, and serves as a way to simply
 access each plugin's data values. 
        </P
><P
>&#13;The cast should contain, in order, an integer
 or float for every button defined in the varstr,
 including text buttons. Typically these should
 have the same name as the button for simple
 reference.
        </P
></LI
><LI
><P
>&#13;          <I
CLASS="emphasis"
>float cfra</I
>
        </P
><P
>&#13; The cfra value is set by Blender to the current
 from before every render pass. This value is
 an the frame number +/- .5 depending on the field
 settings.
        </P
></LI
><LI
><P
>&#13;          <I
CLASS="emphasis"
>plugin_seq_doit prototype</I
>
        </P
><P
>&#13; The plugin_seq_doit function should be prototyped
 for use by the getinfo function. You do not need
 to change this line.
        </P
></LI
><LI
><P
>&#13;          <I
CLASS="emphasis"
>plugin_seq_getversion</I
>
        </P
><P
>&#13; This function must be in each plugin for it
 to be loaded correctly. You should not change
 this function.
        </P
></LI
><LI
><P
>&#13;          <I
CLASS="emphasis"
>plugin_but_changed</I
>
        </P
><P
>&#13; This function is used to pass information
 about what buttons the user changes in
 the interface. Most plugins should not need
 to use this function, only when the interface
 allows the user to alter some variable
 that forces the plugin to do recalculation
 (a random hash table for example).
        </P
></LI
><LI
><P
>&#13;          <I
CLASS="emphasis"
>plugin_init</I
>
        </P
><P
>&#13; If needed plugins may use this function
 to initialize internal data. NOTE: This init
 function can be called multiple times if the same
 plugin texture is copied. Do not init global data
 specific to a single instance of a plugin in this
 function.
        </P
></LI
><LI
><P
>&#13;          <I
CLASS="emphasis"
>plugin_getinfo</I
>
        </P
><P
>&#13; This function is used to communicate information to
 Blender. You should never need to change it. 
        </P
></LI
><LI
><P
>&#13;          <I
CLASS="emphasis"
>plugin_seq_doit</I
>
        </P
><P
>&#13; The sequence doit function is responsible for
 applying the plugin's effect and copying the
 final data into the out buffer.
        </P
><P
>&#13;          <I
CLASS="emphasis"
>The Arguments</I
>
        </P
><P
></P
><UL
><LI
><P
>&#13;              <I
CLASS="emphasis"
>Cast *cast</I
>
            </P
><P
>&#13; 
 The Cast structure which contains the plugin
 data, see the <I
CLASS="emphasis"
>Cast</I
> entry above.
            </P
></LI
><LI
><P
>&#13;              <I
CLASS="emphasis"
>float facf0</I
>
            </P
><P
>&#13; The value of the plugin's IPO curve for
 the first field offset. If the user hasn't
 made an IPO curve this ranges between 0 and
 1 for the duration of the plugin.
            </P
></LI
><LI
><P
>&#13;              <I
CLASS="emphasis"
>float facf1</I
>
            </P
><P
>&#13; The value of the plugin's IPO curve for
 the second field offset. If the user hasn't
 made an IPO curve this ranges between 0 and
 1 for the duration of the plugin.
            </P
></LI
><LI
><P
>&#13;              <I
CLASS="emphasis"
>int x
int y</I
>
            </P
><P
>&#13; The width and height of the image buffers,
 respectively.
            </P
></LI
><LI
><P
>&#13;              <I
CLASS="emphasis"
>Imbuf *ibuf1</I
>
            </P
><P
>&#13; A pointer to the first image buffer the
 plugin is linked to. This will always be
 a valid image buffer.
            </P
></LI
><LI
><P
>&#13;              <I
CLASS="emphasis"
>Imbuf *ibuf2</I
>
            </P
><P
>&#13; A pointer to the second image buffer the
 plugin is linked to. Plugins using this
 buffer should check for a NULL buffer,
 as the user may not have attached the
 plugin to two buffers.
            </P
></LI
><LI
><P
>&#13;              <I
CLASS="emphasis"
>Imbuf *out</I
>
            </P
><P
>&#13;  The image buffer for the plugin's output.
            </P
></LI
><LI
><P
>&#13;              <I
CLASS="emphasis"
>Imbuf *use</I
>
            </P
><P
>&#13;  A pointer to the third image buffer the
 plugin is linked to. Plugins using this
 buffer should check for a NULL buffer,
 as the user may not have attached the
 plugin to three buffers.
            </P
></LI
></UL
></LI
></UL
><P
>&#13;      <I
CLASS="emphasis"
>ImBuf image structure</I
>
    </P
><P
>&#13; The ImBuf structure always contains 32 bits ABGR pixel data.
    </P
><P
>&#13; ImBuf structs are always equal in size, indicated by the 
 passed <I
CLASS="emphasis"
>x</I
> and <I
CLASS="emphasis"
>y</I
> value. 
    </P
><P
>&#13;      <I
CLASS="emphasis"
>User Interaction</I
>
    </P
><P
>&#13; 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. 
    </P
></DIV
><DIV
CLASS="section"
><H2
CLASS="section"
><A
NAME="section_plugin_sequence_ex1"
></A
>Generic Sequence Plugin:</H2
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="programlisting"
>#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-&#62;name= name;
 info-&#62;nvars= sizeof(varstr)/sizeof(VarStruct);
 info-&#62;cfra= &#38;cfra;

 info-&#62;varstr= varstr;

 info-&#62;init= plugin_init;
 info-&#62;seq_doit= (SeqDoit) plugin_seq_doit;
 info-&#62;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-&#62;rect;
 char *out=(char *)outbuf-&#62;rect;

} </PRE
></TD
></TR
></TABLE
></DIV
><DIV
CLASS="section"
><H2
CLASS="section"
><A
NAME="section_plugin_sequence_ex2"
></A
>Our Modifications:</H2
><P
>&#13;
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. 
    </P
><P
>&#13;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. <TT
CLASS="literal"
></TT
>
    </P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="screen"
>/*
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
*/
    </PRE
></TD
></TR
></TABLE
><P
>&#13;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. <TT
CLASS="literal"
></TT
>
    </P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="screen"
>char name[24]= "simpfilt.c";

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

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-&#62;intensity) &#38;&#38;
             (in1[1] &#62; cast-&#62;intensity) &#38;&#38;
	     (in1[2] &#62; cast-&#62;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];
         }
      }
   }

    </PRE
></TD
></TR
></TABLE
><P
>&#13;
So we wind up with simpfilt.c
    </P
></DIV
><DIV
CLASS="section"
><H2
CLASS="section"
><A
NAME="section_plugin_sequence_compile"
></A
>Compiling:</H2
><P
>&#13;
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) <TT
CLASS="literal"
></TT
>
    </P
><P
>&#13;    </P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="screen"
> 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
    </PRE
></TD
></TR
></TABLE
></DIV
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x10808.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="p10940.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Compiling:</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="c10609.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Beyond Blender</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>