SplitViewer node:
- fix thumbnail preview (previously it showed only one input) - make SplitViewer node update even if the second input is not connected - now it works when the first socket is connected to a zero-sized node tree (e. g. Color Input node) - SplitViewer node is now based on 2 operations: SplitOperation and ViewerOperation. - ViewerBaseOperation was removed as a redundant one. Any future viewer style node can use the same principle and prepare the output before passing to an actual ViewerOperation. Thanks Lukas Toenne for reviewing this patch and giving me get few pieces of advice.
This commit is contained in:
@@ -425,14 +425,12 @@ set(SRC
|
|||||||
operations/COM_CompositorOperation.cpp
|
operations/COM_CompositorOperation.cpp
|
||||||
operations/COM_OutputFileOperation.h
|
operations/COM_OutputFileOperation.h
|
||||||
operations/COM_OutputFileOperation.cpp
|
operations/COM_OutputFileOperation.cpp
|
||||||
operations/COM_ViewerBaseOperation.h
|
|
||||||
operations/COM_ViewerBaseOperation.cpp
|
|
||||||
operations/COM_ViewerOperation.h
|
operations/COM_ViewerOperation.h
|
||||||
operations/COM_ViewerOperation.cpp
|
operations/COM_ViewerOperation.cpp
|
||||||
operations/COM_PreviewOperation.h
|
operations/COM_PreviewOperation.h
|
||||||
operations/COM_PreviewOperation.cpp
|
operations/COM_PreviewOperation.cpp
|
||||||
operations/COM_SplitViewerOperation.h
|
operations/COM_SplitOperation.h
|
||||||
operations/COM_SplitViewerOperation.cpp
|
operations/COM_SplitOperation.cpp
|
||||||
operations/COM_ConvertValueToColorProg.h
|
operations/COM_ConvertValueToColorProg.h
|
||||||
operations/COM_ConvertValueToColorProg.cpp
|
operations/COM_ConvertValueToColorProg.cpp
|
||||||
operations/COM_ConvertColorToValueProg.h
|
operations/COM_ConvertColorToValueProg.h
|
||||||
|
@@ -107,7 +107,7 @@ extern "C" {
|
|||||||
* - [@ref ChunkExecutionState.COM_ES_EXECUTED]: Chunk is finished
|
* - [@ref ChunkExecutionState.COM_ES_EXECUTED]: Chunk is finished
|
||||||
*
|
*
|
||||||
* @see ExecutionGroup.execute
|
* @see ExecutionGroup.execute
|
||||||
* @see ViewerBaseOperation.getChunkOrder
|
* @see ViewerOperation.getChunkOrder
|
||||||
* @see OrderOfChunks
|
* @see OrderOfChunks
|
||||||
*
|
*
|
||||||
* @section interest Area of interest
|
* @section interest Area of interest
|
||||||
|
@@ -248,7 +248,7 @@ void ExecutionGroup::execute(ExecutionSystem *graph)
|
|||||||
OrderOfChunks chunkorder = COM_ORDER_OF_CHUNKS_DEFAULT;
|
OrderOfChunks chunkorder = COM_ORDER_OF_CHUNKS_DEFAULT;
|
||||||
|
|
||||||
if (operation->isViewerOperation()) {
|
if (operation->isViewerOperation()) {
|
||||||
ViewerBaseOperation *viewer = (ViewerBaseOperation *)operation;
|
ViewerOperation *viewer = (ViewerOperation *)operation;
|
||||||
centerX = viewer->getCenterX();
|
centerX = viewer->getCenterX();
|
||||||
centerY = viewer->getCenterY();
|
centerY = viewer->getCenterY();
|
||||||
chunkorder = viewer->getChunkOrder();
|
chunkorder = viewer->getChunkOrder();
|
||||||
|
@@ -36,7 +36,7 @@
|
|||||||
#include "COM_GroupNode.h"
|
#include "COM_GroupNode.h"
|
||||||
#include "COM_WriteBufferOperation.h"
|
#include "COM_WriteBufferOperation.h"
|
||||||
#include "COM_ReadBufferOperation.h"
|
#include "COM_ReadBufferOperation.h"
|
||||||
#include "COM_ViewerBaseOperation.h"
|
#include "COM_ViewerOperation.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "BKE_node.h"
|
#include "BKE_node.h"
|
||||||
@@ -212,7 +212,7 @@ void ExecutionSystemHelper::debugDump(ExecutionSystem *system)
|
|||||||
printf("|");
|
printf("|");
|
||||||
}
|
}
|
||||||
if (operation->isViewerOperation()) {
|
if (operation->isViewerOperation()) {
|
||||||
ViewerBaseOperation *viewer = (ViewerBaseOperation *)operation;
|
ViewerOperation *viewer = (ViewerOperation *)operation;
|
||||||
if (viewer->isActiveViewerOutput()) {
|
if (viewer->isActiveViewerOutput()) {
|
||||||
printf("Active viewer");
|
printf("Active viewer");
|
||||||
}
|
}
|
||||||
|
@@ -23,7 +23,8 @@
|
|||||||
#include "COM_SplitViewerNode.h"
|
#include "COM_SplitViewerNode.h"
|
||||||
#include "BKE_global.h"
|
#include "BKE_global.h"
|
||||||
|
|
||||||
#include "COM_SplitViewerOperation.h"
|
#include "COM_SplitOperation.h"
|
||||||
|
#include "COM_ViewerOperation.h"
|
||||||
#include "COM_ExecutionSystem.h"
|
#include "COM_ExecutionSystem.h"
|
||||||
|
|
||||||
SplitViewerNode::SplitViewerNode(bNode *editorNode) : Node(editorNode)
|
SplitViewerNode::SplitViewerNode(bNode *editorNode) : Node(editorNode)
|
||||||
@@ -42,29 +43,32 @@ void SplitViewerNode::convertToOperations(ExecutionSystem *graph, CompositorCont
|
|||||||
InputSocket *image2Socket = this->getInputSocket(1);
|
InputSocket *image2Socket = this->getInputSocket(1);
|
||||||
Image *image = (Image *)this->getbNode()->id;
|
Image *image = (Image *)this->getbNode()->id;
|
||||||
ImageUser *imageUser = (ImageUser *) this->getbNode()->storage;
|
ImageUser *imageUser = (ImageUser *) this->getbNode()->storage;
|
||||||
if (image1Socket->isConnected() && image2Socket->isConnected()) {
|
|
||||||
SplitViewerOperation *splitViewerOperation = new SplitViewerOperation();
|
|
||||||
splitViewerOperation->setImage(image);
|
|
||||||
splitViewerOperation->setImageUser(imageUser);
|
|
||||||
splitViewerOperation->setActive(is_active);
|
|
||||||
splitViewerOperation->setSplitPercentage(this->getbNode()->custom1);
|
|
||||||
|
|
||||||
splitViewerOperation->setViewSettings(context->getViewSettings());
|
SplitOperation *splitViewerOperation = new SplitOperation();
|
||||||
splitViewerOperation->setDisplaySettings(context->getDisplaySettings());
|
splitViewerOperation->setSplitPercentage(this->getbNode()->custom1);
|
||||||
|
splitViewerOperation->setXSplit(!this->getbNode()->custom2);
|
||||||
|
|
||||||
/* defaults - the viewer node has these options but not exposed for split view
|
image1Socket->relinkConnections(splitViewerOperation->getInputSocket(0), 0, graph);
|
||||||
* we could use the split to define an area of interest on one axis at least */
|
image2Socket->relinkConnections(splitViewerOperation->getInputSocket(1), 1, graph);
|
||||||
splitViewerOperation->setChunkOrder(COM_ORDER_OF_CHUNKS_DEFAULT);
|
|
||||||
splitViewerOperation->setCenterX(0.5f);
|
|
||||||
splitViewerOperation->setCenterY(0.5f);
|
|
||||||
|
|
||||||
splitViewerOperation->setXSplit(!this->getbNode()->custom2);
|
ViewerOperation *viewerOperation = new ViewerOperation();
|
||||||
image1Socket->relinkConnections(splitViewerOperation->getInputSocket(0), 0, graph);
|
viewerOperation->setImage(image);
|
||||||
image2Socket->relinkConnections(splitViewerOperation->getInputSocket(1), 1, graph);
|
viewerOperation->setImageUser(imageUser);
|
||||||
|
viewerOperation->setActive(is_active);
|
||||||
|
viewerOperation->setViewSettings(context->getViewSettings());
|
||||||
|
viewerOperation->setDisplaySettings(context->getDisplaySettings());
|
||||||
|
|
||||||
if (is_active)
|
/* defaults - the viewer node has these options but not exposed for split view
|
||||||
addPreviewOperation(graph, context, splitViewerOperation->getInputSocket(0));
|
* we could use the split to define an area of interest on one axis at least */
|
||||||
|
viewerOperation->setChunkOrder(COM_ORDER_OF_CHUNKS_DEFAULT);
|
||||||
|
viewerOperation->setCenterX(0.5f);
|
||||||
|
viewerOperation->setCenterY(0.5f);
|
||||||
|
|
||||||
graph->addOperation(splitViewerOperation);
|
addLink(graph, splitViewerOperation->getOutputSocket(), viewerOperation->getInputSocket(0));
|
||||||
}
|
|
||||||
|
if (is_active)
|
||||||
|
addPreviewOperation(graph, context, viewerOperation->getInputSocket(0));
|
||||||
|
|
||||||
|
graph->addOperation(splitViewerOperation);
|
||||||
|
graph->addOperation(viewerOperation);
|
||||||
}
|
}
|
||||||
|
@@ -20,7 +20,7 @@
|
|||||||
* Monique Dewanchand
|
* Monique Dewanchand
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "COM_SplitViewerOperation.h"
|
#include "COM_SplitOperation.h"
|
||||||
#include "COM_SocketConnection.h"
|
#include "COM_SocketConnection.h"
|
||||||
#include "BLI_listbase.h"
|
#include "BLI_listbase.h"
|
||||||
#include "BKE_image.h"
|
#include "BKE_image.h"
|
||||||
@@ -35,58 +35,47 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SplitViewerOperation::SplitViewerOperation() : ViewerBaseOperation()
|
SplitOperation::SplitOperation() : NodeOperation()
|
||||||
{
|
{
|
||||||
this->addInputSocket(COM_DT_COLOR);
|
this->addInputSocket(COM_DT_COLOR);
|
||||||
this->addInputSocket(COM_DT_COLOR);
|
this->addInputSocket(COM_DT_COLOR);
|
||||||
|
this->addOutputSocket(COM_DT_COLOR);
|
||||||
this->m_image1Input = NULL;
|
this->m_image1Input = NULL;
|
||||||
this->m_image2Input = NULL;
|
this->m_image2Input = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SplitViewerOperation::initExecution()
|
void SplitOperation::initExecution()
|
||||||
{
|
{
|
||||||
// When initializing the tree during initial load the width and height can be zero.
|
// When initializing the tree during initial load the width and height can be zero.
|
||||||
this->m_image1Input = getInputSocketReader(0);
|
this->m_image1Input = getInputSocketReader(0);
|
||||||
this->m_image2Input = getInputSocketReader(1);
|
this->m_image2Input = getInputSocketReader(1);
|
||||||
ViewerBaseOperation::initExecution();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SplitViewerOperation::deinitExecution()
|
void SplitOperation::deinitExecution()
|
||||||
{
|
{
|
||||||
this->m_image1Input = NULL;
|
this->m_image1Input = NULL;
|
||||||
this->m_image2Input = NULL;
|
this->m_image2Input = NULL;
|
||||||
ViewerBaseOperation::deinitExecution();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SplitOperation::executePixel(float output[4], float x, float y, PixelSampler sampler)
|
||||||
void SplitViewerOperation::executeRegion(rcti *rect, unsigned int tileNumber)
|
|
||||||
{
|
{
|
||||||
float *buffer = this->m_outputBuffer;
|
|
||||||
|
|
||||||
if (!buffer) return;
|
|
||||||
int x1 = rect->xmin;
|
|
||||||
int y1 = rect->ymin;
|
|
||||||
int x2 = rect->xmax;
|
|
||||||
int y2 = rect->ymax;
|
|
||||||
int offset = (y1 * this->getWidth() + x1) * 4;
|
|
||||||
int x;
|
|
||||||
int y;
|
|
||||||
int perc = this->m_xSplit ? this->m_splitPercentage * this->getWidth() / 100.0f : this->m_splitPercentage * this->getHeight() / 100.0f;
|
int perc = this->m_xSplit ? this->m_splitPercentage * this->getWidth() / 100.0f : this->m_splitPercentage * this->getHeight() / 100.0f;
|
||||||
for (y = y1; y < y2; y++) {
|
bool image1 = this->m_xSplit ? x > perc : y > perc;
|
||||||
for (x = x1; x < x2; x++) {
|
if (image1) {
|
||||||
bool image1;
|
this->m_image1Input->read(output, x, y, COM_PS_NEAREST);
|
||||||
image1 = this->m_xSplit ? x > perc : y > perc;
|
}
|
||||||
if (image1) {
|
else {
|
||||||
this->m_image1Input->read(&(buffer[offset]), x, y, COM_PS_NEAREST);
|
this->m_image2Input->read(output, x, y, COM_PS_NEAREST);
|
||||||
}
|
|
||||||
else {
|
|
||||||
this->m_image2Input->read(&(buffer[offset]), x, y, COM_PS_NEAREST);
|
|
||||||
}
|
|
||||||
|
|
||||||
offset += 4;
|
|
||||||
}
|
|
||||||
offset += (this->getWidth() - (x2 - x1)) * 4;
|
|
||||||
}
|
}
|
||||||
updateImage(rect);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SplitOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2])
|
||||||
|
{
|
||||||
|
unsigned int tempPreferredResolution[2] = {0, 0};
|
||||||
|
unsigned int tempResolution[2];
|
||||||
|
|
||||||
|
this->getInputSocket(0)->determineResolution(tempResolution, tempPreferredResolution);
|
||||||
|
this->setResolutionInputSocketIndex((tempResolution[0] && tempResolution[1]) ? 0 : 1);
|
||||||
|
|
||||||
|
NodeOperation::determineResolution(resolution, preferredResolution);
|
||||||
|
}
|
@@ -20,13 +20,11 @@
|
|||||||
* Monique Dewanchand
|
* Monique Dewanchand
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _COM_SplitViewerOperation_h
|
#ifndef _COM_SplitOperation_h
|
||||||
#define _COM_SplitViewerOperation_h
|
#define _COM_SplitOperation_h
|
||||||
#include "COM_ViewerBaseOperation.h"
|
#include "COM_NodeOperation.h"
|
||||||
#include "DNA_image_types.h"
|
|
||||||
#include "BLI_rect.h"
|
|
||||||
|
|
||||||
class SplitViewerOperation : public ViewerBaseOperation {
|
class SplitOperation : public NodeOperation {
|
||||||
private:
|
private:
|
||||||
SocketReader *m_image1Input;
|
SocketReader *m_image1Input;
|
||||||
SocketReader *m_image2Input;
|
SocketReader *m_image2Input;
|
||||||
@@ -34,10 +32,11 @@ private:
|
|||||||
float m_splitPercentage;
|
float m_splitPercentage;
|
||||||
bool m_xSplit;
|
bool m_xSplit;
|
||||||
public:
|
public:
|
||||||
SplitViewerOperation();
|
SplitOperation();
|
||||||
void executeRegion(rcti *rect, unsigned int tileNumber);
|
|
||||||
void initExecution();
|
void initExecution();
|
||||||
void deinitExecution();
|
void deinitExecution();
|
||||||
|
void executePixel(float output[4], float x, float y, PixelSampler sampler);
|
||||||
|
void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]);
|
||||||
void setSplitPercentage(float splitPercentage) { this->m_splitPercentage = splitPercentage; }
|
void setSplitPercentage(float splitPercentage) { this->m_splitPercentage = splitPercentage; }
|
||||||
void setXSplit(bool xsplit) { this->m_xSplit = xsplit; }
|
void setXSplit(bool xsplit) { this->m_xSplit = xsplit; }
|
||||||
};
|
};
|
@@ -1,123 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2011, Blender Foundation.
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*
|
|
||||||
* Contributor:
|
|
||||||
* Jeroen Bakker
|
|
||||||
* Monique Dewanchand
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "COM_ViewerBaseOperation.h"
|
|
||||||
#include "COM_SocketConnection.h"
|
|
||||||
#include "BLI_listbase.h"
|
|
||||||
#include "BKE_image.h"
|
|
||||||
#include "WM_api.h"
|
|
||||||
#include "WM_types.h"
|
|
||||||
#include "PIL_time.h"
|
|
||||||
#include "BLI_utildefines.h"
|
|
||||||
#include "BLI_math_color.h"
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#include "MEM_guardedalloc.h"
|
|
||||||
#include "IMB_imbuf.h"
|
|
||||||
#include "IMB_imbuf_types.h"
|
|
||||||
#include "IMB_colormanagement.h"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ViewerBaseOperation::ViewerBaseOperation() : NodeOperation()
|
|
||||||
{
|
|
||||||
this->setImage(NULL);
|
|
||||||
this->setImageUser(NULL);
|
|
||||||
this->m_outputBuffer = NULL;
|
|
||||||
this->m_depthBuffer = NULL;
|
|
||||||
this->m_active = false;
|
|
||||||
this->m_doDepthBuffer = false;
|
|
||||||
this->m_viewSettings = NULL;
|
|
||||||
this->m_displaySettings = NULL;
|
|
||||||
this->m_ignoreAlpha = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ViewerBaseOperation::initExecution()
|
|
||||||
{
|
|
||||||
if (isActiveViewerOutput()) {
|
|
||||||
initImage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ViewerBaseOperation::initImage()
|
|
||||||
{
|
|
||||||
Image *anImage = this->m_image;
|
|
||||||
ImBuf *ibuf = BKE_image_acquire_ibuf(anImage, this->m_imageUser, &this->m_lock);
|
|
||||||
|
|
||||||
if (!ibuf) return;
|
|
||||||
BLI_lock_thread(LOCK_DRAW_IMAGE);
|
|
||||||
if (ibuf->x != (int)getWidth() || ibuf->y != (int)getHeight()) {
|
|
||||||
|
|
||||||
imb_freerectImBuf(ibuf);
|
|
||||||
imb_freerectfloatImBuf(ibuf);
|
|
||||||
IMB_freezbuffloatImBuf(ibuf);
|
|
||||||
ibuf->x = getWidth();
|
|
||||||
ibuf->y = getHeight();
|
|
||||||
imb_addrectfloatImBuf(ibuf);
|
|
||||||
anImage->ok = IMA_OK_LOADED;
|
|
||||||
|
|
||||||
ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
|
|
||||||
|
|
||||||
BLI_unlock_thread(LOCK_DRAW_IMAGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_doDepthBuffer) {
|
|
||||||
addzbuffloatImBuf(ibuf);
|
|
||||||
}
|
|
||||||
BLI_unlock_thread(LOCK_DRAW_IMAGE);
|
|
||||||
|
|
||||||
/* now we combine the input with ibuf */
|
|
||||||
this->m_outputBuffer = ibuf->rect_float;
|
|
||||||
|
|
||||||
/* needed for display buffer update */
|
|
||||||
this->m_ibuf = ibuf;
|
|
||||||
|
|
||||||
if (m_doDepthBuffer) {
|
|
||||||
this->m_depthBuffer = ibuf->zbuf_float;
|
|
||||||
}
|
|
||||||
|
|
||||||
BKE_image_release_ibuf(this->m_image, this->m_ibuf, this->m_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ViewerBaseOperation:: updateImage(rcti *rect)
|
|
||||||
{
|
|
||||||
IMB_partial_display_buffer_update(this->m_ibuf, this->m_outputBuffer, NULL, getWidth(), 0, 0,
|
|
||||||
this->m_viewSettings, this->m_displaySettings,
|
|
||||||
rect->xmin, rect->ymin, rect->xmax, rect->ymax, FALSE);
|
|
||||||
|
|
||||||
this->updateDraw();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ViewerBaseOperation::deinitExecution()
|
|
||||||
{
|
|
||||||
this->m_outputBuffer = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
const CompositorPriority ViewerBaseOperation::getRenderPriority() const
|
|
||||||
{
|
|
||||||
if (this->isActiveViewerOutput()) {
|
|
||||||
return COM_PRIORITY_HIGH;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return COM_PRIORITY_LOW;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,75 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2011, Blender Foundation.
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*
|
|
||||||
* Contributor:
|
|
||||||
* Jeroen Bakker
|
|
||||||
* Monique Dewanchand
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _COM_ViewerBaseOperation_h
|
|
||||||
#define _COM_ViewerBaseOperation_h
|
|
||||||
#include "COM_NodeOperation.h"
|
|
||||||
#include "DNA_image_types.h"
|
|
||||||
#include "BLI_rect.h"
|
|
||||||
#include "BKE_global.h"
|
|
||||||
|
|
||||||
class ViewerBaseOperation : public NodeOperation {
|
|
||||||
protected:
|
|
||||||
float *m_outputBuffer;
|
|
||||||
float *m_depthBuffer;
|
|
||||||
Image *m_image;
|
|
||||||
ImageUser *m_imageUser;
|
|
||||||
void *m_lock;
|
|
||||||
bool m_active;
|
|
||||||
float m_centerX;
|
|
||||||
float m_centerY;
|
|
||||||
OrderOfChunks m_chunkOrder;
|
|
||||||
bool m_doDepthBuffer;
|
|
||||||
ImBuf *m_ibuf;
|
|
||||||
bool m_ignoreAlpha;
|
|
||||||
|
|
||||||
const ColorManagedViewSettings *m_viewSettings;
|
|
||||||
const ColorManagedDisplaySettings *m_displaySettings;
|
|
||||||
|
|
||||||
public:
|
|
||||||
bool isOutputOperation(bool rendering) const { if (G.background) return false; return isActiveViewerOutput(); }
|
|
||||||
void initExecution();
|
|
||||||
void deinitExecution();
|
|
||||||
void setImage(Image *image) { this->m_image = image; }
|
|
||||||
void setImageUser(ImageUser *imageUser) { this->m_imageUser = imageUser; }
|
|
||||||
const bool isActiveViewerOutput() const { return this->m_active; }
|
|
||||||
void setActive(bool active) { this->m_active = active; }
|
|
||||||
void setCenterX(float centerX) { this->m_centerX = centerX;}
|
|
||||||
void setCenterY(float centerY) { this->m_centerY = centerY;}
|
|
||||||
void setChunkOrder(OrderOfChunks tileOrder) { this->m_chunkOrder = tileOrder; }
|
|
||||||
float getCenterX() { return this->m_centerX; }
|
|
||||||
float getCenterY() { return this->m_centerY; }
|
|
||||||
OrderOfChunks getChunkOrder() { return this->m_chunkOrder; }
|
|
||||||
const CompositorPriority getRenderPriority() const;
|
|
||||||
bool isViewerOperation() { return true; }
|
|
||||||
void setIgnoreAlpha(bool value) { this->m_ignoreAlpha = value; }
|
|
||||||
|
|
||||||
void setViewSettings(const ColorManagedViewSettings *viewSettings) { this->m_viewSettings = viewSettings; }
|
|
||||||
void setDisplaySettings(const ColorManagedDisplaySettings *displaySettings) { this->m_displaySettings = displaySettings; }
|
|
||||||
protected:
|
|
||||||
ViewerBaseOperation();
|
|
||||||
void updateImage(rcti *rect);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void initImage();
|
|
||||||
};
|
|
||||||
#endif
|
|
@@ -35,11 +35,22 @@ extern "C" {
|
|||||||
#include "MEM_guardedalloc.h"
|
#include "MEM_guardedalloc.h"
|
||||||
#include "IMB_imbuf.h"
|
#include "IMB_imbuf.h"
|
||||||
#include "IMB_imbuf_types.h"
|
#include "IMB_imbuf_types.h"
|
||||||
|
#include "IMB_colormanagement.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ViewerOperation::ViewerOperation() : ViewerBaseOperation()
|
ViewerOperation::ViewerOperation() : NodeOperation()
|
||||||
{
|
{
|
||||||
|
this->setImage(NULL);
|
||||||
|
this->setImageUser(NULL);
|
||||||
|
this->m_outputBuffer = NULL;
|
||||||
|
this->m_depthBuffer = NULL;
|
||||||
|
this->m_active = false;
|
||||||
|
this->m_doDepthBuffer = false;
|
||||||
|
this->m_viewSettings = NULL;
|
||||||
|
this->m_displaySettings = NULL;
|
||||||
|
this->m_ignoreAlpha = false;
|
||||||
|
|
||||||
this->addInputSocket(COM_DT_COLOR);
|
this->addInputSocket(COM_DT_COLOR);
|
||||||
this->addInputSocket(COM_DT_VALUE);
|
this->addInputSocket(COM_DT_VALUE);
|
||||||
this->addInputSocket(COM_DT_VALUE);
|
this->addInputSocket(COM_DT_VALUE);
|
||||||
@@ -56,7 +67,10 @@ void ViewerOperation::initExecution()
|
|||||||
this->m_alphaInput = getInputSocketReader(1);
|
this->m_alphaInput = getInputSocketReader(1);
|
||||||
this->m_depthInput = getInputSocketReader(2);
|
this->m_depthInput = getInputSocketReader(2);
|
||||||
this->m_doDepthBuffer = (this->m_depthInput != NULL);
|
this->m_doDepthBuffer = (this->m_depthInput != NULL);
|
||||||
ViewerBaseOperation::initExecution();
|
|
||||||
|
if (isActiveViewerOutput()) {
|
||||||
|
initImage();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViewerOperation::deinitExecution()
|
void ViewerOperation::deinitExecution()
|
||||||
@@ -64,10 +78,9 @@ void ViewerOperation::deinitExecution()
|
|||||||
this->m_imageInput = NULL;
|
this->m_imageInput = NULL;
|
||||||
this->m_alphaInput = NULL;
|
this->m_alphaInput = NULL;
|
||||||
this->m_depthInput = NULL;
|
this->m_depthInput = NULL;
|
||||||
ViewerBaseOperation::deinitExecution();
|
this->m_outputBuffer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ViewerOperation::executeRegion(rcti *rect, unsigned int tileNumber)
|
void ViewerOperation::executeRegion(rcti *rect, unsigned int tileNumber)
|
||||||
{
|
{
|
||||||
float *buffer = this->m_outputBuffer;
|
float *buffer = this->m_outputBuffer;
|
||||||
@@ -114,3 +127,62 @@ void ViewerOperation::executeRegion(rcti *rect, unsigned int tileNumber)
|
|||||||
}
|
}
|
||||||
updateImage(rect);
|
updateImage(rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ViewerOperation::initImage()
|
||||||
|
{
|
||||||
|
Image *anImage = this->m_image;
|
||||||
|
ImBuf *ibuf = BKE_image_acquire_ibuf(anImage, this->m_imageUser, &this->m_lock);
|
||||||
|
|
||||||
|
if (!ibuf) return;
|
||||||
|
BLI_lock_thread(LOCK_DRAW_IMAGE);
|
||||||
|
if (ibuf->x != (int)getWidth() || ibuf->y != (int)getHeight()) {
|
||||||
|
|
||||||
|
imb_freerectImBuf(ibuf);
|
||||||
|
imb_freerectfloatImBuf(ibuf);
|
||||||
|
IMB_freezbuffloatImBuf(ibuf);
|
||||||
|
ibuf->x = getWidth();
|
||||||
|
ibuf->y = getHeight();
|
||||||
|
imb_addrectfloatImBuf(ibuf);
|
||||||
|
anImage->ok = IMA_OK_LOADED;
|
||||||
|
|
||||||
|
ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
|
||||||
|
|
||||||
|
BLI_unlock_thread(LOCK_DRAW_IMAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_doDepthBuffer) {
|
||||||
|
addzbuffloatImBuf(ibuf);
|
||||||
|
}
|
||||||
|
BLI_unlock_thread(LOCK_DRAW_IMAGE);
|
||||||
|
|
||||||
|
/* now we combine the input with ibuf */
|
||||||
|
this->m_outputBuffer = ibuf->rect_float;
|
||||||
|
|
||||||
|
/* needed for display buffer update */
|
||||||
|
this->m_ibuf = ibuf;
|
||||||
|
|
||||||
|
if (m_doDepthBuffer) {
|
||||||
|
this->m_depthBuffer = ibuf->zbuf_float;
|
||||||
|
}
|
||||||
|
|
||||||
|
BKE_image_release_ibuf(this->m_image, this->m_ibuf, this->m_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewerOperation::updateImage(rcti *rect)
|
||||||
|
{
|
||||||
|
IMB_partial_display_buffer_update(this->m_ibuf, this->m_outputBuffer, NULL, getWidth(), 0, 0,
|
||||||
|
this->m_viewSettings, this->m_displaySettings,
|
||||||
|
rect->xmin, rect->ymin, rect->xmax, rect->ymax, FALSE);
|
||||||
|
|
||||||
|
this->updateDraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
const CompositorPriority ViewerOperation::getRenderPriority() const
|
||||||
|
{
|
||||||
|
if (this->isActiveViewerOutput()) {
|
||||||
|
return COM_PRIORITY_HIGH;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return COM_PRIORITY_LOW;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -25,18 +25,55 @@
|
|||||||
#include "COM_NodeOperation.h"
|
#include "COM_NodeOperation.h"
|
||||||
#include "DNA_image_types.h"
|
#include "DNA_image_types.h"
|
||||||
#include "BLI_rect.h"
|
#include "BLI_rect.h"
|
||||||
#include "COM_ViewerBaseOperation.h"
|
#include "BKE_global.h"
|
||||||
|
|
||||||
class ViewerOperation : public ViewerBaseOperation {
|
class ViewerOperation : public NodeOperation {
|
||||||
private:
|
private:
|
||||||
|
float *m_outputBuffer;
|
||||||
|
float *m_depthBuffer;
|
||||||
|
Image *m_image;
|
||||||
|
ImageUser *m_imageUser;
|
||||||
|
void *m_lock;
|
||||||
|
bool m_active;
|
||||||
|
float m_centerX;
|
||||||
|
float m_centerY;
|
||||||
|
OrderOfChunks m_chunkOrder;
|
||||||
|
bool m_doDepthBuffer;
|
||||||
|
ImBuf *m_ibuf;
|
||||||
|
bool m_ignoreAlpha;
|
||||||
|
|
||||||
|
const ColorManagedViewSettings *m_viewSettings;
|
||||||
|
const ColorManagedDisplaySettings *m_displaySettings;
|
||||||
|
|
||||||
SocketReader *m_imageInput;
|
SocketReader *m_imageInput;
|
||||||
SocketReader *m_alphaInput;
|
SocketReader *m_alphaInput;
|
||||||
SocketReader *m_depthInput;
|
SocketReader *m_depthInput;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ViewerOperation();
|
ViewerOperation();
|
||||||
void executeRegion(rcti *rect, unsigned int tileNumber);
|
|
||||||
void initExecution();
|
void initExecution();
|
||||||
void deinitExecution();
|
void deinitExecution();
|
||||||
|
void executeRegion(rcti *rect, unsigned int tileNumber);
|
||||||
|
bool isOutputOperation(bool rendering) const { if (G.background) return false; return isActiveViewerOutput(); }
|
||||||
|
void setImage(Image *image) { this->m_image = image; }
|
||||||
|
void setImageUser(ImageUser *imageUser) { this->m_imageUser = imageUser; }
|
||||||
|
const bool isActiveViewerOutput() const { return this->m_active; }
|
||||||
|
void setActive(bool active) { this->m_active = active; }
|
||||||
|
void setCenterX(float centerX) { this->m_centerX = centerX;}
|
||||||
|
void setCenterY(float centerY) { this->m_centerY = centerY;}
|
||||||
|
void setChunkOrder(OrderOfChunks tileOrder) { this->m_chunkOrder = tileOrder; }
|
||||||
|
float getCenterX() const { return this->m_centerX; }
|
||||||
|
float getCenterY() const { return this->m_centerY; }
|
||||||
|
OrderOfChunks getChunkOrder() const { return this->m_chunkOrder; }
|
||||||
|
const CompositorPriority getRenderPriority() const;
|
||||||
|
bool isViewerOperation() { return true; }
|
||||||
|
void setIgnoreAlpha(bool value) { this->m_ignoreAlpha = value; }
|
||||||
|
|
||||||
|
void setViewSettings(const ColorManagedViewSettings *viewSettings) { this->m_viewSettings = viewSettings; }
|
||||||
|
void setDisplaySettings(const ColorManagedDisplaySettings *displaySettings) { this->m_displaySettings = displaySettings; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void updateImage(rcti *rect);
|
||||||
|
void initImage();
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user