diff options
Diffstat (limited to 'source/blender/compositor')
25 files changed, 281 insertions, 213 deletions
diff --git a/source/blender/compositor/intern/COM_CompositorContext.cpp b/source/blender/compositor/intern/COM_CompositorContext.cpp index e1cc25d028a..6008a889205 100644 --- a/source/blender/compositor/intern/COM_CompositorContext.cpp +++ b/source/blender/compositor/intern/COM_CompositorContext.cpp @@ -29,7 +29,6 @@ CompositorContext::CompositorContext() this->m_rd = NULL; this->m_quality = COM_QUALITY_HIGH; this->m_hasActiveOpenCLDevices = false; - this->m_activegNode = NULL; this->m_fastCalculation = false; this->m_viewSettings = NULL; this->m_displaySettings = NULL; diff --git a/source/blender/compositor/intern/COM_CompositorContext.h b/source/blender/compositor/intern/COM_CompositorContext.h index 840a9e59584..3c7db703bf9 100644 --- a/source/blender/compositor/intern/COM_CompositorContext.h +++ b/source/blender/compositor/intern/COM_CompositorContext.h @@ -64,11 +64,12 @@ private: * @see ExecutionSystem */ bNodeTree *m_bnodetree; - + /** - * @brief activegNode the group node that is currently being edited. + * @brief Preview image hash table + * This field is initialized in ExecutionSystem and must only be read from that point on. */ - bNode *m_activegNode; + bNodeInstanceHash *m_previews; /** * @brief does this system have active opencl devices? @@ -115,19 +116,19 @@ public: const bNodeTree *getbNodeTree() const { return this->m_bnodetree; } /** - * @brief set the active groupnode of the context + * @brief get the scene of the context */ - void setActivegNode(bNode *gnode) { this->m_activegNode = gnode; } + const RenderData *getRenderData() const { return this->m_rd; } /** - * @brief get the active groupnode of the context + * @brief set the preview image hash table */ - const bNode *getActivegNode() const { return this->m_activegNode; } + void setPreviewHash(bNodeInstanceHash *previews) { this->m_previews = previews; } /** - * @brief get the scene of the context + * @brief get the preview image hash table */ - const RenderData *getRenderData() const { return this->m_rd; } + bNodeInstanceHash *getPreviewHash() const { return this->m_previews; } /** * @brief set view settings of color color management diff --git a/source/blender/compositor/intern/COM_Converter.cpp b/source/blender/compositor/intern/COM_Converter.cpp index 9c4a32f20c9..80f5b4fc149 100644 --- a/source/blender/compositor/intern/COM_Converter.cpp +++ b/source/blender/compositor/intern/COM_Converter.cpp @@ -124,7 +124,7 @@ Node *Converter::convert(bNode *b_node, bool fast) { - Node *node; + Node *node = NULL; if (b_node->flag & NODE_MUTED) { node = new MuteNode(b_node); @@ -226,6 +226,10 @@ Node *Converter::convert(bNode *b_node, bool fast) case NODE_GROUP: node = new GroupNode(b_node); break; + case NODE_GROUP_INPUT: + case NODE_GROUP_OUTPUT: + /* handled in GroupNode::ungroup */ + break; case CMP_NODE_NORMAL: node = new NormalNode(b_node); break; @@ -399,7 +403,6 @@ Node *Converter::convert(bNode *b_node, bool fast) node = new PixelateNode(b_node); break; default: - node = new MuteNode(b_node); break; } return node; diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.cpp b/source/blender/compositor/intern/COM_ExecutionSystem.cpp index 2b2af73d0c8..2da1c34ab44 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystem.cpp +++ b/source/blender/compositor/intern/COM_ExecutionSystem.cpp @@ -49,7 +49,9 @@ ExecutionSystem::ExecutionSystem(RenderData *rd, bNodeTree *editingtree, bool re const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings) { this->m_context.setbNodeTree(editingtree); + this->m_context.setPreviewHash(editingtree->previews); this->m_context.setFastCalculation(fastcalculation); +#if 0 /* XXX TODO find a better way to define visible output nodes from all editors */ bNode *gnode; for (gnode = (bNode *)editingtree->nodes.first; gnode; gnode = gnode->next) { if (gnode->type == NODE_GROUP && gnode->typeinfo->group_edit_get(gnode)) { @@ -57,6 +59,7 @@ ExecutionSystem::ExecutionSystem(RenderData *rd, bNodeTree *editingtree, bool re break; } } +#endif /* initialize the CompositorContext */ if (rendering) { @@ -68,7 +71,7 @@ ExecutionSystem::ExecutionSystem(RenderData *rd, bNodeTree *editingtree, bool re this->m_context.setRendering(rendering); this->m_context.setHasActiveOpenCLDevices(WorkScheduler::hasGPUDevices() && (editingtree->flag & NTREE_COM_OPENCL)); - ExecutionSystemHelper::addbNodeTree(*this, 0, editingtree, NULL); + ExecutionSystemHelper::addbNodeTree(*this, 0, editingtree, NODE_INSTANCE_KEY_BASE); this->m_context.setRenderData(rd); this->m_context.setViewSettings(viewSettings); diff --git a/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp b/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp index 506bd42ace3..ad396e053f2 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp +++ b/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp @@ -26,7 +26,6 @@ #include <stdio.h> #include "PIL_time.h" -#include "BKE_node.h" #include "COM_Converter.h" #include "COM_NodeOperation.h" @@ -39,18 +38,25 @@ #include "COM_ReadBufferOperation.h" #include "COM_ViewerBaseOperation.h" -void ExecutionSystemHelper::addbNodeTree(ExecutionSystem &system, int nodes_start, bNodeTree *tree, bNode *groupnode) +extern "C" { +#include "BKE_node.h" +} + +void ExecutionSystemHelper::addbNodeTree(ExecutionSystem &system, int nodes_start, bNodeTree *tree, bNodeInstanceKey parent_key) { vector<Node *>& nodes = system.getNodes(); vector<SocketConnection *>& links = system.getConnections(); - const bNode *activeGroupNode = system.getContext().getActivegNode(); - bool isActiveGroup = activeGroupNode == groupnode; /* add all nodes of the tree to the node list */ bNode *node = (bNode *)tree->nodes.first; while (node != NULL) { + /* XXX TODO replace isActiveGroup by a more accurate check, all visible editors should do this! */ + bool isActiveGroup = true; Node *nnode = addNode(nodes, node, isActiveGroup, system.getContext().isFastCalculation()); - nnode->setbNodeGroup(groupnode); + if (nnode) { + nnode->setbNodeTree(tree); + nnode->setInstanceKey(BKE_node_instance_key(parent_key, tree, node)); + } node = node->next; } @@ -81,8 +87,10 @@ void ExecutionSystemHelper::addNode(vector<Node *>& nodes, Node *node) Node *ExecutionSystemHelper::addNode(vector<Node *>& nodes, bNode *b_node, bool inActiveGroup, bool fast) { Node *node = Converter::convert(b_node, fast); - node->setIsInActiveGroup(inActiveGroup); - addNode(nodes, node); + if (node) { + node->setIsInActiveGroup(inActiveGroup); + addNode(nodes, node); + } return node; } void ExecutionSystemHelper::addOperation(vector<NodeOperation *>& operations, NodeOperation *operation) @@ -109,43 +117,21 @@ void ExecutionSystemHelper::findOutputNodeOperations(vector<NodeOperation *> *re static InputSocket *find_input(NodeRange &node_range, bNode *bnode, bNodeSocket *bsocket) { - if (bnode != NULL) { - for (NodeIterator it = node_range.first; it != node_range.second; ++it) { - Node *node = *it; - if (node->getbNode() == bnode) - return node->findInputSocketBybNodeSocket(bsocket); - } - } - else { - for (NodeIterator it = node_range.first; it != node_range.second; ++it) { - Node *node = *it; - if (node->isProxyNode()) { - InputSocket *proxySocket = node->getInputSocket(0); - if (proxySocket->getbNodeSocket() == bsocket) - return proxySocket; - } - } + for (NodeIterator it = node_range.first; it != node_range.second; ++it) { + Node *node = *it; + InputSocket *input = node->findInputSocketBybNodeSocket(bsocket); + if (input) + return input; } return NULL; } static OutputSocket *find_output(NodeRange &node_range, bNode *bnode, bNodeSocket *bsocket) { - if (bnode != NULL) { - for (NodeIterator it = node_range.first; it != node_range.second; ++it) { - Node *node = *it; - if (node->getbNode() == bnode) - return node->findOutputSocketBybNodeSocket(bsocket); - } - } - else { - for (NodeIterator it = node_range.first; it != node_range.second; ++it) { - Node *node = *it; - if (node->isProxyNode()) { - OutputSocket *proxySocket = node->getOutputSocket(0); - if (proxySocket->getbNodeSocket() == bsocket) - return proxySocket; - } - } + for (NodeIterator it = node_range.first; it != node_range.second; ++it) { + Node *node = *it; + OutputSocket *output = node->findOutputSocketBybNodeSocket(bsocket); + if (output) + return output; } return NULL; } @@ -190,7 +176,7 @@ void ExecutionSystemHelper::debugDump(ExecutionSystem *system) tot = system->getNodes().size(); for (int i = 0; i < tot; i++) { node = system->getNodes()[i]; - printf("// NODE: %s\r\n", node->getbNode()->typeinfo->name); + printf("// NODE: %s\r\n", node->getbNode()->typeinfo->ui_name); } tot = system->getOperations().size(); for (int i = 0; i < tot; i++) { diff --git a/source/blender/compositor/intern/COM_ExecutionSystemHelper.h b/source/blender/compositor/intern/COM_ExecutionSystemHelper.h index 307e082ea80..e05796b9127 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystemHelper.h +++ b/source/blender/compositor/intern/COM_ExecutionSystemHelper.h @@ -48,7 +48,7 @@ public: * @param tree bNodeTree to add * @return Node representing the "Compositor node" of the maintree. or NULL when a subtree is added */ - static void addbNodeTree(ExecutionSystem &system, int nodes_start, bNodeTree *tree, bNode *groupnode); + static void addbNodeTree(ExecutionSystem &system, int nodes_start, bNodeTree *tree, bNodeInstanceKey parent_key); /** * @brief add an editor node to the system. diff --git a/source/blender/compositor/intern/COM_InputSocket.cpp b/source/blender/compositor/intern/COM_InputSocket.cpp index 2493d4e5a27..6868745d631 100644 --- a/source/blender/compositor/intern/COM_InputSocket.cpp +++ b/source/blender/compositor/intern/COM_InputSocket.cpp @@ -157,24 +157,3 @@ NodeOperation *InputSocket::getOperation() const return NULL; } } - -float *InputSocket::getStaticValues() -{ - /* XXX only works for socket types with actual float input values. - * currently all compositor socket types (value, rgba, vector) support this. - */ - bNodeSocket *b_socket = this->getbNodeSocket(); - static float default_null = 0.0f; - - switch (this->getDataType()) { - case COM_DT_VALUE: - return &((bNodeSocketValueFloat *)b_socket->default_value)->value; - case COM_DT_COLOR: - return ((bNodeSocketValueRGBA *)b_socket->default_value)->value; - case COM_DT_VECTOR: - return ((bNodeSocketValueVector *)b_socket->default_value)->value; - default: - /* XXX this should never happen, just added to please the compiler */ - return &default_null; - } -} diff --git a/source/blender/compositor/intern/COM_InputSocket.h b/source/blender/compositor/intern/COM_InputSocket.h index 5cd4cf3beb7..5a36fe3f33b 100644 --- a/source/blender/compositor/intern/COM_InputSocket.h +++ b/source/blender/compositor/intern/COM_InputSocket.h @@ -143,7 +143,6 @@ public: bool isStatic(); - float *getStaticValues(); SocketReader *getReader(); NodeOperation *getOperation() const; }; diff --git a/source/blender/compositor/intern/COM_Node.cpp b/source/blender/compositor/intern/COM_Node.cpp index d49bb5f96fb..f59580acb50 100644 --- a/source/blender/compositor/intern/COM_Node.cpp +++ b/source/blender/compositor/intern/COM_Node.cpp @@ -67,10 +67,9 @@ Node::Node(bNode *editorNode, bool create_sockets): NodeBase() void Node::addSetValueOperation(ExecutionSystem *graph, InputSocket *inputsocket, int editorNodeInputSocketIndex) { - bNodeSocket *bSock = this->getEditorInputSocket(editorNodeInputSocketIndex); + InputSocket *input = getInputSocket(editorNodeInputSocketIndex); SetValueOperation *operation = new SetValueOperation(); - bNodeSocketValueFloat *val = (bNodeSocketValueFloat *)bSock->default_value; - operation->setValue(val->value); + operation->setValue(input->getEditorValueFloat()); this->addLink(graph, operation->getOutputSocket(), inputsocket); graph->addOperation(operation); } @@ -79,11 +78,13 @@ void Node::addPreviewOperation(ExecutionSystem *system, CompositorContext *conte { if (this->isInActiveGroup()) { if (!(this->getbNode()->flag & NODE_HIDDEN)) { // do not calculate previews of hidden nodes. - if (this->getbNode()->flag & NODE_PREVIEW) { + bNodeInstanceHash *previews = context->getPreviewHash(); + if (previews && (this->getbNode()->flag & NODE_PREVIEW)) { PreviewOperation *operation = new PreviewOperation(context->getViewSettings(), context->getDisplaySettings()); system->addOperation(operation); operation->setbNode(this->getbNode()); operation->setbNodeTree(system->getContext().getbNodeTree()); + operation->verifyPreview(previews, this->getInstanceKey()); this->addLink(system, outputSocket, operation->getInputSocket(0)); } } @@ -114,25 +115,27 @@ SocketConnection *Node::addLink(ExecutionSystem *graph, OutputSocket *outputSock void Node::addSetColorOperation(ExecutionSystem *graph, InputSocket *inputsocket, int editorNodeInputSocketIndex) { - bNodeSocket *bSock = this->getEditorInputSocket(editorNodeInputSocketIndex); + InputSocket *input = getInputSocket(editorNodeInputSocketIndex); SetColorOperation *operation = new SetColorOperation(); - bNodeSocketValueRGBA *val = (bNodeSocketValueRGBA *)bSock->default_value; - operation->setChannel1(val->value[0]); - operation->setChannel2(val->value[1]); - operation->setChannel3(val->value[2]); - operation->setChannel4(val->value[3]); + float col[4]; + input->getEditorValueColor(col); + operation->setChannel1(col[0]); + operation->setChannel2(col[1]); + operation->setChannel3(col[2]); + operation->setChannel4(col[3]); this->addLink(graph, operation->getOutputSocket(), inputsocket); graph->addOperation(operation); } void Node::addSetVectorOperation(ExecutionSystem *graph, InputSocket *inputsocket, int editorNodeInputSocketIndex) { - bNodeSocket *bSock = this->getEditorInputSocket(editorNodeInputSocketIndex); - bNodeSocketValueVector *val = (bNodeSocketValueVector *)bSock->default_value; + InputSocket *input = getInputSocket(editorNodeInputSocketIndex); SetVectorOperation *operation = new SetVectorOperation(); - operation->setX(val->value[0]); - operation->setY(val->value[1]); - operation->setZ(val->value[2]); + float vec[3]; + input->getEditorValueVector(vec); + operation->setX(vec[0]); + operation->setY(vec[1]); + operation->setZ(vec[2]); this->addLink(graph, operation->getOutputSocket(), inputsocket); graph->addOperation(operation); } diff --git a/source/blender/compositor/intern/COM_Node.h b/source/blender/compositor/intern/COM_Node.h index 5b0381f6443..fb5dfe2e9b7 100644 --- a/source/blender/compositor/intern/COM_Node.h +++ b/source/blender/compositor/intern/COM_Node.h @@ -53,12 +53,11 @@ private: * @brief Is this node part of the active group */ bool m_inActiveGroup; - + /** - * @brief The group node this node belongs to. - * @note: used to find the links in the current subtree for muting nodes + * @brief Instance key to identify the node in an instance hash table */ - bNode *m_bNodeGroup; + bNodeInstanceKey m_instanceKey; public: Node(bNode *editorNode, bool create_sockets = true); @@ -145,8 +144,9 @@ public: */ OutputSocket *findOutputSocketBybNodeSocket(bNodeSocket *socket); - inline void setbNodeGroup(bNode *group) {this->m_bNodeGroup = group;} - inline bNode *getbNodeGroup() {return this->m_bNodeGroup;} + void setInstanceKey(bNodeInstanceKey instance_key) { m_instanceKey = instance_key; } + bNodeInstanceKey getInstanceKey() const { return m_instanceKey; } + protected: void addPreviewOperation(ExecutionSystem *system, CompositorContext *context, InputSocket *inputSocket); void addPreviewOperation(ExecutionSystem *system, CompositorContext *context, OutputSocket *outputSocket); diff --git a/source/blender/compositor/intern/COM_NodeBase.h b/source/blender/compositor/intern/COM_NodeBase.h index e386b5e08a0..41b6ab70bf9 100644 --- a/source/blender/compositor/intern/COM_NodeBase.h +++ b/source/blender/compositor/intern/COM_NodeBase.h @@ -59,6 +59,11 @@ private: */ bNode *m_editorNode; + /** + * @brief stores the reference to the SDNA bNode struct + */ + bNodeTree *m_editorNodeTree; + protected: /** * @brief get access to the vector of input sockets @@ -82,14 +87,25 @@ public: /** * @brief get the reference to the SDNA bNode struct */ - bNode *getbNode() {return m_editorNode;} + bNode *getbNode() const {return m_editorNode;} + + /** + * @brief get the reference to the SDNA bNodeTree struct + */ + bNodeTree *getbNodeTree() const {return m_editorNodeTree;} /** * @brief set the reference to the bNode * @note used in Node instances to receive the storage/settings and complex node for highlight during execution * @param bNode */ - void setbNode(bNode *bNode) {this->m_editorNode = bNode;} + void setbNode(bNode *node) {this->m_editorNode = node;} + + /** + * @brief set the reference to the bNodeTree + * @param bNodeTree + */ + void setbNodeTree(bNodeTree *nodetree) {this->m_editorNodeTree = nodetree;} /** * @brief is this node an operation? diff --git a/source/blender/compositor/intern/COM_Socket.cpp b/source/blender/compositor/intern/COM_Socket.cpp index 30f28f9dddb..3465fa6f56d 100644 --- a/source/blender/compositor/intern/COM_Socket.cpp +++ b/source/blender/compositor/intern/COM_Socket.cpp @@ -24,6 +24,10 @@ #include "COM_Node.h" #include "COM_SocketConnection.h" +extern "C" { +#include "RNA_access.h" +} + Socket::Socket(DataType datatype) { this->m_datatype = datatype; @@ -41,3 +45,24 @@ int Socket::isOutputSocket() const { return false; } const int Socket::isConnected() const { return false; } void Socket::setNode(NodeBase *node) { this->m_node = node; } NodeBase *Socket::getNode() const { return this->m_node; } + +float Socket::getEditorValueFloat() +{ + PointerRNA ptr; + RNA_pointer_create((ID *)getNode()->getbNodeTree(), &RNA_NodeSocket, getbNodeSocket(), &ptr); + return RNA_float_get(&ptr, "default_value"); +} + +void Socket::getEditorValueColor(float *value) +{ + PointerRNA ptr; + RNA_pointer_create((ID *)getNode()->getbNodeTree(), &RNA_NodeSocket, getbNodeSocket(), &ptr); + return RNA_float_get_array(&ptr, "default_value", value); +} + +void Socket::getEditorValueVector(float *value) +{ + PointerRNA ptr; + RNA_pointer_create((ID *)getNode()->getbNodeTree(), &RNA_NodeSocket, getbNodeSocket(), &ptr); + return RNA_float_get_array(&ptr, "default_value", value); +} diff --git a/source/blender/compositor/intern/COM_Socket.h b/source/blender/compositor/intern/COM_Socket.h index bad112d20c7..6532864a4d9 100644 --- a/source/blender/compositor/intern/COM_Socket.h +++ b/source/blender/compositor/intern/COM_Socket.h @@ -36,6 +36,7 @@ using namespace std; class SocketConnection; class NodeBase; +struct PointerRNA; /** * @brief Base class for InputSocket and OutputSocket. @@ -86,6 +87,10 @@ public: void setEditorSocket(bNodeSocket *editorSocket) { this->m_editorSocket = editorSocket; } bNodeSocket *getbNodeSocket() const { return this->m_editorSocket; } + float getEditorValueFloat(); + void getEditorValueColor(float *value); + void getEditorValueVector(float *value); + #ifdef WITH_CXX_GUARDEDALLOC MEM_CXX_CLASS_ALLOC_FUNCS("COM:Socket") #endif diff --git a/source/blender/compositor/intern/COM_compositor.cpp b/source/blender/compositor/intern/COM_compositor.cpp index 49ab9db5dd8..94a27e17b68 100644 --- a/source/blender/compositor/intern/COM_compositor.cpp +++ b/source/blender/compositor/intern/COM_compositor.cpp @@ -21,9 +21,9 @@ */ -#include "BKE_node.h" extern "C" { - #include "BLI_threads.h" +#include "BKE_node.h" +#include "BLI_threads.h" } #include "BKE_main.h" #include "BKE_global.h" @@ -63,6 +63,11 @@ void COM_execute(RenderData *rd, bNodeTree *editingtree, int rendering, return; } + /* Make sure node tree has previews. + * Don't create previews in advance, this is done when adding preview operations. + */ + BKE_node_preview_init_tree(editingtree, COM_PREVIEW_SIZE, COM_PREVIEW_SIZE, FALSE); + /* initialize workscheduler, will check if already done. TODO deinitialize somewhere */ bool use_opencl = (editingtree->flag & NTREE_COM_OPENCL); WorkScheduler::initialize(use_opencl); @@ -85,7 +90,6 @@ void COM_execute(RenderData *rd, bNodeTree *editingtree, int rendering, } } - ExecutionSystem *system = new ExecutionSystem(rd, editingtree, rendering, false, viewSettings, displaySettings); system->execute(); delete system; 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); } diff --git a/source/blender/compositor/operations/COM_PreviewOperation.cpp b/source/blender/compositor/operations/COM_PreviewOperation.cpp index 6e58b277f66..ba158fb2509 100644 --- a/source/blender/compositor/operations/COM_PreviewOperation.cpp +++ b/source/blender/compositor/operations/COM_PreviewOperation.cpp @@ -36,42 +36,47 @@ extern "C" { #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" #include "IMB_colormanagement.h" + #include "BKE_node.h" } PreviewOperation::PreviewOperation(const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings) : NodeOperation() { this->addInputSocket(COM_DT_COLOR, COM_SC_NO_RESIZE); + this->m_preview = NULL; this->m_outputBuffer = NULL; this->m_input = NULL; this->m_divider = 1.0f; - this->m_node = NULL; this->m_viewSettings = viewSettings; this->m_displaySettings = displaySettings; } +void PreviewOperation::verifyPreview(bNodeInstanceHash *previews, bNodeInstanceKey key) +{ + /* Size (0, 0) ensures the preview rect is not allocated in advance, + * this is set later in initExecution once the resolution is determined. + */ + this->m_preview = BKE_node_preview_verify(previews, key, 0, 0, TRUE); +} + void PreviewOperation::initExecution() { this->m_input = getInputSocketReader(0); - if (!this->m_node->preview) { - this->m_node->preview = (bNodePreview *)MEM_callocN(sizeof(bNodePreview), "node preview"); - } - else { - if (this->getWidth() == (unsigned int)this->m_node->preview->xsize && - this->getHeight() == (unsigned int)this->m_node->preview->ysize) - { - this->m_outputBuffer = this->m_node->preview->rect; - } + + if (this->getWidth() == (unsigned int)this->m_preview->xsize && + this->getHeight() == (unsigned int)this->m_preview->ysize) + { + this->m_outputBuffer = this->m_preview->rect; } if (this->m_outputBuffer == NULL) { this->m_outputBuffer = (unsigned char *)MEM_callocN(sizeof(unsigned char) * 4 * getWidth() * getHeight(), "PreviewOperation"); - if (this->m_node->preview->rect) { - MEM_freeN(this->m_node->preview->rect); + if (this->m_preview->rect) { + MEM_freeN(this->m_preview->rect); } - this->m_node->preview->xsize = getWidth(); - this->m_node->preview->ysize = getHeight(); - this->m_node->preview->rect = this->m_outputBuffer; + this->m_preview->xsize = getWidth(); + this->m_preview->ysize = getHeight(); + this->m_preview->rect = this->m_outputBuffer; } } diff --git a/source/blender/compositor/operations/COM_PreviewOperation.h b/source/blender/compositor/operations/COM_PreviewOperation.h index 0da6b8e4e56..bb60dfa0420 100644 --- a/source/blender/compositor/operations/COM_PreviewOperation.h +++ b/source/blender/compositor/operations/COM_PreviewOperation.h @@ -35,7 +35,7 @@ protected: /** * @brief holds reference to the SDNA bNode, where this nodes will render the preview image for */ - bNode *m_node; + bNodePreview *m_preview; SocketReader *m_input; float m_divider; @@ -43,6 +43,8 @@ protected: const ColorManagedDisplaySettings *m_displaySettings; public: PreviewOperation(const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings); + void verifyPreview(bNodeInstanceHash *previews, bNodeInstanceKey key); + bool isOutputOperation(bool rendering) const { return !G.background; } void initExecution(); void deinitExecution(); @@ -50,7 +52,6 @@ public: void executeRegion(rcti *rect, unsigned int tileNumber); void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); - void setbNode(bNode *node) { this->m_node = node; } bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); bool isPreviewOperation() { return true; } |