diff options
41 files changed, 391 insertions, 81 deletions
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp index dc20dbdbea2..1af0972ecf9 100644 --- a/intern/cycles/render/image.cpp +++ b/intern/cycles/render/image.cpp @@ -109,8 +109,11 @@ int ImageManager::add_image(const string& filename, bool& is_float) if(slot == float_images.size()) { /* max images limit reached */ - if(float_images.size() == TEX_NUM_FLOAT_IMAGES) + if(float_images.size() == TEX_NUM_FLOAT_IMAGES) { + printf("ImageManager::add_image: byte image limit reached %d, skipping '%s'\n", + TEX_NUM_IMAGES, filename.c_str()); return -1; + } float_images.resize(float_images.size() + 1); } @@ -141,8 +144,11 @@ int ImageManager::add_image(const string& filename, bool& is_float) if(slot == images.size()) { /* max images limit reached */ - if(images.size() == TEX_NUM_IMAGES) + if(images.size() == TEX_NUM_IMAGES) { + printf("ImageManager::add_image: byte image limit reached %d, skipping '%s'\n", + TEX_NUM_IMAGES, filename.c_str()); return -1; + } images.resize(images.size() + 1); } @@ -353,13 +359,13 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, int sl device->tex_free(tex_img); if(!file_load_float_image(img, tex_img)) { - /* on failure to load, we set a 1x1 pixels black image */ + /* on failure to load, we set a 1x1 pixels pink image */ float *pixels = (float*)tex_img.resize(1, 1); - pixels[0] = 0.0f; - pixels[1] = 0.0f; - pixels[2] = 0.0f; - pixels[3] = 0.0f; + pixels[0] = TEX_IMAGE_MISSING_R; + pixels[1] = TEX_IMAGE_MISSING_G; + pixels[2] = TEX_IMAGE_MISSING_B; + pixels[3] = TEX_IMAGE_MISSING_A; } string name; @@ -380,13 +386,13 @@ void ImageManager::device_load_image(Device *device, DeviceScene *dscene, int sl device->tex_free(tex_img); if(!file_load_image(img, tex_img)) { - /* on failure to load, we set a 1x1 pixels black image */ + /* on failure to load, we set a 1x1 pixels pink image */ uchar *pixels = (uchar*)tex_img.resize(1, 1); - pixels[0] = 0; - pixels[1] = 0; - pixels[2] = 0; - pixels[3] = 0; + pixels[0] = (TEX_IMAGE_MISSING_R * 255); + pixels[1] = (TEX_IMAGE_MISSING_G * 255); + pixels[2] = (TEX_IMAGE_MISSING_B * 255); + pixels[3] = (TEX_IMAGE_MISSING_A * 255); } string name; diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h index 2b5e53cabe1..ef046cfcafb 100644 --- a/intern/cycles/render/image.h +++ b/intern/cycles/render/image.h @@ -31,6 +31,12 @@ CCL_NAMESPACE_BEGIN #define TEX_IMAGE_MAX (TEX_NUM_IMAGES + TEX_NUM_FLOAT_IMAGES) #define TEX_IMAGE_FLOAT_START TEX_NUM_IMAGES +/* color to use when textures are not found */ +#define TEX_IMAGE_MISSING_R 1 +#define TEX_IMAGE_MISSING_G 0 +#define TEX_IMAGE_MISSING_B 1 +#define TEX_IMAGE_MISSING_A 1 + class Device; class DeviceScene; class Progress; diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 0f64d858de0..e4a4b874964 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -184,10 +184,12 @@ void ImageTextureNode::compile(SVMCompiler& compiler) /* image not found */ if(!color_out->links.empty()) { compiler.add_node(NODE_VALUE_V, color_out->stack_offset); - compiler.add_node(NODE_VALUE_V, make_float3(0, 0, 0)); + compiler.add_node(NODE_VALUE_V, make_float3(TEX_IMAGE_MISSING_R, + TEX_IMAGE_MISSING_G, + TEX_IMAGE_MISSING_B)); } if(!alpha_out->links.empty()) - compiler.add_node(NODE_VALUE_F, __float_as_int(0.0f), alpha_out->stack_offset); + compiler.add_node(NODE_VALUE_F, __float_as_int(TEX_IMAGE_MISSING_A), alpha_out->stack_offset); } } @@ -288,10 +290,12 @@ void EnvironmentTextureNode::compile(SVMCompiler& compiler) /* image not found */ if(!color_out->links.empty()) { compiler.add_node(NODE_VALUE_V, color_out->stack_offset); - compiler.add_node(NODE_VALUE_V, make_float3(0, 0, 0)); + compiler.add_node(NODE_VALUE_V, make_float3(TEX_IMAGE_MISSING_R, + TEX_IMAGE_MISSING_G, + TEX_IMAGE_MISSING_B)); } if(!alpha_out->links.empty()) - compiler.add_node(NODE_VALUE_F, __float_as_int(0.0f), alpha_out->stack_offset); + compiler.add_node(NODE_VALUE_F, __float_as_int(TEX_IMAGE_MISSING_A), alpha_out->stack_offset); } } diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py index ba38ed5b7be..a2f5610ff84 100644 --- a/release/scripts/startup/bl_ui/space_node.py +++ b/release/scripts/startup/bl_ui/space_node.py @@ -224,7 +224,7 @@ class NODE_PT_properties(Panel): class NODE_PT_quality(bpy.types.Panel): bl_space_type = 'NODE_EDITOR' bl_region_type = 'UI' - bl_label = "Quality" + bl_label = "Performance" @classmethod def poll(cls, context): @@ -240,7 +240,9 @@ class NODE_PT_quality(bpy.types.Panel): layout.prop(tree, "edit_quality", text="Edit") layout.prop(tree, "chunk_size") layout.prop(tree, "use_opencl") - + layout.prop(tree, "two_pass") + layout.prop(snode, "show_highlight") + class NODE_MT_node_color_presets(Menu): """Predefined node color""" diff --git a/source/blender/compositor/intern/COM_CompositorContext.cpp b/source/blender/compositor/intern/COM_CompositorContext.cpp index 56335630b80..fbdb4cd6b28 100644 --- a/source/blender/compositor/intern/COM_CompositorContext.cpp +++ b/source/blender/compositor/intern/COM_CompositorContext.cpp @@ -30,6 +30,7 @@ CompositorContext::CompositorContext() this->m_quality = COM_QUALITY_HIGH; this->m_hasActiveOpenCLDevices = false; this->m_activegNode = NULL; + this->m_fastCalculation = false; } const int CompositorContext::getFramenumber() const diff --git a/source/blender/compositor/intern/COM_CompositorContext.h b/source/blender/compositor/intern/COM_CompositorContext.h index 49acda811f1..2f6abf39985 100644 --- a/source/blender/compositor/intern/COM_CompositorContext.h +++ b/source/blender/compositor/intern/COM_CompositorContext.h @@ -73,6 +73,11 @@ private: * @brief does this system have active opencl devices? */ bool m_hasActiveOpenCLDevices; + + /** + * @brief Skip slow nodes + */ + bool m_fastCalculation; public: /** @@ -148,6 +153,9 @@ public: int getChunksize() { return this->getbNodeTree()->chunksize; } const int isColorManaged() const; + + void setFastCalculation(bool fastCalculation) {this->m_fastCalculation = fastCalculation;} + bool isFastCalculation() {return this->m_fastCalculation;} }; diff --git a/source/blender/compositor/intern/COM_Converter.cpp b/source/blender/compositor/intern/COM_Converter.cpp index c8b6503c9c5..4f7b7c233f9 100644 --- a/source/blender/compositor/intern/COM_Converter.cpp +++ b/source/blender/compositor/intern/COM_Converter.cpp @@ -118,7 +118,7 @@ #include "COM_ViewerNode.h" #include "COM_ZCombineNode.h" -Node *Converter::convert(bNode *b_node) +Node *Converter::convert(bNode *b_node, bool fast) { Node *node; @@ -126,6 +126,22 @@ Node *Converter::convert(bNode *b_node) node = new MuteNode(b_node); return node; } + if (fast) { + if (b_node->type == CMP_NODE_BLUR || + b_node->type == CMP_NODE_VECBLUR || + b_node->type == CMP_NODE_BILATERALBLUR || + b_node->type == CMP_NODE_DEFOCUS || + b_node->type == CMP_NODE_BOKEHBLUR || + b_node->type == CMP_NODE_GLARE || + b_node->type == CMP_NODE_DBLUR || + b_node->type == CMP_NODE_MOVIEDISTORTION || + b_node->type == CMP_NODE_LENSDIST || + b_node->type == CMP_NODE_DOUBLEEDGEMASK || + b_node->type == CMP_NODE_DILATEERODE) + { + return new MuteNode(b_node); + } + } switch (b_node->type) { case CMP_NODE_COMPOSITE: diff --git a/source/blender/compositor/intern/COM_Converter.h b/source/blender/compositor/intern/COM_Converter.h index dbe98871c50..15bda0839fa 100644 --- a/source/blender/compositor/intern/COM_Converter.h +++ b/source/blender/compositor/intern/COM_Converter.h @@ -42,7 +42,7 @@ public: * @see Node * @see MuteNode */ - static Node *convert(bNode *b_node); + static Node *convert(bNode *b_node, bool fast); /** * @brief This method will add a datetype conversion rule when the to-socket does not support the from-socket actual data type. diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.cpp b/source/blender/compositor/intern/COM_ExecutionGroup.cpp index 2d3d24b296f..e437b069e33 100644 --- a/source/blender/compositor/intern/COM_ExecutionGroup.cpp +++ b/source/blender/compositor/intern/COM_ExecutionGroup.cpp @@ -27,6 +27,8 @@ #include "BLI_math.h" #include "PIL_time.h" +#include "WM_api.h" +#include "WM_types.h" #include "COM_ExecutionGroup.h" #include "COM_InputSocket.h" @@ -347,6 +349,8 @@ void ExecutionGroup::execute(ExecutionSystem *graph) finished = false; startEvaluated = true; numberEvaluated++; + + WM_main_add_notifier(NC_WINDOW | ND_DRAW, NULL); } else if (state == COM_ES_SCHEDULED) { finished = false; diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.cpp b/source/blender/compositor/intern/COM_ExecutionSystem.cpp index 23e243187d5..ff841092848 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystem.cpp +++ b/source/blender/compositor/intern/COM_ExecutionSystem.cpp @@ -44,9 +44,10 @@ #include "MEM_guardedalloc.h" #endif -ExecutionSystem::ExecutionSystem(RenderData *rd, bNodeTree *editingtree, bool rendering) +ExecutionSystem::ExecutionSystem(RenderData *rd, bNodeTree *editingtree, bool rendering, bool fastcalculation) { this->m_context.setbNodeTree(editingtree); + this->m_context.setFastCalculation(fastcalculation); bNode *gnode; for (gnode = (bNode *)editingtree->nodes.first; gnode; gnode = (bNode *)gnode->next) { if (gnode->type == NODE_GROUP && gnode->typeinfo->group_edit_get(gnode)) { @@ -137,8 +138,10 @@ void ExecutionSystem::execute() WorkScheduler::start(this->m_context); executeGroups(COM_PRIORITY_HIGH); - executeGroups(COM_PRIORITY_MEDIUM); - executeGroups(COM_PRIORITY_LOW); + if (!this->getContext().isFastCalculation()) { + executeGroups(COM_PRIORITY_MEDIUM); + executeGroups(COM_PRIORITY_LOW); + } WorkScheduler::finish(); WorkScheduler::stop(); diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.h b/source/blender/compositor/intern/COM_ExecutionSystem.h index e51bd7f3026..209358ec786 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystem.h +++ b/source/blender/compositor/intern/COM_ExecutionSystem.h @@ -156,7 +156,7 @@ public: * @param editingtree [bNodeTree*] * @param rendering [true false] */ - ExecutionSystem(RenderData *rd, bNodeTree *editingtree, bool rendering); + ExecutionSystem(RenderData *rd, bNodeTree *editingtree, bool rendering, bool fastcalculation); /** * Destructor diff --git a/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp b/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp index 0f6ba1f4ac9..0abf7efdcfa 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp +++ b/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp @@ -49,7 +49,7 @@ void ExecutionSystemHelper::addbNodeTree(ExecutionSystem &system, int nodes_star /* add all nodes of the tree to the node list */ bNode *node = (bNode *)tree->nodes.first; while (node != NULL) { - addNode(nodes, node, isActiveGroup); + addNode(nodes, node, isActiveGroup, system.getContext().isFastCalculation()); node = (bNode *)node->next; } @@ -77,11 +77,11 @@ void ExecutionSystemHelper::addNode(vector<Node *>& nodes, Node *node) nodes.push_back(node); } -Node *ExecutionSystemHelper::addNode(vector<Node *>& nodes, bNode *b_node, bool inActiveGroup) +Node *ExecutionSystemHelper::addNode(vector<Node *>& nodes, bNode *b_node, bool inActiveGroup, bool fast) { Converter converter; Node *node; - node = converter.convert(b_node); + node = converter.convert(b_node, fast); node->setIsInActiveGroup(inActiveGroup); if (node != NULL) { addNode(nodes, node); diff --git a/source/blender/compositor/intern/COM_ExecutionSystemHelper.h b/source/blender/compositor/intern/COM_ExecutionSystemHelper.h index 4b65ed15577..bd34fe8ab02 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystemHelper.h +++ b/source/blender/compositor/intern/COM_ExecutionSystemHelper.h @@ -58,7 +58,7 @@ public: * @param bNode node to add * @return Node that represents the bNode or null when not able to convert. */ - static Node *addNode(vector<Node *>& nodes, bNode *b_node, bool isInActiveGroup); + static Node *addNode(vector<Node *>& nodes, bNode *b_node, bool isInActiveGroup, bool fast); /** * @brief Add a Node to a list diff --git a/source/blender/compositor/intern/COM_Node.cpp b/source/blender/compositor/intern/COM_Node.cpp index 15b8a3933a7..320baacb669 100644 --- a/source/blender/compositor/intern/COM_Node.cpp +++ b/source/blender/compositor/intern/COM_Node.cpp @@ -39,9 +39,9 @@ //#include <stdio.h> #include "COM_defines.h" -Node::Node(bNode *editorNode, bool create_sockets) +Node::Node(bNode *editorNode, bool create_sockets): NodeBase() { - this->m_editorNode = editorNode; + setbNode(editorNode); if (create_sockets) { bNodeSocket *input = (bNodeSocket *)editorNode->inputs.first; @@ -64,15 +64,6 @@ Node::Node(bNode *editorNode, bool create_sockets) } } } -Node::Node() -{ - this->m_editorNode = NULL; -} - -bNode *Node::getbNode() -{ - return this->m_editorNode; -} void Node::addSetValueOperation(ExecutionSystem *graph, InputSocket *inputsocket, int editorNodeInputSocketIndex) { diff --git a/source/blender/compositor/intern/COM_Node.h b/source/blender/compositor/intern/COM_Node.h index 5d6d232f37a..bc4a25db605 100644 --- a/source/blender/compositor/intern/COM_Node.h +++ b/source/blender/compositor/intern/COM_Node.h @@ -48,10 +48,6 @@ typedef pair<NodeIterator, NodeIterator> NodeRange; */ class Node : public NodeBase { private: - /** - * @brief stores the reference to the SDNA bNode struct - */ - bNode *m_editorNode; /** * @brief Is this node part of the active group @@ -60,12 +56,7 @@ private: public: Node(bNode *editorNode, bool create_sockets = true); - - /** - * @brief get the reference to the SDNA bNode struct - */ - bNode *getbNode(); - + /** * @brief Is this node in the active group (the group that is being edited) * @param isInActiveGroup @@ -137,9 +128,6 @@ public: */ OutputSocket *findOutputSocketBybNodeSocket(bNodeSocket *socket); protected: - - Node(); - void addPreviewOperation(ExecutionSystem *system, InputSocket *inputSocket); void addPreviewOperation(ExecutionSystem *system, OutputSocket *outputSocket); diff --git a/source/blender/compositor/intern/COM_NodeBase.cpp b/source/blender/compositor/intern/COM_NodeBase.cpp index 8dbda5f649c..5c2ce37bdea 100644 --- a/source/blender/compositor/intern/COM_NodeBase.cpp +++ b/source/blender/compositor/intern/COM_NodeBase.cpp @@ -33,7 +33,7 @@ NodeBase::NodeBase() { - /* pass */ + this->m_editorNode = NULL; } diff --git a/source/blender/compositor/intern/COM_NodeBase.h b/source/blender/compositor/intern/COM_NodeBase.h index 7095cda39e3..3c390f6bcdb 100644 --- a/source/blender/compositor/intern/COM_NodeBase.h +++ b/source/blender/compositor/intern/COM_NodeBase.h @@ -54,6 +54,11 @@ private: */ vector<OutputSocket *> m_outputsockets; + /** + * @brief stores the reference to the SDNA bNode struct + */ + bNode *m_editorNode; + protected: /** * @brief get access to the vector of input sockets @@ -74,6 +79,18 @@ public: virtual ~NodeBase(); /** + * @brief get the reference to the SDNA bNode struct + */ + bNode *getbNode() {return m_editorNode;} + + /** + * @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;} + + /** * @brief is this node an operation? * This is true when the instance is of the subclass NodeOperation. * @return [true:false] diff --git a/source/blender/compositor/intern/COM_NodeOperation.cpp b/source/blender/compositor/intern/COM_NodeOperation.cpp index 6ef8a5ff078..c3fa308971c 100644 --- a/source/blender/compositor/intern/COM_NodeOperation.cpp +++ b/source/blender/compositor/intern/COM_NodeOperation.cpp @@ -28,7 +28,7 @@ #include "COM_SocketConnection.h" #include "COM_defines.h" -NodeOperation::NodeOperation() +NodeOperation::NodeOperation() : NodeBase() { this->m_resolutionInputSocketIndex = 0; this->m_complex = false; diff --git a/source/blender/compositor/intern/COM_compositor.cpp b/source/blender/compositor/intern/COM_compositor.cpp index 7282cf65bc3..9e48334bcca 100644 --- a/source/blender/compositor/intern/COM_compositor.cpp +++ b/source/blender/compositor/intern/COM_compositor.cpp @@ -57,8 +57,23 @@ void COM_execute(RenderData *rd, bNodeTree *editingtree, int rendering) /* set progress bar to 0% and status to init compositing*/ editingtree->progress(editingtree->prh, 0.0); + bool twopass = (editingtree->flag&NTREE_TWO_PASS) > 0 || rendering; /* initialize execution system */ - ExecutionSystem *system = new ExecutionSystem(rd, editingtree, rendering); + if (twopass) { + ExecutionSystem *system = new ExecutionSystem(rd, editingtree, rendering, twopass); + system->execute(); + delete system; + + if (editingtree->test_break(editingtree->tbh)) { + // during editing multiple calls to this method can be triggered. + // make sure one the last one will be doing the work. + BLI_mutex_unlock(&compositorMutex); + return; + } + } + + + ExecutionSystem *system = new ExecutionSystem(rd, editingtree, rendering, false); system->execute(); delete system; diff --git a/source/blender/compositor/nodes/COM_BlurNode.cpp b/source/blender/compositor/nodes/COM_BlurNode.cpp index 1b541d81c33..5447652c238 100644 --- a/source/blender/compositor/nodes/COM_BlurNode.cpp +++ b/source/blender/compositor/nodes/COM_BlurNode.cpp @@ -49,6 +49,7 @@ void BlurNode::convertToOperations(ExecutionSystem *graph, CompositorContext *co if (data->filtertype == R_FILTER_FAST_GAUSS) { FastGaussianBlurOperation *operationfgb = new FastGaussianBlurOperation(); operationfgb->setData(data); + operationfgb->setbNode(editorNode); this->getInputSocket(0)->relinkConnections(operationfgb->getInputSocket(0), 0, graph); this->getInputSocket(1)->relinkConnections(operationfgb->getInputSocket(1), 1, graph); this->getOutputSocket(0)->relinkConnections(operationfgb->getOutputSocket(0)); @@ -58,12 +59,14 @@ void BlurNode::convertToOperations(ExecutionSystem *graph, CompositorContext *co else if (!data->bokeh) { GaussianXBlurOperation *operationx = new GaussianXBlurOperation(); operationx->setData(data); + operationx->setbNode(editorNode); operationx->setQuality(quality); this->getInputSocket(0)->relinkConnections(operationx->getInputSocket(0), 0, graph); this->getInputSocket(1)->relinkConnections(operationx->getInputSocket(1), 1, graph); graph->addOperation(operationx); GaussianYBlurOperation *operationy = new GaussianYBlurOperation(); operationy->setData(data); + operationy->setbNode(editorNode); operationy->setQuality(quality); this->getOutputSocket(0)->relinkConnections(operationy->getOutputSocket()); graph->addOperation(operationy); @@ -79,6 +82,7 @@ void BlurNode::convertToOperations(ExecutionSystem *graph, CompositorContext *co else { GaussianBokehBlurOperation *operation = new GaussianBokehBlurOperation(); operation->setData(data); + operation->setbNode(editorNode); this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph); this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, graph); operation->setQuality(quality); diff --git a/source/blender/compositor/nodes/COM_BokehBlurNode.cpp b/source/blender/compositor/nodes/COM_BokehBlurNode.cpp index 59ec9525fa6..0ea4b20c793 100644 --- a/source/blender/compositor/nodes/COM_BokehBlurNode.cpp +++ b/source/blender/compositor/nodes/COM_BokehBlurNode.cpp @@ -61,6 +61,7 @@ void BokehBlurNode::convertToOperations(ExecutionSystem *graph, CompositorContex 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()); // } diff --git a/source/blender/compositor/nodes/COM_DefocusNode.cpp b/source/blender/compositor/nodes/COM_DefocusNode.cpp index 461505871c6..4c6b3ad137b 100644 --- a/source/blender/compositor/nodes/COM_DefocusNode.cpp +++ b/source/blender/compositor/nodes/COM_DefocusNode.cpp @@ -46,6 +46,7 @@ void DefocusNode::convertToOperations(ExecutionSystem *graph, CompositorContext NodeDefocus *data = (NodeDefocus *)node->storage; NodeOperation *radiusOperation; + OutputSocket * depthOperation; if (data->no_zbuf) { MathMultiplyOperation *multiply = new MathMultiplyOperation(); SetValueOperation *multiplier = new SetValueOperation(); @@ -63,6 +64,7 @@ void DefocusNode::convertToOperations(ExecutionSystem *graph, CompositorContext graph->addOperation(maxRadius); graph->addOperation(minimize); radiusOperation = minimize; + depthOperation = minimize->getOutputSocket(0); } else { ConvertDepthToRadiusOperation *converter = new ConvertDepthToRadiusOperation(); @@ -72,6 +74,7 @@ void DefocusNode::convertToOperations(ExecutionSystem *graph, CompositorContext this->getInputSocket(1)->relinkConnections(converter->getInputSocket(0), 1, graph); graph->addOperation(converter); radiusOperation = converter; + depthOperation = converter->getInputSocket(0)->getConnection()->getFromSocket(); } BokehImageOperation *bokeh = new BokehImageOperation(); @@ -89,7 +92,15 @@ void DefocusNode::convertToOperations(ExecutionSystem *graph, CompositorContext bokeh->setData(bokehdata); bokeh->deleteDataOnFinish(); graph->addOperation(bokeh); - + +#ifdef COM_DEFOCUS_SEARCH + InverseSearchRadiusOperation *search = new InverseSearchRadiusOperation(); + addLink(graph, radiusOperation->getOutputSocket(0), search->getInputSocket(0)); + addLink(graph, depthOperation, search->getInputSocket(1)); + search->setMaxBlur(data->maxblur); + search->setThreshold(data->bthresh); + graph->addOperation(search); +#endif VariableSizeBokehBlurOperation *operation = new VariableSizeBokehBlurOperation(); if (data->preview) { operation->setQuality(COM_QUALITY_LOW); @@ -97,10 +108,14 @@ void DefocusNode::convertToOperations(ExecutionSystem *graph, CompositorContext operation->setQuality(context->getQuality()); } operation->setMaxBlur(data->maxblur); + operation->setbNode(node); operation->setThreshold(data->bthresh); addLink(graph, bokeh->getOutputSocket(), operation->getInputSocket(1)); addLink(graph, radiusOperation->getOutputSocket(), operation->getInputSocket(2)); - addLink(graph, radiusOperation->getInputSocket(0)->getConnection()->getFromSocket(), operation->getInputSocket(3)); + addLink(graph, depthOperation, operation->getInputSocket(3)); +#ifdef COM_DEFOCUS_SEARCH + addLink(graph, search->getOutputSocket(), operation->getInputSocket(4)); +#endif if (data->gamco) { GammaCorrectOperation *correct = new GammaCorrectOperation(); GammaUncorrectOperation *inverse = new GammaUncorrectOperation(); @@ -115,6 +130,5 @@ void DefocusNode::convertToOperations(ExecutionSystem *graph, CompositorContext this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph); this->getOutputSocket()->relinkConnections(operation->getOutputSocket()); } - graph->addOperation(operation); } diff --git a/source/blender/compositor/nodes/COM_DilateErodeNode.cpp b/source/blender/compositor/nodes/COM_DilateErodeNode.cpp index 3f4e3736bbe..043ae367fbb 100644 --- a/source/blender/compositor/nodes/COM_DilateErodeNode.cpp +++ b/source/blender/compositor/nodes/COM_DilateErodeNode.cpp @@ -40,6 +40,7 @@ void DilateErodeNode::convertToOperations(ExecutionSystem *graph, CompositorCont bNode *editorNode = this->getbNode(); if (editorNode->custom1 == CMP_NODE_DILATEERODE_DISTANCE_THRESH) { DilateErodeThresholdOperation *operation = new DilateErodeThresholdOperation(); + operation->setbNode(editorNode); operation->setDistance(editorNode->custom2); operation->setInset(editorNode->custom3); @@ -59,6 +60,7 @@ void DilateErodeNode::convertToOperations(ExecutionSystem *graph, CompositorCont else if (editorNode->custom1 == CMP_NODE_DILATEERODE_DISTANCE) { if (editorNode->custom2 > 0) { DilateDistanceOperation *operation = new DilateDistanceOperation(); + operation->setbNode(editorNode); operation->setDistance(editorNode->custom2); this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph); this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0)); @@ -66,6 +68,7 @@ void DilateErodeNode::convertToOperations(ExecutionSystem *graph, CompositorCont } else { ErodeDistanceOperation *operation = new ErodeDistanceOperation(); + operation->setbNode(editorNode); operation->setDistance(-editorNode->custom2); this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph); this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0)); @@ -90,12 +93,14 @@ void DilateErodeNode::convertToOperations(ExecutionSystem *graph, CompositorCont } GaussianAlphaXBlurOperation *operationx = new GaussianAlphaXBlurOperation(); + operationx->setbNode(editorNode); operationx->setData(data); operationx->setQuality(quality); this->getInputSocket(0)->relinkConnections(operationx->getInputSocket(0), 0, graph); // this->getInputSocket(1)->relinkConnections(operationx->getInputSocket(1), 1, graph); // no size input yet graph->addOperation(operationx); GaussianAlphaYBlurOperation *operationy = new GaussianAlphaYBlurOperation(); + operationy->setbNode(editorNode); operationy->setData(data); operationy->setQuality(quality); this->getOutputSocket(0)->relinkConnections(operationy->getOutputSocket()); @@ -127,6 +132,7 @@ void DilateErodeNode::convertToOperations(ExecutionSystem *graph, CompositorCont else { if (editorNode->custom2 > 0) { DilateStepOperation *operation = new DilateStepOperation(); + operation->setbNode(editorNode); operation->setIterations(editorNode->custom2); this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph); this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0)); @@ -134,6 +140,7 @@ void DilateErodeNode::convertToOperations(ExecutionSystem *graph, CompositorCont } else { ErodeStepOperation *operation = new ErodeStepOperation(); + operation->setbNode(editorNode); operation->setIterations(-editorNode->custom2); this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph); this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0)); diff --git a/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.cpp b/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.cpp index 57c319e7630..ab1d83385c7 100644 --- a/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.cpp +++ b/source/blender/compositor/nodes/COM_DoubleEdgeMaskNode.cpp @@ -36,6 +36,7 @@ void DoubleEdgeMaskNode::convertToOperations(ExecutionSystem *system, Compositor bNode *bnode = this->getbNode(); operation = new DoubleEdgeMaskOperation(); + operation->setbNode(bnode); operation->setAdjecentOnly(bnode->custom1); operation->setKeepInside(bnode->custom2); diff --git a/source/blender/compositor/nodes/COM_FilterNode.cpp b/source/blender/compositor/nodes/COM_FilterNode.cpp index 23f87805821..021ec6c2508 100644 --- a/source/blender/compositor/nodes/COM_FilterNode.cpp +++ b/source/blender/compositor/nodes/COM_FilterNode.cpp @@ -73,7 +73,7 @@ void FilterNode::convertToOperations(ExecutionSystem *graph, CompositorContext * operation->set3x3Filter(0, 0, 0, 0, 1, 0, 0, 0, 0); break; } - + operation->setbNode(this->getbNode()); inputImageSocket->relinkConnections(operation->getInputSocket(0), 1, graph); inputSocket->relinkConnections(operation->getInputSocket(1), 0, graph); outputSocket->relinkConnections(operation->getOutputSocket()); diff --git a/source/blender/compositor/nodes/COM_GlareNode.cpp b/source/blender/compositor/nodes/COM_GlareNode.cpp index 7b34fa4d286..8782e6bb6d9 100644 --- a/source/blender/compositor/nodes/COM_GlareNode.cpp +++ b/source/blender/compositor/nodes/COM_GlareNode.cpp @@ -63,6 +63,8 @@ void GlareNode::convertToOperations(ExecutionSystem *system, CompositorContext * SetValueOperation *mixvalueoperation = new SetValueOperation(); MixGlareOperation *mixoperation = new MixGlareOperation(); mixoperation->getInputSocket(2)->setResizeMode(COM_SC_FIT); + thresholdOperation->setbNode(node); + glareoperation->setbNode(node); this->getInputSocket(0)->relinkConnections(thresholdOperation->getInputSocket(0), 0, system); addLink(system, thresholdOperation->getOutputSocket(), glareoperation->getInputSocket(0)); diff --git a/source/blender/compositor/nodes/COM_KeyingNode.cpp b/source/blender/compositor/nodes/COM_KeyingNode.cpp index cc6fc6e1236..7c39765fbf1 100644 --- a/source/blender/compositor/nodes/COM_KeyingNode.cpp +++ b/source/blender/compositor/nodes/COM_KeyingNode.cpp @@ -74,9 +74,11 @@ OutputSocket *KeyingNode::setupPreBlur(ExecutionSystem *graph, InputSocket *inpu blurXOperation->setSize(size); blurXOperation->setAxis(KeyingBlurOperation::BLUR_AXIS_X); + blurXOperation->setbNode(this->getbNode()); blurYOperation->setSize(size); blurYOperation->setAxis(KeyingBlurOperation::BLUR_AXIS_Y); + blurYOperation->setbNode(this->getbNode()); addLink(graph, separateOperation->getOutputSocket(), blurXOperation->getInputSocket(0)); addLink(graph, blurXOperation->getOutputSocket(), blurYOperation->getInputSocket(0)); @@ -104,9 +106,11 @@ OutputSocket *KeyingNode::setupPostBlur(ExecutionSystem *graph, OutputSocket *po blurXOperation->setSize(size); blurXOperation->setAxis(KeyingBlurOperation::BLUR_AXIS_X); + blurXOperation->setbNode(this->getbNode()); blurYOperation->setSize(size); blurYOperation->setAxis(KeyingBlurOperation::BLUR_AXIS_Y); + blurYOperation->setbNode(this->getbNode()); addLink(graph, postBlurInput, blurXOperation->getInputSocket(0)); addLink(graph, blurXOperation->getOutputSocket(), blurYOperation->getInputSocket(0)); @@ -129,6 +133,7 @@ OutputSocket *KeyingNode::setupDilateErode(ExecutionSystem *graph, OutputSocket dilateErodeOperation = new ErodeDistanceOperation(); dilateErodeOperation->setDistance(-distance); } + dilateErodeOperation->setbNode(this->getbNode()); addLink(graph, dilateErodeInput, dilateErodeOperation->getInputSocket(0)); @@ -161,14 +166,16 @@ OutputSocket *KeyingNode::setupFeather(ExecutionSystem *graph, CompositorContext operationx->setSize(1.0f); operationx->setSubtract(distance < 0); operationx->setFalloff(falloff); + operationx->setbNode(this->getbNode()); graph->addOperation(operationx); - + GaussianAlphaYBlurOperation *operationy = new GaussianAlphaYBlurOperation(); operationy->setData(data); operationy->setQuality(quality); operationy->setSize(1.0f); operationy->setSubtract(distance < 0); operationy->setFalloff(falloff); + operationy->setbNode(this->getbNode()); graph->addOperation(operationy); addLink(graph, featherInput, operationx->getInputSocket(0)); diff --git a/source/blender/compositor/nodes/COM_KeyingScreenNode.cpp b/source/blender/compositor/nodes/COM_KeyingScreenNode.cpp index 0fb8d45d066..cd1f79235ea 100644 --- a/source/blender/compositor/nodes/COM_KeyingScreenNode.cpp +++ b/source/blender/compositor/nodes/COM_KeyingScreenNode.cpp @@ -45,6 +45,7 @@ void KeyingScreenNode::convertToOperations(ExecutionSystem *graph, CompositorCon // always connect the output image KeyingScreenOperation *operation = new KeyingScreenOperation(); + operation->setbNode(editorNode); if (outputScreen->isConnected()) { outputScreen->relinkConnections(operation->getOutputSocket()); diff --git a/source/blender/compositor/nodes/COM_LensDistortionNode.cpp b/source/blender/compositor/nodes/COM_LensDistortionNode.cpp index bb431f86897..4870e252b74 100644 --- a/source/blender/compositor/nodes/COM_LensDistortionNode.cpp +++ b/source/blender/compositor/nodes/COM_LensDistortionNode.cpp @@ -37,7 +37,7 @@ void LensDistortionNode::convertToOperations(ExecutionSystem *graph, CompositorC NodeLensDist *data = (NodeLensDist *)editorNode->storage; if (data->proj) { ProjectorLensDistortionOperation *operation = new ProjectorLensDistortionOperation(); - + operation->setbNode(editorNode); this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, graph); this->getInputSocket(2)->relinkConnections(operation->getInputSocket(1), 2, graph); this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0)); @@ -48,6 +48,7 @@ void LensDistortionNode::convertToOperations(ExecutionSystem *graph, CompositorC } else { ScreenLensDistortionOperation *operation = new ScreenLensDistortionOperation(); + operation->setbNode(editorNode); operation->setData(data); if (!(this->getInputSocket(1)->isConnected() || this->getInputSocket(2)->isConnected())) { diff --git a/source/blender/compositor/nodes/COM_MaskNode.cpp b/source/blender/compositor/nodes/COM_MaskNode.cpp index 13037b61a56..b6300300f6f 100644 --- a/source/blender/compositor/nodes/COM_MaskNode.cpp +++ b/source/blender/compositor/nodes/COM_MaskNode.cpp @@ -45,7 +45,7 @@ void MaskNode::convertToOperations(ExecutionSystem *graph, CompositorContext *co // always connect the output image MaskOperation *operation = new MaskOperation(); - + operation->setbNode(editorNode); operation->setMaskWidth(data->xsch * data->size / 100.0f); operation->setMaskHeight(data->ysch * data->size / 100.0f); diff --git a/source/blender/compositor/nodes/COM_TonemapNode.cpp b/source/blender/compositor/nodes/COM_TonemapNode.cpp index a1f33ed464b..68e322e9dcf 100644 --- a/source/blender/compositor/nodes/COM_TonemapNode.cpp +++ b/source/blender/compositor/nodes/COM_TonemapNode.cpp @@ -34,7 +34,7 @@ void TonemapNode::convertToOperations(ExecutionSystem *system, CompositorContext { NodeTonemap *data = (NodeTonemap *)this->getbNode()->storage; TonemapOperation *operation = data->type == 1 ? new PhotoreceptorTonemapOperation() : new TonemapOperation(); - + operation->setbNode(this->getbNode()); operation->setData(data); this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, system); this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket(0)); diff --git a/source/blender/compositor/nodes/COM_VectorBlurNode.cpp b/source/blender/compositor/nodes/COM_VectorBlurNode.cpp index 5ef384a9984..07c8120b1d2 100644 --- a/source/blender/compositor/nodes/COM_VectorBlurNode.cpp +++ b/source/blender/compositor/nodes/COM_VectorBlurNode.cpp @@ -34,6 +34,7 @@ void VectorBlurNode::convertToOperations(ExecutionSystem *system, CompositorCont bNode *node = this->getbNode(); NodeBlurData *vectorBlurSettings = (NodeBlurData *)node->storage; VectorBlurOperation *operation = new VectorBlurOperation(); + operation->setbNode(node); operation->setVectorBlurSettings(vectorBlurSettings); operation->setQuality(context->getQuality()); this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, system); diff --git a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp index 9eb004b3686..46101f6355d 100644 --- a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp @@ -33,6 +33,9 @@ VariableSizeBokehBlurOperation::VariableSizeBokehBlurOperation() : NodeOperation this->addInputSocket(COM_DT_COLOR, COM_SC_NO_RESIZE); // do not resize the bokeh image. this->addInputSocket(COM_DT_VALUE); // radius this->addInputSocket(COM_DT_VALUE); // depth +#ifdef COM_DEFOCUS_SEARCH + this->addInputSocket(COM_DT_COLOR, COM_SC_NO_RESIZE); // inverse search radius optimization structure. +#endif this->addOutputSocket(COM_DT_COLOR); this->setComplex(true); @@ -42,6 +45,9 @@ VariableSizeBokehBlurOperation::VariableSizeBokehBlurOperation() : NodeOperation this->m_inputDepthProgram = NULL; this->m_maxBlur = 32.0f; this->m_threshold = 1.0f; +#ifdef COM_DEFOCUS_SEARCH + this->m_inputSearchProgram = NULL; +#endif } @@ -51,6 +57,9 @@ void VariableSizeBokehBlurOperation::initExecution() this->m_inputBokehProgram = getInputSocketReader(1); this->m_inputSizeProgram = getInputSocketReader(2); this->m_inputDepthProgram = getInputSocketReader(3); +#ifdef COM_DEFOCUS_SEARCH + this->m_inputSearchProgram = getInputSocketReader(4); +#endif QualityStepHelper::initExecution(COM_QH_INCREASE); } @@ -63,10 +72,19 @@ void VariableSizeBokehBlurOperation::executePixel(float *color, int x, int y, Me float multiplier_accum[4] = {0.0f, 0.0f, 0.0f, 0.0f}; float color_accum[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - int miny = y - this->m_maxBlur; - int maxy = y + this->m_maxBlur; - int minx = x - this->m_maxBlur; - int maxx = x + this->m_maxBlur; +#ifdef COM_DEFOCUS_SEARCH + float search[4]; + this->inputSearchProgram->read(search, x/InverseSearchRadiusOperation::DIVIDER, y/InverseSearchRadiusOperation::DIVIDER, inputBuffers, NULL); + int minx = search[0]; + int miny = search[1]; + int maxx = search[2]; + int maxy = search[3]; +#else + int minx = MAX2(x - this->m_maxBlur, 0.0f); + int miny = MAX2(y - this->m_maxBlur, 0.0f); + int maxx = MIN2(x + this->m_maxBlur, m_width); + int maxy = MIN2(y + this->m_maxBlur, m_height); +#endif { this->m_inputSizeProgram->read(tempSize, x, y, COM_PS_NEAREST, inputBuffers); this->m_inputDepthProgram->read(tempDepth, x, y, COM_PS_NEAREST, inputBuffers); @@ -80,9 +98,9 @@ void VariableSizeBokehBlurOperation::executePixel(float *color, int x, int y, Me for (int nx = minx; nx < maxx; nx += QualityStepHelper::getStep()) { if (nx >= 0 && nx < this->getWidth() && ny >= 0 && ny < getHeight()) { this->m_inputDepthProgram->read(tempDepth, nx, ny, COM_PS_NEAREST, inputBuffers); - this->m_inputSizeProgram->read(tempSize, nx, ny, COM_PS_NEAREST, inputBuffers); - float size = tempSize[0]; if (tempDepth[0] < centerDepth) { + this->m_inputSizeProgram->read(tempSize, nx, ny, COM_PS_NEAREST, inputBuffers); + float size = tempSize[0]; if ((sizeCenter > this->m_threshold && size > this->m_threshold) || size <= this->m_threshold) { float dx = nx - x; float dy = ny - y; @@ -115,6 +133,10 @@ void VariableSizeBokehBlurOperation::deinitExecution() this->m_inputProgram = NULL; this->m_inputBokehProgram = NULL; this->m_inputSizeProgram = NULL; + this->m_inputDepthProgram = NULL; +#ifdef COM_DEFOCUS_SEARCH + this->m_inputSearchProgram = NULL; +#endif } bool VariableSizeBokehBlurOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) @@ -130,6 +152,7 @@ bool VariableSizeBokehBlurOperation::determineDependingAreaOfInterest(rcti *inpu bokehInput.xmin = 0; bokehInput.ymax = 512; bokehInput.ymin = 0; + NodeOperation *operation = getInputOperation(2); if (operation->determineDependingAreaOfInterest(&newInput, readOperation, output) ) { @@ -143,9 +166,118 @@ bool VariableSizeBokehBlurOperation::determineDependingAreaOfInterest(rcti *inpu if (operation->determineDependingAreaOfInterest(&newInput, readOperation, output) ) { return true; } +#ifdef COM_DEFOCUS_SEARCH + rcti searchInput; + searchInput.xmax = (input->xmax/InverseSearchRadiusOperation::DIVIDER)+1; + searchInput.xmin = (input->xmin/InverseSearchRadiusOperation::DIVIDER)-1; + searchInput.ymax = (input->ymax/InverseSearchRadiusOperation::DIVIDER)+1; + searchInput.ymin = (input->ymin/InverseSearchRadiusOperation::DIVIDER)-1; + operation = getInputOperation(4); + if (operation->determineDependingAreaOfInterest(&searchInput, readOperation, output) ) { + return true; + } +#endif operation = getInputOperation(0); if (operation->determineDependingAreaOfInterest(&newInput, readOperation, output) ) { return true; } return false; } + +#ifdef COM_DEFOCUS_SEARCH +// InverseSearchRadiusOperation +InverseSearchRadiusOperation::InverseSearchRadiusOperation() : NodeOperation() +{ + this->addInputSocket(COM_DT_VALUE, COM_SC_NO_RESIZE); // radius + this->addInputSocket(COM_DT_VALUE, COM_SC_NO_RESIZE); // depth + this->addOutputSocket(COM_DT_COLOR); + this->setComplex(true); + this->inputRadius = NULL; + this->inputDepth = NULL; +} + +void InverseSearchRadiusOperation::initExecution() +{ + this->inputRadius = this->getInputSocketReader(0); + this->inputDepth = this->getInputSocketReader(1); +} + +void* InverseSearchRadiusOperation::initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers) +{ + MemoryBuffer * data = new MemoryBuffer(NULL, rect); + int x, y; + float width = this->inputRadius->getWidth(); + float height = this->inputRadius->getHeight(); + + for (x = rect->xmin; x < rect->xmax ; x++) { + for (y = rect->ymin; y < rect->ymax ; y++) { + float[4] temp; + int rx = x * DIVIDER; + int ry = y * DIVIDER; + this->inputRadius->read(temp, rx, ry, memoryBuffers, NULL); + float centerRadius = temp[0]; + this->inputDepth->read(temp, rx, ry, memoryBuffers, NULL); + float centerDepth = temp[0]; + t[0] = MAX2(rx - this->maxBlur, 0.0f); + t[1] = MAX2(ry - this->maxBlur, 0.0f); + t[2] = MIN2(rx + this->maxBlur, width); + t[3] = MIN2(ry + this->maxBlur, height); + int minx = t[0]; + int miny = t[1]; + int maxx = t[2]; + int maxy = t[3]; + int sminx = rx; + int smaxx = rx; + int sminy = ry; + int smaxy = ry; + for (int nx = minx ; nx < maxx ; nx ++) { + for (int ny = miny ; ny < maxy ; ny ++) { + this->inputRadius->read(temp, nx, ny, memoryBuffers, NULL); + if (nx < rx && temp[0]) + + } + } + float t[4]; + data->writePixel(x, y, t); + } + } + return data; +} + +void InverseSearchRadiusOperation::executePixel(float *color, int x, int y, MemoryBuffer *inputBuffers[], void *data) +{ + MemoryBuffer *buffer = (MemoryBuffer*)data; + buffer->read(color, x, y); +} + +void InverseSearchRadiusOperation::deinitializeTileData(rcti *rect, MemoryBuffer **memoryBuffers, void *data) +{ + if (data) { + MemoryBuffer* mb = (MemoryBuffer*)data; + delete mb; + } +} + +void InverseSearchRadiusOperation::deinitExecution() +{ + this->inputRadius = NULL; + this->inputDepth = NULL; +} + +void InverseSearchRadiusOperation::determineResolution(unsigned int resolution[], unsigned int preferredResolution[]) +{ + NodeOperation::determineResolution(resolution, preferredResolution); + resolution[0] = resolution[0] / DIVIDER; + resolution[1] = resolution[1] / DIVIDER; +} + +bool InverseSearchRadiusOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) +{ + rcti newRect; + newRect.ymin = input->ymin*DIVIDER; + newRect.ymax = input->ymax*DIVIDER; + newRect.xmin = input->xmin*DIVIDER; + newRect.xmax = input->xmax*DIVIDER; + return NodeOperation::determineDependingAreaOfInterest(&newRect, readOperation, output); +} +#endif diff --git a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.h b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.h index 8e59a43fcb1..4bf597ff831 100644 --- a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.h +++ b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.h @@ -25,6 +25,7 @@ #include "COM_NodeOperation.h" #include "COM_QualityStepHelper.h" + class VariableSizeBokehBlurOperation : public NodeOperation, public QualityStepHelper { private: int m_maxBlur; @@ -33,6 +34,9 @@ private: SocketReader *m_inputBokehProgram; SocketReader *m_inputSizeProgram; SocketReader *m_inputDepthProgram; +#ifdef COM_DEFOCUS_SEARCH + SocketReader *inputSearchProgram; +#endif public: VariableSizeBokehBlurOperation(); @@ -60,4 +64,42 @@ public: }; + +#ifdef COM_DEFOCUS_SEARCH +class InverseSearchRadiusOperation : public NodeOperation { +private: + int maxBlur; + float threshold; + SocketReader *inputDepth; + SocketReader *inputRadius; +public: + static const int DIVIDER = 4; + + InverseSearchRadiusOperation(); + + /** + * the inner loop of this program + */ + void executePixel(float *color, int x, int y, MemoryBuffer * inputBuffers[], void *data); + + /** + * Initialize the execution + */ + void initExecution(); + void* initializeTileData(rcti *rect, MemoryBuffer **memoryBuffers); + void deinitializeTileData(rcti *rect, MemoryBuffer **memoryBuffers, void *data); + + /** + * Deinitialize the execution + */ + void deinitExecution(); + + bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); + void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]); + + void setMaxBlur(int maxRadius) { this->maxBlur = maxRadius; } + + void setThreshold(float threshold) { this->threshold = threshold; } +}; +#endif #endif diff --git a/source/blender/compositor/operations/COM_WriteBufferOperation.cpp b/source/blender/compositor/operations/COM_WriteBufferOperation.cpp index 7259db34134..b23c1a02b9f 100644 --- a/source/blender/compositor/operations/COM_WriteBufferOperation.cpp +++ b/source/blender/compositor/operations/COM_WriteBufferOperation.cpp @@ -63,6 +63,9 @@ void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber, Me MemoryBuffer *memoryBuffer = this->m_memoryProxy->getBuffer(); float *buffer = memoryBuffer->getBuffer(); if (this->m_input->isComplex()) { + bNode* bnode = this->m_input->getbNode(); +// if (bnode&& bnode->new_node) bnode->new_node->highlight++; + void *data = this->m_input->initializeTileData(rect, memoryBuffers); int x1 = rect->xmin; int y1 = rect->ymin; @@ -87,6 +90,7 @@ void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber, Me this->m_input->deinitializeTileData(rect, memoryBuffers, data); data = NULL; } +// if (bnode&& bnode->new_node) bnode->new_node->highlight++; } else { int x1 = rect->xmin; @@ -139,6 +143,8 @@ void WriteBufferOperation::executeOpenCLRegion(OpenCLDevice* device, rcti *rect, list<cl_mem> *clMemToCleanUp = new list<cl_mem>(); clMemToCleanUp->push_back(clOutputBuffer); list<cl_kernel> *clKernelsToCleanUp = new list<cl_kernel>(); + bNode* bnode = this->m_input->getbNode(); +// if (bnode&& bnode->new_node) bnode->new_node->highlight++; this->m_input->executeOpenCL(device, outputBuffer, clOutputBuffer, inputMemoryBuffers, clMemToCleanUp, clKernelsToCleanUp); @@ -156,7 +162,8 @@ void WriteBufferOperation::executeOpenCLRegion(OpenCLDevice* device, rcti *rect, if (error != CL_SUCCESS) { printf("CLERROR[%d]: %s\n", error, clewErrorString(error)); } this->getMemoryProxy()->getBuffer()->copyContentFrom(outputBuffer); - + +// if (bnode&& bnode->new_node) bnode->new_node->highlight++; // STEP 4 diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index ab127c3faf3..92e3c0201e0 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -724,6 +724,12 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN if (node->flag & NODE_MUTED) UI_ThemeColorBlend(color_id, TH_REDALERT, 0.5f); + if (ntree->type == NTREE_COMPOSIT && (snode->flag&SNODE_SHOW_HIGHLIGHT)) { + if (node->highlight) { + UI_ThemeColorBlend(color_id, TH_ACTIVE, 0.5f); + node->highlight = 0; + } + } uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT); uiRoundBox(rct->xmin, rct->ymax-NODE_DY, rct->xmax, rct->ymax, BASIS_RAD); @@ -805,7 +811,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN glDisable(GL_BLEND); /* outline active and selected emphasis */ - if ( node->flag & (NODE_ACTIVE|SELECT) ) { + if ( node->flag & (NODE_ACTIVE|SELECT)) { glEnable(GL_BLEND); glEnable(GL_LINE_SMOOTH); @@ -862,7 +868,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN node->block= NULL; } -static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, bNode *node) +static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeTree *ntree, bNode *node) { bNodeSocket *sock; rctf *rct= &node->totr; @@ -879,10 +885,18 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b UI_ThemeColor(color_id); if (node->flag & NODE_MUTED) UI_ThemeColorBlend(color_id, TH_REDALERT, 0.5f); + + if (ntree->type == NTREE_COMPOSIT && (snode->flag&SNODE_SHOW_HIGHLIGHT)) { + if (node->highlight) { + UI_ThemeColorBlend(color_id, TH_ACTIVE, 0.5f); + node->highlight = 0; + } + } + uiRoundBox(rct->xmin, rct->ymin, rct->xmax, rct->ymax, hiddenrad); /* outline active and selected emphasis */ - if ( node->flag & (NODE_ACTIVE|SELECT) ) { + if ( node->flag & (NODE_ACTIVE|SELECT)) { glEnable(GL_BLEND); glEnable(GL_LINE_SMOOTH); @@ -1005,7 +1019,7 @@ void node_set_cursor(wmWindow *win, SpaceNode *snode) void node_draw_default(const bContext *C, ARegion *ar, SpaceNode *snode, bNodeTree *ntree, bNode *node) { if (node->flag & NODE_HIDDEN) - node_draw_hidden(C, ar, snode, node); + node_draw_hidden(C, ar, snode, ntree, node); else node_draw_basis(C, ar, snode, ntree, node); } diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 23413bce1bc..84b30e295f0 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -177,10 +177,11 @@ typedef struct bNode { char label[64]; /* custom user-defined label, MAX_NAME */ short custom1, custom2; /* to be abused for buttons */ float custom3, custom4; + int highlight; /* 0 = not highlighted, 1-N = highlighted*/ + int pad; short need_exec, exec; /* need_exec is set as UI execution event, exec is flag during exec */ void *threaddata; /* optional extra storage for use in thread (read only then!) */ - rctf totr; /* entire boundbox */ rctf butr; /* optional buttons area */ rctf prvr; /* optional preview area */ @@ -302,6 +303,7 @@ typedef struct bNodeTree { /* ntree->flag */ #define NTREE_DS_EXPAND 1 /* for animation editors */ #define NTREE_COM_OPENCL 2 /* use opencl */ +#define NTREE_TWO_PASS 4 /* two pass */ /* XXX not nice, but needed as a temporary flags * for group updates after library linking. */ diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 05cfc17b00d..6183300a813 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -879,11 +879,12 @@ typedef struct SpaceNode { /* snode->flag */ typedef enum eSpaceNode_Flag { - SNODE_BACKDRAW = (1 << 1), -/* SNODE_DISPGP = (1 << 2), */ /* XXX: Grease Pencil - deprecated? */ - SNODE_USE_ALPHA = (1 << 3), - SNODE_SHOW_ALPHA = (1 << 4), - SNODE_AUTO_RENDER = (1 << 5), + SNODE_BACKDRAW = (1 << 1), +/* SNODE_DISPGP = (1 << 2), */ /* XXX: Grease Pencil - deprecated? */ + SNODE_USE_ALPHA = (1 << 3), + SNODE_SHOW_ALPHA = (1 << 4), + SNODE_AUTO_RENDER = (1 << 5), + SNODE_SHOW_HIGHLIGHT = (1 << 6), } eSpaceNode_Flag; /* snode->texfrom */ diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 5c55e642cb1..c9810cafce1 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -4296,6 +4296,10 @@ static void rna_def_composite_nodetree(BlenderRNA *brna) prop = RNA_def_property(srna, "use_opencl", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", NTREE_COM_OPENCL); RNA_def_property_ui_text(prop, "OpenCL", "Enable GPU calculations"); + + prop = RNA_def_property(srna, "two_pass", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", NTREE_TWO_PASS); + RNA_def_property_ui_text(prop, "Two Pass", "Use two pass execution during editing; First calculate fast nodes, second pass calculate all nodes."); } static void rna_def_shader_nodetree(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index ef3028674b7..33bcd116d39 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -2937,6 +2937,11 @@ static void rna_def_space_node(BlenderRNA *brna) RNA_def_property_pointer_sdna(prop, NULL, "view_settings"); RNA_def_property_struct_type(prop, "ColorManagedViewSettings"); RNA_def_property_ui_text(prop, "View Settings", "Color management settings used for displaying images on the display"); + + prop = RNA_def_property(srna, "show_highlight", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SNODE_SHOW_HIGHLIGHT); + RNA_def_property_ui_text(prop, "Highlight", "Highlight nodes that are being calculated"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NODE_VIEW, NULL); } static void rna_def_space_logic(BlenderRNA *brna) diff --git a/source/blender/nodes/composite/node_composite_tree.c b/source/blender/nodes/composite/node_composite_tree.c index 72112180bc8..58357bdd59d 100644 --- a/source/blender/nodes/composite/node_composite_tree.c +++ b/source/blender/nodes/composite/node_composite_tree.c @@ -118,7 +118,6 @@ static void update_node(bNodeTree *ntree, bNode *node) } } node->need_exec= 1; - /* individual node update call */ if (node->typeinfo->updatefunc) node->typeinfo->updatefunc(ntree, node); @@ -192,6 +191,8 @@ static void local_sync(bNodeTree *localtree, bNodeTree *ntree) /* move over the compbufs and previews */ for (lnode= localtree->nodes.first; lnode; lnode= lnode->next) { + lnode->new_node->new_node = lnode; + lnode->highlight = 0; if ( (lnode->exec & NODE_READY) && !(lnode->exec & NODE_SKIPPED) ) { if (ntreeNodeExists(ntree, lnode->new_node)) { @@ -200,6 +201,7 @@ static void local_sync(bNodeTree *localtree, bNodeTree *ntree) lnode->new_node->preview= lnode->preview; lnode->preview= NULL; } + } } } @@ -212,6 +214,7 @@ static void local_merge(bNodeTree *localtree, bNodeTree *ntree) /* move over the compbufs and previews */ for (lnode= localtree->nodes.first; lnode; lnode= lnode->next) { + lnode->highlight = 0; if (ntreeNodeExists(ntree, lnode->new_node)) { if (ELEM(lnode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) { if (lnode->id && (lnode->flag & NODE_DO_OUTPUT)) { |