From BlenderWiki

Jump to: navigation, search
Note: This is an archived version of the Blender Developer Wiki. The current and active wiki is available on wiki.blender.org.

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

blender/compositor/CMakeLists.txt