diff options
Diffstat (limited to 'source/blender/compositor')
24 files changed, 216 insertions, 50 deletions
diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt index ba897a87f97..4b058a41f71 100644 --- a/source/blender/compositor/CMakeLists.txt +++ b/source/blender/compositor/CMakeLists.txt @@ -660,6 +660,6 @@ list(APPEND INC ${CMAKE_CURRENT_BINARY_DIR}/operations ) data_to_c(${CMAKE_CURRENT_SOURCE_DIR}/operations/COM_OpenCLKernels.cl - ${CMAKE_CURRENT_BINARY_DIR}/operations/COM_OpenCLKernels.cl.h SRC) + ${CMAKE_CURRENT_BINARY_DIR}/operations/COM_OpenCLKernels.cl.h SRC) blender_add_lib(bf_compositor "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/compositor/intern/COM_Converter.cpp b/source/blender/compositor/intern/COM_Converter.cpp index 80f5b4fc149..80ae952b87f 100644 --- a/source/blender/compositor/intern/COM_Converter.cpp +++ b/source/blender/compositor/intern/COM_Converter.cpp @@ -403,6 +403,7 @@ 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_ExecutionGroup.cpp b/source/blender/compositor/intern/COM_ExecutionGroup.cpp index 14fd7e0b6cf..82d1c7883e1 100644 --- a/source/blender/compositor/intern/COM_ExecutionGroup.cpp +++ b/source/blender/compositor/intern/COM_ExecutionGroup.cpp @@ -633,3 +633,13 @@ void ExecutionGroup::setViewerBorder(float xmin, float xmax, float ymin, float y ymin * this->m_height, ymax * this->m_height); } } + +void ExecutionGroup::setRenderBorder(float xmin, float xmax, float ymin, float ymax) +{ + NodeOperation *operation = this->getOutputNodeOperation(); + + if (operation->isOutputOperation(true) && !(operation->isViewerOperation() || operation->isPreviewOperation())) { + BLI_rcti_init(&this->m_viewerBorder, xmin * this->m_width, xmax * this->m_width, + ymin * this->m_height, ymax * this->m_height); + } +} diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.h b/source/blender/compositor/intern/COM_ExecutionGroup.h index b5f02e05be1..537dcb5974a 100644 --- a/source/blender/compositor/intern/COM_ExecutionGroup.h +++ b/source/blender/compositor/intern/COM_ExecutionGroup.h @@ -417,6 +417,8 @@ public: */ void setViewerBorder(float xmin, float xmax, float ymin, float ymax); + void setRenderBorder(float xmin, float xmax, float ymin, float ymax); + #ifdef WITH_CXX_GUARDEDALLOC MEM_CXX_CLASS_ALLOC_FUNCS("COM:ExecutionGroup") #endif diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.cpp b/source/blender/compositor/intern/COM_ExecutionSystem.cpp index 2d87845d254..450d1b03917 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystem.cpp +++ b/source/blender/compositor/intern/COM_ExecutionSystem.cpp @@ -95,6 +95,16 @@ ExecutionSystem::ExecutionSystem(RenderData *rd, bNodeTree *editingtree, bool re ExecutionGroup *executionGroup = this->m_groups[index]; executionGroup->determineResolution(resolution); + if (rendering) { + /* case when cropping to render border happens is handled in + * compositor output and render layer nodes + */ + if ((rd->mode & R_BORDER) && !(rd->mode & R_CROP)) { + executionGroup->setRenderBorder(rd->border.xmin, rd->border.xmax, + rd->border.ymin, rd->border.ymax); + } + } + if (use_viewer_border) { executionGroup->setViewerBorder(viewer_border->xmin, viewer_border->xmax, viewer_border->ymin, viewer_border->ymax); diff --git a/source/blender/compositor/intern/COM_NodeOperation.h b/source/blender/compositor/intern/COM_NodeOperation.h index 60ffadf60f7..26a382929cb 100644 --- a/source/blender/compositor/intern/COM_NodeOperation.h +++ b/source/blender/compositor/intern/COM_NodeOperation.h @@ -81,6 +81,9 @@ private: */ const bNodeTree *m_btree; + /** + * @brief set to truth when resolution for this operation is set + */ bool m_isResolutionSet; public: /** diff --git a/source/blender/compositor/intern/COM_compositor.cpp b/source/blender/compositor/intern/COM_compositor.cpp index 94a27e17b68..a0f660058f9 100644 --- a/source/blender/compositor/intern/COM_compositor.cpp +++ b/source/blender/compositor/intern/COM_compositor.cpp @@ -65,8 +65,10 @@ void COM_execute(RenderData *rd, bNodeTree *editingtree, int rendering, /* Make sure node tree has previews. * Don't create previews in advance, this is done when adding preview operations. + * Reserved preview size is determined by render output for now. */ - BKE_node_preview_init_tree(editingtree, COM_PREVIEW_SIZE, COM_PREVIEW_SIZE, FALSE); + float aspect = rd->xsch > 0 ? (float)rd->ysch / (float)rd->xsch : 1.0; + BKE_node_preview_init_tree(editingtree, COM_PREVIEW_SIZE, (int)(COM_PREVIEW_SIZE * aspect), FALSE); /* initialize workscheduler, will check if already done. TODO deinitialize somewhere */ bool use_opencl = (editingtree->flag & NTREE_COM_OPENCL); diff --git a/source/blender/compositor/nodes/COM_CompositorNode.cpp b/source/blender/compositor/nodes/COM_CompositorNode.cpp index a78f96adfc6..f555e53f156 100644 --- a/source/blender/compositor/nodes/COM_CompositorNode.cpp +++ b/source/blender/compositor/nodes/COM_CompositorNode.cpp @@ -32,6 +32,8 @@ CompositorNode::CompositorNode(bNode *editorNode) : Node(editorNode) void CompositorNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { bNode *editorNode = this->getbNode(); + bool is_active = (editorNode->flag & NODE_DO_OUTPUT_RECALC) || + context->isRendering(); InputSocket *imageSocket = this->getInputSocket(0); InputSocket *alphaSocket = this->getInputSocket(1); @@ -42,10 +44,11 @@ void CompositorNode::convertToOperations(ExecutionSystem *graph, CompositorConte compositorOperation->setRenderData(context->getRenderData()); compositorOperation->setbNodeTree(context->getbNodeTree()); compositorOperation->setIgnoreAlpha(editorNode->custom2 & CMP_NODE_OUTPUT_IGNORE_ALPHA); + compositorOperation->setActive(is_active); imageSocket->relinkConnections(compositorOperation->getInputSocket(0), 0, graph); alphaSocket->relinkConnections(compositorOperation->getInputSocket(1)); depthSocket->relinkConnections(compositorOperation->getInputSocket(2)); graph->addOperation(compositorOperation); + addPreviewOperation(graph, context, compositorOperation->getInputSocket(0)); } - diff --git a/source/blender/compositor/nodes/COM_MovieClipNode.cpp b/source/blender/compositor/nodes/COM_MovieClipNode.cpp index 5d5e68fba37..10dd72ec7bf 100644 --- a/source/blender/compositor/nodes/COM_MovieClipNode.cpp +++ b/source/blender/compositor/nodes/COM_MovieClipNode.cpp @@ -41,10 +41,11 @@ MovieClipNode::MovieClipNode(bNode *editorNode) : Node(editorNode) void MovieClipNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { OutputSocket *outputMovieClip = this->getOutputSocket(0); - OutputSocket *offsetXMovieClip = this->getOutputSocket(1); - OutputSocket *offsetYMovieClip = this->getOutputSocket(2); - OutputSocket *scaleMovieClip = this->getOutputSocket(3); - OutputSocket *angleMovieClip = this->getOutputSocket(4); + OutputSocket *alphaMovieClip = this->getOutputSocket(1); + OutputSocket *offsetXMovieClip = this->getOutputSocket(2); + OutputSocket *offsetYMovieClip = this->getOutputSocket(3); + OutputSocket *scaleMovieClip = this->getOutputSocket(4); + OutputSocket *angleMovieClip = this->getOutputSocket(5); bNode *editorNode = this->getbNode(); MovieClip *movieClip = (MovieClip *)editorNode->id; @@ -73,6 +74,16 @@ void MovieClipNode::convertToOperations(ExecutionSystem *graph, CompositorContex operation->setCacheFrame(cacheFrame); graph->addOperation(operation); + if (alphaMovieClip->isConnected()) { + MovieClipAlphaOperation *alphaOperation = new MovieClipAlphaOperation(); + alphaOperation->setMovieClip(movieClip); + alphaOperation->setMovieClipUser(movieClipUser); + alphaOperation->setFramenumber(context->getFramenumber()); + alphaOperation->setCacheFrame(cacheFrame); + alphaMovieClip->relinkConnections(alphaOperation->getOutputSocket()); + graph->addOperation(alphaOperation); + } + MovieTrackingStabilization *stab = &movieClip->tracking.stabilization; float loc[2], scale, angle; loc[0] = 0.0f; @@ -87,7 +98,7 @@ void MovieClipNode::convertToOperations(ExecutionSystem *graph, CompositorContex BKE_tracking_stabilization_data_get(&movieClip->tracking, clip_framenr, ibuf->x, ibuf->y, loc, &scale, &angle); } } - + if (offsetXMovieClip->isConnected()) { SetValueOperation *operationSetValue = new SetValueOperation(); operationSetValue->setValue(loc[0]); diff --git a/source/blender/compositor/nodes/COM_RenderLayersNode.cpp b/source/blender/compositor/nodes/COM_RenderLayersNode.cpp index b57e99754d6..5259fbc7dc5 100644 --- a/source/blender/compositor/nodes/COM_RenderLayersNode.cpp +++ b/source/blender/compositor/nodes/COM_RenderLayersNode.cpp @@ -61,6 +61,7 @@ void RenderLayersNode::testSocketConnection(ExecutionSystem *system, CompositorC if (outputSocket->isConnected()) { operation->setScene(scene); operation->setLayerId(layerId); + operation->setRenderData(context->getRenderData()); outputSocket->relinkConnections(operation->getOutputSocket()); system->addOperation(operation); if (outputSocketNumber == 0) { // only do for image socket if connected @@ -72,6 +73,7 @@ void RenderLayersNode::testSocketConnection(ExecutionSystem *system, CompositorC system->addOperation(operation); operation->setScene(scene); operation->setLayerId(layerId); + operation->setRenderData(context->getRenderData()); addPreviewOperation(system, context, operation->getOutputSocket()); } else { diff --git a/source/blender/compositor/nodes/COM_SocketProxyNode.h b/source/blender/compositor/nodes/COM_SocketProxyNode.h index a83ac094b2b..b679901ba2c 100644 --- a/source/blender/compositor/nodes/COM_SocketProxyNode.h +++ b/source/blender/compositor/nodes/COM_SocketProxyNode.h @@ -31,9 +31,9 @@ */ class SocketProxyNode : public Node { private: - bool m_buffer; + bool m_buffer; public: - SocketProxyNode(bNode *editorNode, bNodeSocket *editorInput, bNodeSocket *editorOutput, bool buffer); + SocketProxyNode(bNode *editorNode, bNodeSocket *editorInput, bNodeSocket *editorOutput, bool buffer); void convertToOperations(ExecutionSystem *graph, CompositorContext *context); virtual bool isProxyNode() const { return true; } diff --git a/source/blender/compositor/nodes/COM_SplitViewerNode.cpp b/source/blender/compositor/nodes/COM_SplitViewerNode.cpp index 37b888becca..0293f4926db 100644 --- a/source/blender/compositor/nodes/COM_SplitViewerNode.cpp +++ b/source/blender/compositor/nodes/COM_SplitViewerNode.cpp @@ -33,6 +33,11 @@ SplitViewerNode::SplitViewerNode(bNode *editorNode) : Node(editorNode) void SplitViewerNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { + bNode *editorNode = this->getbNode(); + bool is_active = ((editorNode->flag & NODE_DO_OUTPUT_RECALC) && + (editorNode->flag & NODE_DO_OUTPUT) && this->isInActiveGroup()) || + context->isRendering(); + InputSocket *image1Socket = this->getInputSocket(0); InputSocket *image2Socket = this->getInputSocket(1); Image *image = (Image *)this->getbNode()->id; @@ -41,7 +46,7 @@ void SplitViewerNode::convertToOperations(ExecutionSystem *graph, CompositorCont SplitViewerOperation *splitViewerOperation = new SplitViewerOperation(); splitViewerOperation->setImage(image); splitViewerOperation->setImageUser(imageUser); - splitViewerOperation->setActive((this->getbNode()->flag & NODE_DO_OUTPUT) && this->isInActiveGroup()); + splitViewerOperation->setActive(is_active); splitViewerOperation->setSplitPercentage(this->getbNode()->custom1); splitViewerOperation->setViewSettings(context->getViewSettings()); @@ -56,7 +61,10 @@ void SplitViewerNode::convertToOperations(ExecutionSystem *graph, CompositorCont splitViewerOperation->setXSplit(!this->getbNode()->custom2); image1Socket->relinkConnections(splitViewerOperation->getInputSocket(0), 0, graph); image2Socket->relinkConnections(splitViewerOperation->getInputSocket(1), 1, graph); - addPreviewOperation(graph, context, splitViewerOperation->getInputSocket(0)); + + if (is_active) + addPreviewOperation(graph, context, splitViewerOperation->getInputSocket(0)); + graph->addOperation(splitViewerOperation); } } diff --git a/source/blender/compositor/nodes/COM_ViewerNode.cpp b/source/blender/compositor/nodes/COM_ViewerNode.cpp index 8f9e58fee13..70cc3a288ee 100644 --- a/source/blender/compositor/nodes/COM_ViewerNode.cpp +++ b/source/blender/compositor/nodes/COM_ViewerNode.cpp @@ -33,17 +33,21 @@ ViewerNode::ViewerNode(bNode *editorNode) : Node(editorNode) void ViewerNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context) { + bNode *editorNode = this->getbNode(); + bool is_active = ((editorNode->flag & NODE_DO_OUTPUT_RECALC) && + (editorNode->flag & NODE_DO_OUTPUT) && this->isInActiveGroup()) || + context->isRendering(); + InputSocket *imageSocket = this->getInputSocket(0); InputSocket *alphaSocket = this->getInputSocket(1); InputSocket *depthSocket = this->getInputSocket(2); Image *image = (Image *)this->getbNode()->id; ImageUser *imageUser = (ImageUser *) this->getbNode()->storage; - bNode *editorNode = this->getbNode(); ViewerOperation *viewerOperation = new ViewerOperation(); viewerOperation->setbNodeTree(context->getbNodeTree()); viewerOperation->setImage(image); viewerOperation->setImageUser(imageUser); - viewerOperation->setActive((editorNode->flag & NODE_DO_OUTPUT) && this->isInActiveGroup()); + viewerOperation->setActive(is_active); viewerOperation->setChunkOrder((OrderOfChunks)editorNode->custom1); viewerOperation->setCenterX(editorNode->custom3); viewerOperation->setCenterY(editorNode->custom4); @@ -63,5 +67,6 @@ void ViewerNode::convertToOperations(ExecutionSystem *graph, CompositorContext * alphaSocket->relinkConnections(viewerOperation->getInputSocket(1)); depthSocket->relinkConnections(viewerOperation->getInputSocket(2)); graph->addOperation(viewerOperation); + addPreviewOperation(graph, context, viewerOperation->getInputSocket(0)); } diff --git a/source/blender/compositor/operations/COM_CompositorOperation.cpp b/source/blender/compositor/operations/COM_CompositorOperation.cpp index 43f491ad2d9..56527da47bc 100644 --- a/source/blender/compositor/operations/COM_CompositorOperation.cpp +++ b/source/blender/compositor/operations/COM_CompositorOperation.cpp @@ -50,12 +50,16 @@ CompositorOperation::CompositorOperation() : NodeOperation() this->m_depthInput = NULL; this->m_ignoreAlpha = false; + this->m_active = false; this->m_sceneName[0] = '\0'; } void CompositorOperation::initExecution() { + if (!this->m_active) + return; + // When initializing the tree during initial load the width and height can be zero. this->m_imageInput = getInputSocketReader(0); this->m_alphaInput = getInputSocketReader(1); @@ -70,6 +74,9 @@ void CompositorOperation::initExecution() void CompositorOperation::deinitExecution() { + if (!this->m_active) + return; + if (!isBreaked()) { Render *re = RE_GetRender(this->m_sceneName); RenderResult *rr = RE_AcquireResultWrite(re); @@ -136,23 +143,63 @@ void CompositorOperation::executeRegion(rcti *rect, unsigned int tileNumber) int x; int y; bool breaked = false; + int dx = 0, dy = 0; + + const RenderData *rd = this->m_rd; + + if (rd->mode & R_BORDER && rd->mode & R_CROP) { + /*! + When using cropped render result, need to re-position area of interest, + so it'll natch bounds of render border within frame. By default, canvas + will be centered between full frame and cropped frame, so we use such + scheme to map cropped coordinates to full-frame coordinates + + ^ Y + | Width + +------------------------------------------------+ + | | + | | + | Centered canvas, we map coordinate from it | + | +------------------+ | + | | | | H + | | | | e + | +------------------+ . Center | | i + | | | | | | g + | | | | | | h + | |....dx.... +------|-----------+ | t + | | . dy | | + | +------------------+ | + | Render border, we map coordinates to it | + | | X + +------------------------------------------------+----> + Full frame + */ + + int full_width = rd->xsch * rd->size / 100; + int full_height =rd->ysch * rd->size / 100; + + dx = rd->border.xmin * full_width - (full_width - this->getWidth()) / 2.0f; + dy = rd->border.ymin * full_height - (full_height - this->getHeight()) / 2.0f; + } for (y = y1; y < y2 && (!breaked); y++) { for (x = x1; x < x2 && (!breaked); x++) { - this->m_imageInput->read(color, x, y, COM_PS_NEAREST); + int input_x = x + dx, input_y = y + dy; + + this->m_imageInput->read(color, input_x, input_y, COM_PS_NEAREST); if (this->m_ignoreAlpha) { color[3] = 1.0f; } else { if (this->m_alphaInput != NULL) { - this->m_alphaInput->read(&(color[3]), x, y, COM_PS_NEAREST); + this->m_alphaInput->read(&(color[3]), input_x, input_y, COM_PS_NEAREST); } } copy_v4_v4(buffer + offset4, color); if (this->m_depthInput != NULL) { - this->m_depthInput->read(color, x, y, COM_PS_NEAREST); + this->m_depthInput->read(color, input_x, input_y, COM_PS_NEAREST); zbuffer[offset] = color[0]; } offset4 += COM_NUMBER_OF_CHANNELS; diff --git a/source/blender/compositor/operations/COM_CompositorOperation.h b/source/blender/compositor/operations/COM_CompositorOperation.h index 27d29664610..d33e89ed742 100644 --- a/source/blender/compositor/operations/COM_CompositorOperation.h +++ b/source/blender/compositor/operations/COM_CompositorOperation.h @@ -66,19 +66,28 @@ private: */ SocketReader *m_depthInput; - /* Ignore any alpha input */ + /** + * @brief Ignore any alpha input + */ bool m_ignoreAlpha; + /** + * @brief operation is active for calculating final compo result + */ + bool m_active; public: CompositorOperation(); + const bool isActiveCompositorOutput() const { return this->m_active; } void executeRegion(rcti *rect, unsigned int tileNumber); void setSceneName(const char *sceneName) { BLI_strncpy(this->m_sceneName, sceneName, sizeof(this->m_sceneName)); } void setRenderData(const RenderData *rd) { this->m_rd = rd; } - bool isOutputOperation(bool rendering) const { return true; } + bool isOutputOperation(bool rendering) const { return this->isActiveCompositorOutput(); } void initExecution(); void deinitExecution(); const CompositorPriority getRenderPriority() const { return COM_PRIORITY_MEDIUM; } void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); void setIgnoreAlpha(bool value) { this->m_ignoreAlpha = value; } + void setActive(bool active) { this->m_active = active; } }; #endif + diff --git a/source/blender/compositor/operations/COM_CropOperation.cpp b/source/blender/compositor/operations/COM_CropOperation.cpp index 4f9cd771988..844d23db2ac 100644 --- a/source/blender/compositor/operations/COM_CropOperation.cpp +++ b/source/blender/compositor/operations/COM_CropOperation.cpp @@ -119,7 +119,7 @@ void CropImageOperation::determineResolution(unsigned int resolution[2], unsigne void CropImageOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) { - if (x >= 0 && x < getWidth() && y >= 0 && y < getHeight()) { + if (x >= 0 && x < getWidth() && y >= 0 && y < getHeight()) { this->m_inputOperation->read(output, (x + this->m_xmin), (y + this->m_ymin), sampler); } else { diff --git a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp index 2d662c1061e..c236c73e50f 100644 --- a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp @@ -62,7 +62,6 @@ void GaussianBokehBlurOperation::updateGauss() int n; float *dgauss; float *ddgauss; - float val; int j, i; const float width = this->getWidth(); const float height = this->getHeight(); @@ -84,13 +83,15 @@ void GaussianBokehBlurOperation::updateGauss() this->m_radx = ceil(radxf); this->m_rady = ceil(radyf); - - n = (2 * this->m_radx + 1) * (2 * this->m_rady + 1); + + int ddwidth = 2 * this->m_radx + 1; + int ddheight = 2 * this->m_rady + 1; + n = ddwidth * ddheight; /* create a full filter image */ ddgauss = (float *)MEM_mallocN(sizeof(float) * n, __func__); dgauss = ddgauss; - val = 0.0f; + float sum = 0.0f; for (j = -this->m_rady; j <= this->m_rady; j++) { for (i = -this->m_radx; i <= this->m_radx; i++, dgauss++) { float fj = (float)j / radyf; @@ -98,16 +99,19 @@ void GaussianBokehBlurOperation::updateGauss() float dist = sqrt(fj * fj + fi * fi); *dgauss = RE_filter_value(this->m_data->filtertype, dist); - val += *dgauss; + sum += *dgauss; } } - if (val != 0.0f) { - val = 1.0f / val; - for (j = n - 1; j >= 0; j--) { - ddgauss[j] *= val; - } + if (sum > 0.0f) { + /* normalize */ + float norm = 1.0f / sum; + for (j = n - 1; j >= 0; j--) + ddgauss[j] *= norm; + } + else { + int center = m_rady * ddwidth + m_radx; + ddgauss[center] = 1.0f; } - else ddgauss[4] = 1.0f; this->m_gausstab = ddgauss; } diff --git a/source/blender/compositor/operations/COM_MovieClipOperation.cpp b/source/blender/compositor/operations/COM_MovieClipOperation.cpp index 74761f00e1f..a74f2c7299b 100644 --- a/source/blender/compositor/operations/COM_MovieClipOperation.cpp +++ b/source/blender/compositor/operations/COM_MovieClipOperation.cpp @@ -30,9 +30,8 @@ extern "C" { } #include "BKE_image.h" -MovieClipOperation::MovieClipOperation() : NodeOperation() +MovieClipBaseOperation::MovieClipBaseOperation() : NodeOperation() { - this->addOutputSocket(COM_DT_COLOR); this->m_movieClip = NULL; this->m_movieClipBuffer = NULL; this->m_movieClipUser = NULL; @@ -42,7 +41,7 @@ MovieClipOperation::MovieClipOperation() : NodeOperation() } -void MovieClipOperation::initExecution() +void MovieClipBaseOperation::initExecution() { if (this->m_movieClip) { BKE_movieclip_user_set_frame(this->m_movieClipUser, this->m_framenumber); @@ -63,7 +62,7 @@ void MovieClipOperation::initExecution() } } -void MovieClipOperation::deinitExecution() +void MovieClipBaseOperation::deinitExecution() { if (this->m_movieClipBuffer) { IMB_freeImBuf(this->m_movieClipBuffer); @@ -72,7 +71,7 @@ void MovieClipOperation::deinitExecution() } } -void MovieClipOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]) +void MovieClipBaseOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]) { resolution[0] = 0; resolution[1] = 0; @@ -87,7 +86,7 @@ void MovieClipOperation::determineResolution(unsigned int resolution[2], unsigne } } -void MovieClipOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +void MovieClipBaseOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) { if (this->m_movieClipBuffer == NULL || x < 0 || y < 0 || x >= this->getWidth() || y >= this->getHeight() ) { zero_v4(output); @@ -106,3 +105,22 @@ void MovieClipOperation::executePixel(float output[4], float x, float y, PixelSa } } } + +MovieClipOperation::MovieClipOperation() : MovieClipBaseOperation() +{ + this->addOutputSocket(COM_DT_COLOR); +} + +MovieClipAlphaOperation::MovieClipAlphaOperation() : MovieClipBaseOperation() +{ + this->addOutputSocket(COM_DT_VALUE); +} + +void MovieClipAlphaOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +{ + MovieClipBaseOperation::executePixel(output, x, y, sampler); + output[0] = output[3]; + output[1] = 0.0f; + output[2] = 0.0f; + output[3] = 0.0f; +} diff --git a/source/blender/compositor/operations/COM_MovieClipOperation.h b/source/blender/compositor/operations/COM_MovieClipOperation.h index 7cce42f6727..a368dca423c 100644 --- a/source/blender/compositor/operations/COM_MovieClipOperation.h +++ b/source/blender/compositor/operations/COM_MovieClipOperation.h @@ -30,11 +30,9 @@ #include "IMB_imbuf_types.h" /** - * Base class for all renderlayeroperations - * - * @todo: rename to operation. + * Base class for movie clip */ -class MovieClipOperation : public NodeOperation { +class MovieClipBaseOperation : public NodeOperation { protected: MovieClip *m_movieClip; MovieClipUser *m_movieClipUser; @@ -50,7 +48,7 @@ protected: void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]); public: - MovieClipOperation(); + MovieClipBaseOperation(); void initExecution(); void deinitExecution(); @@ -62,4 +60,15 @@ public: void executePixel(float output[4], float x, float y, PixelSampler sampler); }; +class MovieClipOperation : public MovieClipBaseOperation { +public: + MovieClipOperation(); +}; + +class MovieClipAlphaOperation : public MovieClipBaseOperation { +public: + MovieClipAlphaOperation(); + void executePixel(float output[4], float x, float y, PixelSampler sampler); +}; + #endif diff --git a/source/blender/compositor/operations/COM_OpenCLKernels.cl b/source/blender/compositor/operations/COM_OpenCLKernels.cl index 8cc25fc3360..d7a81001531 100644 --- a/source/blender/compositor/operations/COM_OpenCLKernels.cl +++ b/source/blender/compositor/operations/COM_OpenCLKernels.cl @@ -112,7 +112,7 @@ __kernel void defocusKernel(__read_only image2d_t inputImage, __read_only image2 float dx = nx - realCoordinate.s0; if (dx != 0 || dy != 0) { inputCoordinate.s0 = nx - offsetInput.s0; - size = read_imagef(inputSize, SAMPLER_NEAREST, inputCoordinate).s0 * scalar; + size = min(read_imagef(inputSize, SAMPLER_NEAREST, inputCoordinate).s0 * scalar, size_center); if (size > threshold) { if (size >= fabs(dx) && size >= fabs(dy)) { float2 uv = {256.0f + dx * 255.0f / size, diff --git a/source/blender/compositor/operations/COM_OutputFileOperation.cpp b/source/blender/compositor/operations/COM_OutputFileOperation.cpp index 47b69ec87f9..15e5ab947d4 100644 --- a/source/blender/compositor/operations/COM_OutputFileOperation.cpp +++ b/source/blender/compositor/operations/COM_OutputFileOperation.cpp @@ -166,7 +166,7 @@ OutputOpenExrLayer::OutputOpenExrLayer(const char *name_, DataType datatype_) } OutputOpenExrMultiLayerOperation::OutputOpenExrMultiLayerOperation( - const RenderData *rd, const bNodeTree *tree, const char *path, char exr_codec) + const RenderData *rd, const bNodeTree *tree, const char *path, char exr_codec) { this->m_rd = rd; this->m_tree = tree; diff --git a/source/blender/compositor/operations/COM_RenderLayersBaseProg.cpp b/source/blender/compositor/operations/COM_RenderLayersBaseProg.cpp index 2ca499683d3..3421b0a2b34 100644 --- a/source/blender/compositor/operations/COM_RenderLayersBaseProg.cpp +++ b/source/blender/compositor/operations/COM_RenderLayersBaseProg.cpp @@ -37,6 +37,7 @@ RenderLayersBaseProg::RenderLayersBaseProg(int renderpass, int elementsize) : No this->setScene(NULL); this->m_inputBuffer = NULL; this->m_elementsize = elementsize; + this->m_rd = NULL; } @@ -111,14 +112,29 @@ void RenderLayersBaseProg::doInterpolation(float output[4], float x, float y, Pi void RenderLayersBaseProg::executePixel(float output[4], float x, float y, PixelSampler sampler) { - int ix = x; - int iy = y; - + const RenderData *rd = this->m_rd; + + int dx = 0, dy = 0; + + if (rd->mode & R_BORDER && rd->mode & R_CROP) { + /* see comment in executeRegion describing coordinate mapping, + * here it simply goes other way around + */ + int full_width = rd->xsch * rd->size / 100; + int full_height = rd->ysch * rd->size / 100; + + dx = rd->border.xmin * full_width - (full_width - this->getWidth()) / 2.0f; + dy = rd->border.ymin * full_height - (full_height - this->getHeight()) / 2.0f; + } + + int ix = x - dx; + int iy = y - dy; + if (this->m_inputBuffer == NULL || ix < 0 || iy < 0 || ix >= (int)this->getWidth() || iy >= (int)this->getHeight() ) { zero_v4(output); } else { - doInterpolation(output, x, y, sampler); + doInterpolation(output, ix, iy, sampler); } } diff --git a/source/blender/compositor/operations/COM_RenderLayersBaseProg.h b/source/blender/compositor/operations/COM_RenderLayersBaseProg.h index 3916862a0b3..84d6c1ee188 100644 --- a/source/blender/compositor/operations/COM_RenderLayersBaseProg.h +++ b/source/blender/compositor/operations/COM_RenderLayersBaseProg.h @@ -63,7 +63,12 @@ private: int m_renderpass; int m_elementsize; - + + /** + * @brief render data used for active rendering + */ + const RenderData *m_rd; + protected: /** * Constructor @@ -89,6 +94,7 @@ public: */ void setScene(Scene *scene) { this->m_scene = scene; } Scene *getScene() { return this->m_scene; } + void setRenderData(const RenderData *rd) { this->m_rd = rd; } void setLayerId(short layerId) { this->m_layerId = layerId; } short getLayerId() { return this->m_layerId; } void initExecution(); diff --git a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp index 61720c7676d..03031e0f764 100644 --- a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp @@ -146,7 +146,7 @@ void VariableSizeBokehBlurOperation::executePixel(float output[4], int x, int y, int offsetNxNy = offsetNy + (minx * COM_NUMBER_OF_CHANNELS); for (int nx = minx; nx < maxx; nx += QualityStepHelper::getStep()) { if (nx != x || ny != y) { - float size = inputSizeFloatBuffer[offsetNxNy] * scalar; + float size = min(inputSizeFloatBuffer[offsetNxNy] * scalar, size_center); if (size > this->m_threshold) { float dx = nx - x; if (size > fabsf(dx) && size > fabsf(dy)) { |