From BlenderWiki

Jump to: navigation, search
Blender3D FreeTip.gif
IMPORTANT! Do not update this page!
We have moved the Blender User Manual to a new location. Please do not update this page, as it will be locked soon.

Escrevendo um Plugin para Sequenciador

Nesta seção, nós iremos escrever um Plugin básico para o Sequenciador e então navegar através dos passos para a utilização de um Plugin para o Sequenciador.

O conhecimento básico necessário por trás de um Plugin de Sequenciador é que você terá como entradas, de 1 a 3 Buffers de Imagem, tanto quanto algumas outras informações, e você terá como resultado uma saída de Buffer de Imagem.

Manter a informação de partes do Manual ”No estado”
Como esta parte do Manual explica procedimentos avançados do Blender através de configuração e programação Interna, decidi manter os Códigos em C sem tradução parcial ou completa, incluindo os seus comentários. É desejável que o leitor que se aventure na área de programação possua um mínimo de conhecimento do Inglês para que possa se guiar através de manuais de programação, e para que possa compreender os comandos de maneira adequada
→ Ivan Paulos Tomé – Greylica


Todos os arquivos necessários para o desenvolvimento de Plugins como também alguns Plugins de exemplo podem ser encontrados no diretório de Plugins do Blender, localizado em blender/plugins directory. Você pode alternativamente baixar um monte de Plugins a partir deste repositório.

Especificação

#include <plugin.h>
Cada Plugin do Blender deverá possuir este arquivo de cabeçalho, que contém todas as estruturas necessárias para que o Plugin funciona apropriadamente com o Blender.
char name[]="Blur";
Uma "string" (variável de amarração) que contém o nome do Plugin.
VarStruct varstr[]= {...};
A estrutura “varstr” contém toda a informação que o Blender necessita para mostrar os Botões para um Plugin. Os Botões para os Plugins podem ser numéricos para a entrada de dados, ou Texto para comentários e outras informações. Os plugins são limitados para um máximo de 32 variáveis. Cada entrada da estrutura “VarStruct” consiste de "type" (tipo), "name" (nome), "range" (campo de abrangência) e uma "tool tip" (dica de ferramenta).
type
Define os tipos de dados para cada entrada de botão, e maneira que o botão será mostrado .
Para botões numéricos, este valor deverá ser uma combinação (O Binário “OR”, “|”) de “INT” ou “FLO” para o formato numérico (inteiro ou de ponto flutuante), e “NUM”, “NUMSLI”, ou “TOG”, para tipo de botão (numérico, numérico com deslizador, ou de alternância).
Botões de Texto deverá possuir um tipo de rótulo, através da String “LABEL”.
name
É o que será mostrado no botão (ou ao lado dele). Isto é limitado a 15 caracteres.
range information
Consiste de três variáveis de ponto flutuante que definem os valores "default, minimum, and maximum" (padrão, mínimo e máximo) para o botão. Para os botões de alternância TOG, o mínimo é configurado para o estado “pressionado”, e o máximo é configurado para o estado “não pressionado” do botão .
tooltip
É uma "string" (variável de amarração) que será mostrada quando o Mouse estiver passando pelo botão (caso o usuário tenha a opção de Tool Tips habilitada). Isto possui um limite de 80 caracteres, e deverá ser configurado para nulo (NULL) ("") caso não seja utilizado.
typedef struct Cast {...};
A estrutura Cast é utilizada quando estiver chamando a função doit e serve como uma maneira de simplesmente acessar os dados de valor de cada Plugin. A estrutura “cast” deverá conter, em ordem, um número inteiro ou flutuante para cada botão definido na variável “varstr”, incluindo os botões de texto. Tipicamente, estes deverão possuir o mesmo nome que o botão para simples referência.
float cfra
O valor de cfra é configurado pelo Blender para o quadro corrente antes de cada passo de renderização. Este valor é o número do "frame" (quadro) (± 0.5 dependendo de configurações de entrelaçamento (renderizações com field)).
plugin_seq_doit prototype
A função plugin_seq_doit deverá ser prototipada para ser utilizada pela função getinfo . Você não precisa alterar esta linha.
plugin_seq_getversion
Esta função deverá estar em cada Plugin para que este seja carregado corretamente. Você não deve alterar esta função.
plugin_but_changed
Esta função é utilizada para passar informação sobre quais botões o usuário modou dentro da Interface. A maioria dos Plugins não necessita utilizar esta função, somente quando a Interface permite o usuário que altere algumas variáveis que forçam o Plugin a fazer um recálculo (uma tabela randômica picada, por exemplo (random hash table)).
plugin_init
Caso necessário, os Plugins podem utilizar esta função para inicializar os dados Internos.
Nota: Esta função de inicialização pode ser chamada múltiplas vezes caso o mesmo Plugin de textura seja copiado. Não inicie "Global Data" (Dados Globais) específicos de uma instância única de um Plugin nesta função.
plugin_getinfo
Esta função é utilizada para comunicar informação para o Blender. Você nunca precisará alterá-la.
plugin_seq_doit
A função de Plugin de Sequenciador doit é responsável pela aplicação do efeito do Plugin e pela cópia dos dados finais para dentro do Buffer de saída.
The Arguments
Cast *cast
A estrutura Cast que contém os dados do Plugin, veja as entradas acima sobre typedef struct Cast.
float facf0
O valor da Curva IPO do Plugin para o primeiro deslocamento de campo (field). Caso o usuário não tenha feito uma curva IPO, este campo varia entre 0 e 1 para a duração do Plugin.
float facf1
O Valor da curva IPO do Plugin para o deslocamento do segundo campo (field) . Caso o usuário não tenha feito uma curva IPO, este campo varia entre 0 e 1 para a duração do Plugin.
int x, int y
O comprimento e altura dos Buffers de Imagem, respectivamente .
Imbuf *ibuf1
Um ponteiro para o primeiro Buffer de Imagem ao qual o Plugin está ligado. Isto será sempre um Buffer de Imagem válido.
Imbuf *ibuf2
Um ponteiro para o segundo Buffer de Imagem ao qual o Plugin está ligado. Os Plugins que utilizam este Buffer deverão checar por um Buffer do tipo Nulo NULL , pelo fato do usuário não poder ter ligado o mesmo Plugin a dois Buffers.
Imbuf *out
O Buffer de Imagem para a Saída do Plugin.
Imbuf *use
Um ponteiro para o terceiro Buffer de Imagem ao qual o Plugin está ligado. Os Plugins que utilizam este Buffer deverão checar por um Buffer do tipo Nulo NULL, pelo fato do usuário não poder ter ligado o mesmo Plugin a três Buffers.
ImBuf image structure
A estrutura ImBuf sempre contém dados de Pixels em formato de 32 bits RGBA. As estruturas ImBuf são sempre iguais em seu tamanho, indicadas pelos valores x e y.
"User Interaction" (Interação com o Usuário)
Não há uma maneira do Blender saber quantas entradas o Plugin espera para poder funcionar, então é possível que um usuário conecte somente uma entrada para um Plugin que requer duas. Pos esta razão, é sempre importante checar os Buffers que seu Plugin utilizar para ter certeza de que todos eles são válidos. Os Plugins para sequenciador deverão sempre incluir um "label" (rótulo) de texto descrevendo o número de entradas requeridas dentro dos botões de Interface.


Plugin Genérico para o Sequenciador

#include "plugin.h"
 
char name[24]= "";
 
/* structure for buttons,
 *	{butcode, name,       default, min, max, tooltip}
 */
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;
}


Nossas Modificações

O Primeiro passo é ter um diagrama ou um plano de ação. O que este Plugin irá fazer, como os usuários irão interagir com ele. Para este exemplo, nós criaremos um simples filtro que irá possuir um deslizador para uma intensidade que vai de 0-255. Caso quaisquer dos componentes R,G, ou B de um Pixel dentro da Imagem de entrada forem menores do que a nossa Intensidade escolhida, ele irão retornar Preto e Alfa, caso contrário, eles retornarão o que está na Imagem.

Agora nós iremos copiar o nosso Plugin genérico para o arquivo simpfilt.c e iremos preencher as lacunas. É sempre uma boa ideia adicionar alguns comentários. Primeiro, iremos dizer aos usuários o que o Plugin faz, aonde podem obter uma cópia, e quem eles deverão contatar para resolução de problemas como bugs ou melhorias, e os termos de licença ou restrições dentro dos códigos.

Quando estiver utilizando comentários, tenha certeza de utilizar com comentários em estilo de linguagem C, tipicamente “/* */”. Os Plugins são escritos em C e alguns compiladores não aceitam comentários no estilo C++, portanto, não use “//” para seus comentários. Exemplo abaixo (em inglês):

/*
Description: This plugin is a sample sequence plugin that filters out
lower intensity pixels. It 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
*/

O próximo passo é preencher o código para o nome name, você realmente deverá manter este como sendo o mesmo que o seu nome de arquivo *.c , preferivelmente descritivo, com menos de 23 caracteres, sem espaços, e todos em "lowercase" (minúsculo)

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

As estruturas "Cast" e a variável “varstr” necessitam estar em sincronismo. Nós queremos um deslizador, portanto faremos o seguinte:

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;

Agora nós precisamos preencher os códigos para plugin_seq_doit. Nós basicamente queremos um "loop" (que o código seja circular) através de cada Pixel e caso encontre valores em RGB que sejam todos menores que a intensidade escolhida, que ele configure o Pixel de saída para (0,0,0,255) (Alfa), caso contrário configurar os valores de entrada para esta posição:

void plugin_seq_doit(Cast *cast, float facf0, float facf1, int xo, int yo,
                     ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *outbuf, ImBuf *use) {
	int nbrComp = xo * yo * 4; /*There are xo times yo pixels, with 4 components for each;*/
	int i;
	char *in1 = (char *)ibuf1->rect; /*ImBuf::rect is an int pointer (containing 4 chars!) */
	char *out = (char *)outbuf->rect;
 
	for(i=0; i < nbrComp; i+=4)
	{
		/* if R and G and B of the pixel are all greater than
		   the intensity, keep it unchanged. */
		if((in1[i+0] > cast->intensity) &&
		   (in1[i+1] > cast->intensity) &&
		   (in1[i+2] > cast->intensity))
		{
			out[i+0] = in1[i+0];
			out[i+1] = in1[i+1];
			out[i+2] = in1[i+2];
			out[i+3] = in1[i+3];
		}
		/* else, make the pixel black and transparent! */
		else
		{
			out[i+0] = out[i+1] = out[i+2] = 0;
			out[i+3] = 255;
		}
	}
}

Então nós terminamos que um arquivo chamado “simpfilt.c”.

Compilando

O software “bmake” é um simples utilitário, (que roda através de shell script) para auxiliar com a compilação e desenvolvimento de Plugins. Ele ode ser encontrado dentro do subdiretório plugins/ da Instalação do Blender. Ele é invocado pela linha de comando : bmake (plugin_name.c), e irá tentar ligar corretamente as bibliotecas apropriadas e compilar o arquivo específico em C de maneira adequada para seu Sistema.

Caso você esteja tentando desenvolver Plugins em uma Máquina rodando o Sistema Operacional Microsoft Windows, o software “bmake” poderá não funcionar. Neste caso, você deverá procurar pela utilização do software “lcc”. Você poderá utilizar o seguinte para compilar um Plugin com o “lcc”:

Assumindo que você tenha colocado os seus Plugins dentro de c:\blender\plugins, aqui há uma exemplo de como você deverá compilar o Plugin de Textura sweep.c. Abra uma Janela de Console de comando ou DOS e faça o seguinte (Nota: Você irá querer ter certeza de que o diretório lcc\bin está corretamente registrado na lista de caminhos ou “Path”, consulte os arquivos para fazer os registros adequados de suas variáveis de ambiente para seu Sistema Operacional):

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

A última versão do “lcc” não possui a biblioteca “implib”. Caso realmente não a tenha, faça o seguinte:

Note que o arquivo seq.def não é distribuído com os fontes do Blender, mas está disponível a partir do Repositório de Plugins do Blender. Alternativamente, crie um arquivo seq.def, copie e cole o seguinte :

EXPORTS
LibMain@12
plugin_but_changed
plugin_getinfo
plugin_init
plugin_seq_doit
plugin_seq_getversion