diff options
author | Lukas Toenne <lukas.toenne@googlemail.com> | 2013-03-18 20:34:57 +0400 |
---|---|---|
committer | Lukas Toenne <lukas.toenne@googlemail.com> | 2013-03-18 20:34:57 +0400 |
commit | 4638e5f99a9ba59ad0b8a1fd52b12e876480b9e8 (patch) | |
tree | 2444f12b4612440f44cf02835cdf5951b6564e92 /source/blender/compositor/nodes | |
parent | 7bfef29f2f2a1b262d28abdc6e30fcd9c1f1caad (diff) |
Merge of the PyNodes branch (aka "custom nodes") into trunk.
PyNodes opens up the node system in Blender to scripters and adds a number of UI-level improvements.
=== Dynamic node type registration ===
Node types can now be added at runtime, using the RNA registration mechanism from python. This enables addons such as render engines to create a complete user interface with nodes.
Examples of how such nodes can be defined can be found in my personal wiki docs atm [1] and as a script template in release/scripts/templates_py/custom_nodes.py [2].
=== Node group improvements ===
Each node editor now has a tree history of edited node groups, which allows opening and editing nested node groups. The node editor also supports pinning now, so that different spaces can be used to edit different node groups simultaneously. For more ramblings and rationale see (really old) blog post on code.blender.org [3].
The interface of node groups has been overhauled. Sockets of a node group are no longer displayed in columns on either side, but instead special input/output nodes are used to mirror group sockets inside a node tree. This solves the problem of long node lines in groups and allows more adaptable node layout. Internal sockets can be exposed from a group by either connecting to the extension sockets in input/output nodes (shown as empty circle) or by adding sockets from the node property bar in the "Interface" panel. Further details such as the socket name can also be changed there.
[1] http://wiki.blender.org/index.php/User:Phonybone/Python_Nodes
[2] http://projects.blender.org/scm/viewvc.php/trunk/blender/release/scripts/templates_py/custom_nodes.py?view=markup&root=bf-blender
[3] http://code.blender.org/index.php/2012/01/improving-node-group-interface-editing/
Diffstat (limited to 'source/blender/compositor/nodes')
9 files changed, 133 insertions, 94 deletions
diff --git a/source/blender/compositor/nodes/COM_BlurNode.cpp b/source/blender/compositor/nodes/COM_BlurNode.cpp index 6a4987c2075..b59a92710bc 100644 --- a/source/blender/compositor/nodes/COM_BlurNode.cpp +++ b/source/blender/compositor/nodes/COM_BlurNode.cpp @@ -45,8 +45,7 @@ void BlurNode::convertToOperations(ExecutionSystem *graph, CompositorContext *co InputSocket *inputSizeSocket = this->getInputSocket(1); bool connectedSizeSocket = inputSizeSocket->isConnected(); - const bNodeSocket *sock = this->getInputSocket(1)->getbNodeSocket(); - const float size = ((const bNodeSocketValueFloat *)sock->default_value)->value; + const float size = this->getInputSocket(1)->getEditorValueFloat(); CompositorQuality quality = context->getQuality(); NodeOperation *input_operation = NULL, *output_operation = NULL; diff --git a/source/blender/compositor/nodes/COM_BokehBlurNode.cpp b/source/blender/compositor/nodes/COM_BokehBlurNode.cpp index 70f20e3235b..5725bc6cb32 100644 --- a/source/blender/compositor/nodes/COM_BokehBlurNode.cpp +++ b/source/blender/compositor/nodes/COM_BokehBlurNode.cpp @@ -60,21 +60,17 @@ void BokehBlurNode::convertToOperations(ExecutionSystem *graph, CompositorContex else { BokehBlurOperation *operation = new BokehBlurOperation(); - const bNodeSocket *sock = this->getInputSocket(2)->getbNodeSocket(); - const float size = ((const bNodeSocketValueFloat *)sock->default_value)->value; - this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph); this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, graph); this->getInputSocket(2)->relinkConnections(operation->getInputSocket(3), 2, graph); this->getInputSocket(3)->relinkConnections(operation->getInputSocket(2), 3, graph); - //operation->setSize(((bNodeSocketValueFloat *)this->getInputSocket(2)->getbNodeSocket()->default_value)->value); operation->setQuality(context->getQuality()); operation->setbNode(this->getbNode()); graph->addOperation(operation); this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket()); if (!connectedSizeSocket) { - operation->setSize(size); + operation->setSize(this->getInputSocket(2)->getEditorValueFloat()); } } } diff --git a/source/blender/compositor/nodes/COM_ColorCurveNode.cpp b/source/blender/compositor/nodes/COM_ColorCurveNode.cpp index 93ff304afd8..103fbf26c7d 100644 --- a/source/blender/compositor/nodes/COM_ColorCurveNode.cpp +++ b/source/blender/compositor/nodes/COM_ColorCurveNode.cpp @@ -50,10 +50,11 @@ void ColorCurveNode::convertToOperations(ExecutionSystem *graph, CompositorConte this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph); this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, graph); - bNodeSocketValueRGBA *val = (bNodeSocketValueRGBA *)this->getInputSocket(2)->getbNodeSocket()->default_value; - operation->setBlackLevel(val->value); - val = (bNodeSocketValueRGBA *)this->getInputSocket(3)->getbNodeSocket()->default_value; - operation->setWhiteLevel(val->value); + float col[4]; + this->getInputSocket(2)->getEditorValueColor(col); + operation->setBlackLevel(col); + this->getInputSocket(3)->getEditorValueColor(col); + operation->setWhiteLevel(col); this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket()); operation->setCurveMapping((CurveMapping *)this->getbNode()->storage); diff --git a/source/blender/compositor/nodes/COM_ColorNode.cpp b/source/blender/compositor/nodes/COM_ColorNode.cpp index 088f8bbb19d..fc2566e5a47 100644 --- a/source/blender/compositor/nodes/COM_ColorNode.cpp +++ b/source/blender/compositor/nodes/COM_ColorNode.cpp @@ -32,9 +32,10 @@ ColorNode::ColorNode(bNode *editorNode) : Node(editorNode) void ColorNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { SetColorOperation *operation = new SetColorOperation(); - bNodeSocket *socket = this->getEditorOutputSocket(0); - bNodeSocketValueRGBA *dval = (bNodeSocketValueRGBA *)socket->default_value; - this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket()); - operation->setChannels(dval->value); + OutputSocket *output = this->getOutputSocket(0); + output->relinkConnections(operation->getOutputSocket()); + float col[4]; + output->getEditorValueColor(col); + operation->setChannels(col); graph->addOperation(operation); } diff --git a/source/blender/compositor/nodes/COM_GroupNode.cpp b/source/blender/compositor/nodes/COM_GroupNode.cpp index 05c749345d5..3b67d0912d4 100644 --- a/source/blender/compositor/nodes/COM_GroupNode.cpp +++ b/source/blender/compositor/nodes/COM_GroupNode.cpp @@ -20,6 +20,8 @@ * Monique Dewanchand */ +#include "BKE_node.h" + #include "COM_GroupNode.h" #include "COM_SocketProxyNode.h" #include "COM_SetColorOperation.h" @@ -37,13 +39,38 @@ void GroupNode::convertToOperations(ExecutionSystem *graph, CompositorContext *c } } +static int find_group_input(GroupNode *gnode, const char *identifier, InputSocket **r_sock) +{ + int index; + for (index = 0; index < gnode->getNumberOfInputSockets(); ++index) { + InputSocket *sock = gnode->getInputSocket(index); + if (strcmp(sock->getbNodeSocket()->identifier, identifier)==0) { + *r_sock = sock; + return index; + } + } + *r_sock = NULL; + return -1; +} + +static int find_group_output(GroupNode *gnode, const char *identifier, OutputSocket **r_sock) +{ + int index; + for (index = 0; index < gnode->getNumberOfOutputSockets(); ++index) { + OutputSocket *sock = gnode->getOutputSocket(index); + if (strcmp(sock->getbNodeSocket()->identifier, identifier)==0) { + *r_sock = sock; + return index; + } + } + *r_sock = NULL; + return -1; +} + void GroupNode::ungroup(ExecutionSystem &system) { bNode *bnode = this->getbNode(); bNodeTree *subtree = (bNodeTree *)bnode->id; - vector<InputSocket *> &inputsockets = this->getInputSockets(); - vector<OutputSocket *> &outputsockets = this->getOutputSockets(); - unsigned int index; /* get the node list size _before_ adding proxy nodes, so they are available for linking */ int nodes_start = system.getNodes().size(); @@ -54,26 +81,44 @@ void GroupNode::ungroup(ExecutionSystem &system) return; } - for (index = 0; index < inputsockets.size(); index++) { - InputSocket *inputSocket = inputsockets[index]; - bNodeSocket *editorInput = inputSocket->getbNodeSocket(); - if (editorInput->groupsock) { - SocketProxyNode *proxy = new SocketProxyNode(bnode, editorInput, editorInput->groupsock, false); - inputSocket->relinkConnections(proxy->getInputSocket(0), index, &system); - ExecutionSystemHelper::addNode(system.getNodes(), proxy); - } - } - const bool groupnodeBuffering = system.getContext().isGroupnodeBufferEnabled(); - for (index = 0; index < outputsockets.size(); index++) { - OutputSocket *outputSocket = outputsockets[index]; - bNodeSocket *editorOutput = outputSocket->getbNodeSocket(); - if (editorOutput->groupsock) { - SocketProxyNode *proxy = new SocketProxyNode(bnode, editorOutput->groupsock, editorOutput, groupnodeBuffering); - outputSocket->relinkConnections(proxy->getOutputSocket(0)); - ExecutionSystemHelper::addNode(system.getNodes(), proxy); + + /* create proxy nodes for group input/output nodes */ + for (bNode *bionode = (bNode *)subtree->nodes.first; bionode; bionode = bionode->next) { + if (bionode->type == NODE_GROUP_INPUT) { + for (bNodeSocket *bsock = (bNodeSocket *)bionode->outputs.first; bsock; bsock = bsock->next) { + InputSocket *gsock; + int gsock_index = find_group_input(this, bsock->identifier, &gsock); + /* ignore virtual sockets */ + if (gsock) { + SocketProxyNode *proxy = new SocketProxyNode(bionode, gsock->getbNodeSocket(), bsock, false); + ExecutionSystemHelper::addNode(system.getNodes(), proxy); + + gsock->relinkConnectionsDuplicate(proxy->getInputSocket(0), gsock_index, &system); + } + } + } + + if (bionode->type == NODE_GROUP_OUTPUT && (bionode->flag & NODE_DO_OUTPUT)) { + for (bNodeSocket *bsock = (bNodeSocket *)bionode->inputs.first; bsock; bsock = bsock->next) { + OutputSocket *gsock; + find_group_output(this, bsock->identifier, &gsock); + /* ignore virtual sockets */ + if (gsock) { + SocketProxyNode *proxy = new SocketProxyNode(bionode, bsock, gsock->getbNodeSocket(), groupnodeBuffering); + ExecutionSystemHelper::addNode(system.getNodes(), proxy); + + gsock->relinkConnections(proxy->getOutputSocket(0)); + } + } } } - - ExecutionSystemHelper::addbNodeTree(system, nodes_start, subtree, bnode); + + /* unlink the group node itself, input links have been duplicated */ + for (int index = 0; index < this->getNumberOfInputSockets(); ++index) { + InputSocket *sock = this->getInputSocket(index); + sock->unlinkConnections(&system); + } + + ExecutionSystemHelper::addbNodeTree(system, nodes_start, subtree, this->getInstanceKey()); } diff --git a/source/blender/compositor/nodes/COM_LensDistortionNode.cpp b/source/blender/compositor/nodes/COM_LensDistortionNode.cpp index 94c2fc885fb..f91744d88b6 100644 --- a/source/blender/compositor/nodes/COM_LensDistortionNode.cpp +++ b/source/blender/compositor/nodes/COM_LensDistortionNode.cpp @@ -51,8 +51,8 @@ void LensDistortionNode::convertToOperations(ExecutionSystem *graph, CompositorC operation->setData(data); if (!(this->getInputSocket(1)->isConnected() || this->getInputSocket(2)->isConnected())) { // no nodes connected to the distortion and dispersion. We can precalculate some values - float distortion = ((const bNodeSocketValueFloat *)this->getInputSocket(1)->getbNodeSocket()->default_value)->value; - float dispersion = ((const bNodeSocketValueFloat *)this->getInputSocket(2)->getbNodeSocket()->default_value)->value; + float distortion = this->getInputSocket(1)->getEditorValueFloat(); + float dispersion = this->getInputSocket(2)->getEditorValueFloat(); operation->setDistortionAndDispersion(distortion, dispersion); } diff --git a/source/blender/compositor/nodes/COM_NormalNode.cpp b/source/blender/compositor/nodes/COM_NormalNode.cpp index fbfff8386d0..41b91f61328 100644 --- a/source/blender/compositor/nodes/COM_NormalNode.cpp +++ b/source/blender/compositor/nodes/COM_NormalNode.cpp @@ -36,15 +36,13 @@ void NormalNode::convertToOperations(ExecutionSystem *graph, CompositorContext * InputSocket *inputSocket = this->getInputSocket(0); OutputSocket *outputSocket = this->getOutputSocket(0); OutputSocket *outputSocketDotproduct = this->getOutputSocket(1); - bNode *editorNode = this->getbNode(); SetVectorOperation *operationSet = new SetVectorOperation(); - bNodeSocket *insock = (bNodeSocket *)editorNode->outputs.first; - bNodeSocketValueVector *dval = (bNodeSocketValueVector *)insock->default_value; float normal[3]; + outputSocket->getEditorValueVector(normal); /* animation can break normalization, this restores it */ - normalize_v3_v3(normal, dval->value); + normalize_v3(normal); operationSet->setX(normal[0]); operationSet->setY(normal[1]); diff --git a/source/blender/compositor/nodes/COM_SocketProxyNode.cpp b/source/blender/compositor/nodes/COM_SocketProxyNode.cpp index ded6186ad77..c822d2107ec 100644 --- a/source/blender/compositor/nodes/COM_SocketProxyNode.cpp +++ b/source/blender/compositor/nodes/COM_SocketProxyNode.cpp @@ -50,54 +50,54 @@ void SocketProxyNode::convertToOperations(ExecutionSystem *graph, CompositorCont { OutputSocket *outputsocket = this->getOutputSocket(0); InputSocket *inputsocket = this->getInputSocket(0); - if (outputsocket->isConnected()) { - if (inputsocket->isConnected()) { - SocketProxyOperation *operation = new SocketProxyOperation(this->getOutputSocket()->getDataType()); - inputsocket->relinkConnections(operation->getInputSocket(0)); - outputsocket->relinkConnections(operation->getOutputSocket(0)); - graph->addOperation(operation); - if (m_buffer) { - WriteBufferOperation *writeOperation = new WriteBufferOperation(); - ReadBufferOperation *readOperation = new ReadBufferOperation(); - readOperation->setMemoryProxy(writeOperation->getMemoryProxy()); - - operation->getOutputSocket()->relinkConnections(readOperation->getOutputSocket()); - addLink(graph, operation->getOutputSocket(), writeOperation->getInputSocket(0)); - - graph->addOperation(writeOperation); - graph->addOperation(readOperation); - } + if (inputsocket->isConnected()) { + SocketProxyOperation *operation = new SocketProxyOperation(this->getOutputSocket()->getDataType()); + inputsocket->relinkConnections(operation->getInputSocket(0)); + outputsocket->relinkConnections(operation->getOutputSocket(0)); + graph->addOperation(operation); + + if (m_buffer) { + WriteBufferOperation *writeOperation = new WriteBufferOperation(); + ReadBufferOperation *readOperation = new ReadBufferOperation(); + readOperation->setMemoryProxy(writeOperation->getMemoryProxy()); + + operation->getOutputSocket()->relinkConnections(readOperation->getOutputSocket()); + addLink(graph, operation->getOutputSocket(), writeOperation->getInputSocket(0)); + + graph->addOperation(writeOperation); + graph->addOperation(readOperation); } - else { - /* If input is not connected, add a constant value operation instead */ - switch (outputsocket->getDataType()) { - case COM_DT_VALUE: - { - SetValueOperation *operation = new SetValueOperation(); - bNodeSocketValueFloat *dval = (bNodeSocketValueFloat *)inputsocket->getbNodeSocket()->default_value; - operation->setValue(dval->value); - outputsocket->relinkConnections(operation->getOutputSocket(0)); - graph->addOperation(operation); - break; - } - case COM_DT_COLOR: - { - SetColorOperation *operation = new SetColorOperation(); - bNodeSocketValueRGBA *dval = (bNodeSocketValueRGBA *)inputsocket->getbNodeSocket()->default_value; - operation->setChannels(dval->value); - outputsocket->relinkConnections(operation->getOutputSocket(0)); - graph->addOperation(operation); - break; - } - case COM_DT_VECTOR: - { - SetVectorOperation *operation = new SetVectorOperation(); - bNodeSocketValueVector *dval = (bNodeSocketValueVector *)inputsocket->getbNodeSocket()->default_value; - operation->setVector(dval->value); - outputsocket->relinkConnections(operation->getOutputSocket(0)); - graph->addOperation(operation); - break; - } + } + else if (outputsocket->isConnected()) { + /* If input is not connected, add a constant value operation instead */ + switch (outputsocket->getDataType()) { + case COM_DT_VALUE: + { + SetValueOperation *operation = new SetValueOperation(); + operation->setValue(inputsocket->getEditorValueFloat()); + outputsocket->relinkConnections(operation->getOutputSocket(0)); + graph->addOperation(operation); + break; + } + case COM_DT_COLOR: + { + SetColorOperation *operation = new SetColorOperation(); + float col[4]; + inputsocket->getEditorValueColor(col); + operation->setChannels(col); + outputsocket->relinkConnections(operation->getOutputSocket(0)); + graph->addOperation(operation); + break; + } + case COM_DT_VECTOR: + { + SetVectorOperation *operation = new SetVectorOperation(); + float vec[3]; + inputsocket->getEditorValueVector(vec); + operation->setVector(vec); + outputsocket->relinkConnections(operation->getOutputSocket(0)); + graph->addOperation(operation); + break; } } } diff --git a/source/blender/compositor/nodes/COM_ValueNode.cpp b/source/blender/compositor/nodes/COM_ValueNode.cpp index 593d74952ee..ed4440aa099 100644 --- a/source/blender/compositor/nodes/COM_ValueNode.cpp +++ b/source/blender/compositor/nodes/COM_ValueNode.cpp @@ -32,9 +32,8 @@ ValueNode::ValueNode(bNode *editorNode) : Node(editorNode) void ValueNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { SetValueOperation *operation = new SetValueOperation(); - bNodeSocket *socket = this->getEditorOutputSocket(0); - bNodeSocketValueFloat *dval = (bNodeSocketValueFloat *)socket->default_value; - this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket()); - operation->setValue(dval->value); + OutputSocket *output = this->getOutputSocket(0); + output->relinkConnections(operation->getOutputSocket()); + operation->setValue(output->getEditorValueFloat()); graph->addOperation(operation); } |