「利用者:Coenspoor/Minimal node tutorial(2.5)」の版間の差分
(→Create the logic that your node will execute) |
(相違点なし)
|
2012年7月13日 (金) 22:05時点における版
New (as of 2.5) bare minimum
This section will be further documented once I find the time to further delve into the code and better explain why you do certain things. -Coen Spoor
Define node
We first need to define our new node in certain files, to make the compile process and Blender aware of it
source/blender/blenkernel/BKE_node.h
Assign a unique ID to the node(around line 660)
...
#define CMP_NODE_MASK 268
#define CMP_NODE_KEYINGSCREEN 269
#define CMP_NODE_KEYING 270
#define CMP_NODE_YOURNODE 290
...
source/blender/blenkernel/intern/node.c
Create the register function(line 1920)
...
register_node_type_cmp_doubleedgemask(ttype);
register_node_type_cmp_keyingscreen(ttype);
register_node_type_cmp_keying(ttype);
register_node_type_cmp_yournode(ttype);
...
source/blender/makesdna/DNA_node_types.h
around line 550
typedef struct NodeYourNode {
/*variables you want access to*/
} NodeYourNode;
source/blender/makesrna/intern/rna_nodetree.c
static void def_cmp_yournode(StructRNA *srna)
{
/* to be documented*/
}
source/blender/makesrna/intern/rna_nodetree_types.h
DefNode( CompositorNode, CMP_NODE_YOURNODE, def_cmp_yournode, "YOURNODE", YourNode, "YourNode", "" )
source/blender/nodes/NOD_composite.h
void register_node_type_cmp_yournode(struct bNodeTreeType *ttype);
Create the node itself
source/blender/nodes/composite/nodes/node_composite_yournode.c
#include "node_composite_util.h"
/* **************** yournode Tools ******************** */
static bNodeSocketTemplate cmp_node_yournode_in[]= {
{ SOCK_RGBA, 1, N_("Image"), 1.0f, 1.0f, 1.0f, 1.0f},
{ SOCK_FLOAT, 1, N_("VAL"), 1.0f, 0.0f, 0.0f, 0.0f, 0.001f, 10.0f, PROP_UNSIGNED},
{ -1, 0, "" }
};
static bNodeSocketTemplate cmp_node_yournode_out[]= {
{ SOCK_RGBA, 0, N_("Image")},
{ -1, 0, "" }
};
static void do_yournode(bNode *UNUSED(node), float *out, float *in, float *fac)
{
int i=0;
for (i=0; i<3; i++) {
/* check for negative to avoid nan's */
out[i] = in[i];
}
out[3] = in[3];
}
static void node_composit_exec_yournode(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out)
{
/* stack order in: Fac, Image */
/* stack order out: Image */
if (out[0]->hasoutput==0) return;
/* input no image? then only color operation */
if (in[0]->data==NULL) {
do_yournode(node, out[0]->vec, in[0]->vec, in[1]->vec);
}
else {
/* make output size of input image */
CompBuf *cbuf= in[0]->data;
CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); // allocs
composit2_pixel_processor(node, stackbuf, cbuf, in[0]->vec, in[1]->data, in[1]->vec, do_yournode, CB_RGBA, CB_VAL);
out[0]->data= stackbuf;
}
}
void register_node_type_cmp_yournode(bNodeTreeType *ttype)
{
static bNodeType ntype;
node_type_base(ttype, &ntype, CMP_NODE_YOURNODE, "YourNode", NODE_CLASS_OP_COLOR, NODE_OPTIONS);
node_type_socket_templates(&ntype, cmp_node_yournode_in, cmp_node_yournode_out);
node_type_size(&ntype, 140, 100, 320);
node_type_exec(&ntype, node_composit_exec_yournode);
nodeRegisterType(ttype, &ntype);
}
blender/nodes/CMakeLists.txt
composite/nodes/node_composite_yournode.c
New Compositor
Define and include our node/operation
blender/compositor/intern/COM_Converter.cpp
...
#include "COM_YourNode.h"
#include "COM_YourOperation.h"
...
switch (b_node->type) {
...
case CMP_NODE_YOURNODE:
node = new YourNode(b_node);
break;
Create the node
blender/compositor/nodes/COM_YourNode.h
#ifndef _COM_YourNode_h_
#define _COM_YourNode_h_
#include "COM_Node.h"
/**
* @brief YourNode
* @ingroup Node
*/
class YourNode : public Node {
public:
YourNode(bNode *editorNode);
void convertToOperations(ExecutionSystem *graph, CompositorContext *context);
};
#endif
blender/compositor/nodes/COM_YourNode.cpp
#include "COM_YourNode.h"
#include "DNA_scene_types.h"
#include "COM_YourOperation.h"
#include "COM_ExecutionSystem.h"
YourNode::YourNode(bNode *editorNode) : Node(editorNode)
{
/* pass */
}
void YourNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
{
YourOperation *operation = new YourOperation();
this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph);
this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, graph);
this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0));
graph->addOperation(operation);
}
Create the logic that your node will execute
blender/compositor/operations/COM_YourOperation.h
#ifndef _COM_YourOperation_h
#define _COM_YourOperation_h
#include "COM_NodeOperation.h"
class YourOperation : public NodeOperation {
private:
/**
* Cached reference to the inputProgram
*/
SocketReader *m_inputProgram;
SocketReader *m_inputYourProgram;
public:
YourOperation();
/**
* the inner loop of this program
*/
void executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer * inputBuffers[]);
/**
* Initialize the execution
*/
void initExecution();
/**
* Deinitialize the execution
*/
void deinitExecution();
};
#endif
blender/compositor/operations/COM_YourOperation.cpp
#include "COM_YouraOperation.h"
#include "BLI_math.h" /*you probably are going to do something math related*/
GammaOperation::YourOperation() : NodeOperation()
{
this->addInputSocket(COM_DT_COLOR);
this->addInputSocket(COM_DT_VALUE);
this->addOutputSocket(COM_DT_COLOR);
this->m_inputProgram = NULL;
this->m_inputYourProgram = NULL;
}
void YourOperation::initExecution()
{
this->m_inputProgram = this->getInputSocketReader(0);
this->m_inputYourProgram = this->getInputSocketReader(1);
}
void YourOperation::executePixel(float *color, float x, float y, PixelSampler sampler, MemoryBuffer *inputBuffers[])
{
/* Write logic here */
}
void YourOperation::deinitExecution()
{
this->m_inputProgram = NULL;
this->m_inputYourProgram = NULL;
}