Scrittura di un Plugin di Sequenza [Sequence Plugin]

A partire da Blender v2.31

In questa sezione si scriverà un plugin di sequenza elementare e quindi si percorreranno i passi per usare un plugin di sequenza. Le basi dietro un plugin di sequenza sono degli input: da 1 a 3buffer di immagini in ingresso così come qualche altra informazione e restituisce il buffer dell'immagine risultante.

Tutti i file necessari allo sviluppo dei plugin così come un paio di plugin di esempio si trovano nella directory blender/plugins. In alternativa si possono prendere un bel po' di plugin da http://www.cs.umn.edu/~mein/blender/plugins

Specifiche:

A partire da Blender v2.31

Struttura immagine ImBuf

La struttura ImBuf contiene sempre 32 bit RGBA di dati sul pixel.

La struttura ImBuf ha sempre le dimensioni uguali, indicate valori passati di x e y.

Interazione con l'Utente

Non c'è modo per blender di sapere quanti input si aspetta un plugin, così è possibile per un utente includere solo un input ad un plugin che ne aspetta due. Per questa ragione è importante verificare sempre i buffer che usa il plugin per essere sicuri che siano sempre validi. I plugin di sequenza dovrebbero includere anche un'etichetta di testo con la descrizione degli input richiesti nell'interfaccia dei pulsanti.

Plugin di Sequenza Generico:

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

/* struttura per i pulsanti,
 * codice pulsante nome default min max 0
 */

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


/* La struttura cast è per l'input nella funzione principale doit
 Varstr e Cast devono avere le stesse variabili nello stesso ordine */

typedef struct Cast {
 int dummy; /* a causa del pulsante 'label' */
} Cast;

/* cfra: il frame corrente */

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;

} 

Le nostre Modifiche:

Il primo passo inizia col progetto di un gioco. Cosa deve fare questo plugin, come l'utente deve interagire con esso. Per questo esempio si creerà una semplice filtro che avrà uno slider per l'intensità da 0 a 255. Se ciascuna delle componenti R,G, e B di un pixel nell'immagine sorgente è inferiore all'intensità scelta, ritornerà nero ed alfa, altrimenti tornerà quello che era nell'immagine. Ora si copierà il plugin generico in simpfilt.c e si faranno le aggiunte.

Aggiungere dei commenti è sempre una buona idea. Prima si dice agli utenti cosa fa il plugin, dove si può prenderne una copia, chi contattare per modifiche/bug, e qualsiasi limitazione di licenza del codice. Quando si usano commenti ci si assicuri di usare lo stile /* */. I plugin sono in C e qualche compilatore C non accetta lo stile //.

/*
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
*/
    

Successivamente si inserisce il nome [Name], in realtà dovrebbe essere lo stesso del file .c. Preferibilmente descrittivo, con meno di 23 caratteri, senza spazi e tutto in minuscolo.

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

Cast e varstr devono essere sincronizzate. Si vuole un solo slider quindi si fa ciò che segue:

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;                      /* per il pulsante 'label' */
        int intensity;
} Cast;

Ora si deve riempire plugin_seq_doit. Fondamentalmente si vuol fare un loop per ciascun pixel e se RGB sono inferiori dell'intensità imposta l'output a: 0,0,0,255 altrimenti lo imposta al valore dell'input per quella posizione.

   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];
         }
      }
   }

    

Quindi si deve concludere con simpfilt.c

Compilazione:

bmake è una semplice utility (uno script shell) di aiuto alla compilazione e sviluppo dei plugin e la si può trovare nella sub-directory plugins/ della directory di installazione di Blender. Viene richiamato con: bmake (plugin_name.c) e proverà a linkare le librerie giuste e compilare il file C indicato in modo appropriato al proprio sistema. Se si prova a sviluppare dei plugin su una macchina Windows, bmake potrebbe non funzionare. Nel qual caso si deve vedere di usare lcc. Per compilare un plugin con lcc si può usare: Si assume che si abbiano i plugin c:\blender\plugins. Qui c'è un esempio di come si dovrebbe compilare il plugin di texture sweep.c. Si apre una finestra dos e si digita: (Nota: Ci si dovrà assicurare che nel path ci sia la directory lcc\bin)

 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