Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/compositor/operations')
-rw-r--r--source/blender/compositor/operations/COM_CompositorOperation.cpp15
-rw-r--r--source/blender/compositor/operations/COM_CompositorOperation.h6
-rw-r--r--source/blender/compositor/operations/COM_ImageOperation.cpp11
-rw-r--r--source/blender/compositor/operations/COM_ImageOperation.h7
-rw-r--r--source/blender/compositor/operations/COM_MultilayerImageOperation.cpp23
-rw-r--r--source/blender/compositor/operations/COM_MultilayerImageOperation.h11
-rw-r--r--source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cpp317
-rw-r--r--source/blender/compositor/operations/COM_OutputFileMultiViewOperation.h74
-rw-r--r--source/blender/compositor/operations/COM_OutputFileOperation.cpp116
-rw-r--r--source/blender/compositor/operations/COM_OutputFileOperation.h15
-rw-r--r--source/blender/compositor/operations/COM_RenderLayersProg.cpp10
-rw-r--r--source/blender/compositor/operations/COM_RenderLayersProg.h9
-rw-r--r--source/blender/compositor/operations/COM_ViewerOperation.cpp15
-rw-r--r--source/blender/compositor/operations/COM_ViewerOperation.h6
14 files changed, 558 insertions, 77 deletions
diff --git a/source/blender/compositor/operations/COM_CompositorOperation.cpp b/source/blender/compositor/operations/COM_CompositorOperation.cpp
index ffef81d0323..eacbdf91be2 100644
--- a/source/blender/compositor/operations/COM_CompositorOperation.cpp
+++ b/source/blender/compositor/operations/COM_CompositorOperation.cpp
@@ -52,6 +52,7 @@ CompositorOperation::CompositorOperation() : NodeOperation()
this->m_active = false;
this->m_sceneName[0] = '\0';
+ this->m_viewName = NULL;
}
void CompositorOperation::initExecution()
@@ -81,14 +82,16 @@ void CompositorOperation::deinitExecution()
RenderResult *rr = RE_AcquireResultWrite(re);
if (rr) {
- if (rr->rectf != NULL) {
- MEM_freeN(rr->rectf);
+ RenderView *rv = (RenderView *)BLI_findstring(&rr->views, this->m_viewName, offsetof(RenderView, name));
+
+ if (rv->rectf != NULL) {
+ MEM_freeN(rv->rectf);
}
- rr->rectf = this->m_outputBuffer;
- if (rr->rectz != NULL) {
- MEM_freeN(rr->rectz);
+ rv->rectf = this->m_outputBuffer;
+ if (rv->rectz != NULL) {
+ MEM_freeN(rv->rectz);
}
- rr->rectz = this->m_depthBuffer;
+ rv->rectz = this->m_depthBuffer;
}
else {
if (this->m_outputBuffer) {
diff --git a/source/blender/compositor/operations/COM_CompositorOperation.h b/source/blender/compositor/operations/COM_CompositorOperation.h
index 447d74131b3..e81ba520695 100644
--- a/source/blender/compositor/operations/COM_CompositorOperation.h
+++ b/source/blender/compositor/operations/COM_CompositorOperation.h
@@ -75,11 +75,17 @@ private:
* @brief operation is active for calculating final compo result
*/
bool m_active;
+
+ /**
+ * @brief View name, used for multiview
+ */
+ const char *m_viewName;
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 setViewName(const char *viewName) { this->m_viewName = viewName; }
void setRenderData(const RenderData *rd) { this->m_rd = rd; }
bool isOutputOperation(bool /*rendering*/) const { return this->isActiveCompositorOutput(); }
void initExecution();
diff --git a/source/blender/compositor/operations/COM_ImageOperation.cpp b/source/blender/compositor/operations/COM_ImageOperation.cpp
index 624fdf8b626..c140b7afbd7 100644
--- a/source/blender/compositor/operations/COM_ImageOperation.cpp
+++ b/source/blender/compositor/operations/COM_ImageOperation.cpp
@@ -25,6 +25,7 @@
#include "BLI_listbase.h"
#include "DNA_image_types.h"
#include "BKE_image.h"
+#include "BKE_scene.h"
#include "BLI_math.h"
extern "C" {
@@ -48,6 +49,8 @@ BaseImageOperation::BaseImageOperation() : NodeOperation()
this->m_framenumber = 0;
this->m_depthBuffer = NULL;
this->m_numberOfChannels = 0;
+ this->m_rd = NULL;
+ this->m_viewName = NULL;
}
ImageOperation::ImageOperation() : BaseImageOperation()
{
@@ -65,8 +68,12 @@ ImageDepthOperation::ImageDepthOperation() : BaseImageOperation()
ImBuf *BaseImageOperation::getImBuf()
{
ImBuf *ibuf;
-
- ibuf = BKE_image_acquire_ibuf(this->m_image, this->m_imageUser, NULL);
+ ImageUser iuser = *this->m_imageUser;
+
+ /* local changes to the original ImageUser */
+ iuser.multi_index = BKE_scene_multiview_view_id_get(this->m_rd, this->m_viewName);
+
+ ibuf = BKE_image_acquire_ibuf(this->m_image, &iuser, NULL);
if (ibuf == NULL || (ibuf->rect == NULL && ibuf->rect_float == NULL)) {
BKE_image_release_ibuf(this->m_image, ibuf, NULL);
return NULL;
diff --git a/source/blender/compositor/operations/COM_ImageOperation.h b/source/blender/compositor/operations/COM_ImageOperation.h
index 206f1509f60..75222559810 100644
--- a/source/blender/compositor/operations/COM_ImageOperation.h
+++ b/source/blender/compositor/operations/COM_ImageOperation.h
@@ -49,7 +49,9 @@ protected:
int m_imagewidth;
int m_framenumber;
int m_numberOfChannels;
-
+ const RenderData *m_rd;
+ const char *m_viewName;
+
BaseImageOperation();
/**
* Determine the output resolution. The resolution is retrieved from the Renderer
@@ -64,7 +66,8 @@ public:
void deinitExecution();
void setImage(Image *image) { this->m_image = image; }
void setImageUser(ImageUser *imageuser) { this->m_imageUser = imageuser; }
-
+ void setRenderData(const RenderData *rd) { this->m_rd = rd; }
+ void setViewName(const char *viewName) { this->m_viewName = viewName; }
void setFramenumber(int framenumber) { this->m_framenumber = framenumber; }
};
class ImageOperation : public BaseImageOperation {
diff --git a/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp b/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp
index 513140e2f62..00be3b1cdde 100644
--- a/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp
+++ b/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp
@@ -27,18 +27,27 @@ extern "C" {
# include "IMB_imbuf_types.h"
}
-MultilayerBaseOperation::MultilayerBaseOperation(int passindex) : BaseImageOperation()
+MultilayerBaseOperation::MultilayerBaseOperation(int passtype, int view) : BaseImageOperation()
{
- this->m_passId = passindex;
+ this->m_passtype = passtype;
+ this->m_view = view;
}
+
ImBuf *MultilayerBaseOperation::getImBuf()
{
- RenderPass *rpass = (RenderPass *)BLI_findlink(&this->m_renderlayer->passes, this->m_passId);
- if (rpass) {
- this->m_imageUser->pass = m_passId;
- BKE_image_multilayer_index(this->m_image->rr, this->m_imageUser);
- return BaseImageOperation::getImBuf();
+ /* temporarily changes the view to get the right ImBuf */
+ int view = this->m_imageUser->view;
+
+ this->m_imageUser->view = this->m_view;
+ this->m_imageUser->passtype = this->m_passtype;
+
+ if (BKE_image_multilayer_index(this->m_image->rr, this->m_imageUser)) {
+ ImBuf *ibuf = BaseImageOperation::getImBuf();
+ this->m_imageUser->view = view;
+ return ibuf;
}
+
+ this->m_imageUser->view = view;
return NULL;
}
diff --git a/source/blender/compositor/operations/COM_MultilayerImageOperation.h b/source/blender/compositor/operations/COM_MultilayerImageOperation.h
index 37bee1b6a8c..2e140577d74 100644
--- a/source/blender/compositor/operations/COM_MultilayerImageOperation.h
+++ b/source/blender/compositor/operations/COM_MultilayerImageOperation.h
@@ -29,7 +29,8 @@
class MultilayerBaseOperation : public BaseImageOperation {
private:
- int m_passId;
+ int m_passtype;
+ int m_view;
RenderLayer *m_renderlayer;
protected:
ImBuf *getImBuf();
@@ -37,13 +38,13 @@ public:
/**
* Constructor
*/
- MultilayerBaseOperation(int passindex);
+ MultilayerBaseOperation(int passtype, int view);
void setRenderLayer(RenderLayer *renderlayer) { this->m_renderlayer = renderlayer; }
};
class MultilayerColorOperation : public MultilayerBaseOperation {
public:
- MultilayerColorOperation(int passindex) : MultilayerBaseOperation(passindex) {
+ MultilayerColorOperation(int passtype, int view) : MultilayerBaseOperation(passtype, view) {
this->addOutputSocket(COM_DT_COLOR);
}
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
@@ -51,7 +52,7 @@ public:
class MultilayerValueOperation : public MultilayerBaseOperation {
public:
- MultilayerValueOperation(int passindex) : MultilayerBaseOperation(passindex) {
+ MultilayerValueOperation(int passtype, int view) : MultilayerBaseOperation(passtype, view) {
this->addOutputSocket(COM_DT_VALUE);
}
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
@@ -59,7 +60,7 @@ public:
class MultilayerVectorOperation : public MultilayerBaseOperation {
public:
- MultilayerVectorOperation(int passindex) : MultilayerBaseOperation(passindex) {
+ MultilayerVectorOperation(int passtype, int view) : MultilayerBaseOperation(passtype, view) {
this->addOutputSocket(COM_DT_VECTOR);
}
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
diff --git a/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cpp b/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cpp
new file mode 100644
index 00000000000..c927dfa89a1
--- /dev/null
+++ b/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cpp
@@ -0,0 +1,317 @@
+/*
+ * Copyright 2015, 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
+ * Lukas Tönne
+ * Dalai Felinto
+ */
+
+#include "COM_OutputFileOperation.h"
+#include "COM_OutputFileMultiViewOperation.h"
+
+#include <string.h>
+#include "BLI_listbase.h"
+#include "BLI_path_util.h"
+#include "BLI_string.h"
+#include "BKE_image.h"
+#include "BKE_global.h"
+#include "BKE_main.h"
+#include "BKE_scene.h"
+
+#include "DNA_color_types.h"
+#include "MEM_guardedalloc.h"
+
+extern "C" {
+#include "IMB_imbuf.h"
+#include "IMB_colormanagement.h"
+#include "IMB_imbuf_types.h"
+}
+
+/************************************ OpenEXR Singlelayer Multiview *****************************************/
+
+OutputOpenExrSingleLayerMultiViewOperation::OutputOpenExrSingleLayerMultiViewOperation(
+ const RenderData *rd, const bNodeTree *tree, DataType datatype, ImageFormatData *format, const char *path,
+ const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings,
+ const char *viewName)
+ : OutputSingleLayerOperation(rd, tree, datatype, format, path, viewSettings, displaySettings, viewName)
+{
+}
+
+void *OutputOpenExrSingleLayerMultiViewOperation::get_handle(const char *filename)
+{
+ size_t width = this->getWidth();
+ size_t height = this->getHeight();
+ SceneRenderView *srv;
+
+ if (width != 0 && height != 0) {
+ void *exrhandle;
+
+ exrhandle = IMB_exr_get_handle_name(filename);
+
+ if (!BKE_scene_multiview_is_render_view_first(this->m_rd, this->m_viewName))
+ return exrhandle;
+
+ IMB_exr_clear_channels(exrhandle);
+
+ for (srv = (SceneRenderView *)this->m_rd->views.first; srv; srv = srv->next) {
+ if (BKE_scene_multiview_is_render_view_active(this->m_rd, srv) == false)
+ continue;
+
+ IMB_exr_add_view(exrhandle, srv->name);
+ add_exr_channels(exrhandle, NULL, this->m_datatype, srv->name, width, NULL);
+ }
+
+ BLI_make_existing_file(filename);
+
+ /* prepare the file with all the channels */
+
+ if (IMB_exr_begin_write(exrhandle, filename, width, height, this->m_format->exr_codec) == 0) {
+ printf("Error Writing Singlelayer Multiview Openexr\n");
+ IMB_exr_close(exrhandle);
+ }
+ else {
+ IMB_exr_clear_channels(exrhandle);
+ return exrhandle;
+ }
+ }
+ return NULL;
+}
+
+void OutputOpenExrSingleLayerMultiViewOperation::deinitExecution()
+{
+ unsigned int width = this->getWidth();
+ unsigned int height = this->getHeight();
+
+ if (width != 0 && height != 0) {
+ void *exrhandle;
+ Main *bmain = G.main; /* TODO, have this passed along */
+ char filename[FILE_MAX];
+
+ BKE_image_path_from_imtype(
+ filename, this->m_path, bmain->name, this->m_rd->cfra, R_IMF_IMTYPE_OPENEXR,
+ (this->m_rd->scemode & R_EXTENSION) != 0, true, NULL);
+
+ exrhandle = this->get_handle(filename);
+ add_exr_channels(exrhandle, NULL, this->m_datatype, this->m_viewName, width, this->m_outputBuffer);
+
+ /* memory can only be freed after we write all views to the file */
+ this->m_outputBuffer = NULL;
+ this->m_imageInput = NULL;
+
+ /* ready to close the file */
+ if (BKE_scene_multiview_is_render_view_last(this->m_rd, this->m_viewName)) {
+ IMB_exr_write_channels(exrhandle);
+
+ /* free buffer memory for all the views */
+ free_exr_channels(exrhandle, this->m_rd, NULL, this->m_datatype);
+
+ /* remove exr handle and data */
+ IMB_exr_close(exrhandle);
+ }
+ }
+}
+
+/************************************ OpenEXR Multilayer Multiview *****************************************/
+
+OutputOpenExrMultiLayerMultiViewOperation::OutputOpenExrMultiLayerMultiViewOperation(
+ const RenderData *rd, const bNodeTree *tree, const char *path, char exr_codec, const char *viewName)
+ : OutputOpenExrMultiLayerOperation(rd, tree, path, exr_codec, viewName)
+{
+}
+
+void *OutputOpenExrMultiLayerMultiViewOperation::get_handle(const char *filename)
+{
+ unsigned int width = this->getWidth();
+ unsigned int height = this->getHeight();
+
+ if (width != 0 && height != 0) {
+
+ void *exrhandle;
+ SceneRenderView *srv;
+
+ /* get a new global handle */
+ exrhandle = IMB_exr_get_handle_name(filename);
+
+ if (!BKE_scene_multiview_is_render_view_first(this->m_rd, this->m_viewName))
+ return exrhandle;
+
+ IMB_exr_clear_channels(exrhandle);
+
+ /* check renderdata for amount of views */
+ for (srv = (SceneRenderView *) this->m_rd->views.first; srv; srv = srv->next) {
+
+ if (BKE_scene_multiview_is_render_view_active(this->m_rd, srv) == false)
+ continue;
+
+ IMB_exr_add_view(exrhandle, srv->name);
+
+ for (unsigned int i = 0; i < this->m_layers.size(); ++i)
+ add_exr_channels(exrhandle, this->m_layers[i].name, this->m_layers[i].datatype, srv->name, width, NULL);
+ }
+
+ BLI_make_existing_file(filename);
+
+ /* prepare the file with all the channels for the header */
+ if (IMB_exr_begin_write(exrhandle, filename, width, height, this->m_exr_codec) == 0) {
+ printf("Error Writing Multilayer Multiview Openexr\n");
+ IMB_exr_close(exrhandle);
+ }
+ else {
+ IMB_exr_clear_channels(exrhandle);
+ return exrhandle;
+ }
+ }
+ return NULL;
+}
+
+void OutputOpenExrMultiLayerMultiViewOperation::deinitExecution()
+{
+ unsigned int width = this->getWidth();
+ unsigned int height = this->getHeight();
+
+ if (width != 0 && height != 0) {
+ void *exrhandle;
+ Main *bmain = G.main; /* TODO, have this passed along */
+ char filename[FILE_MAX];
+
+ BKE_image_path_from_imtype(
+ filename, this->m_path, bmain->name, this->m_rd->cfra, R_IMF_IMTYPE_MULTILAYER,
+ (this->m_rd->scemode & R_EXTENSION) != 0, true, NULL);
+
+ exrhandle = this->get_handle(filename);
+
+ for (unsigned int i = 0; i < this->m_layers.size(); ++i)
+ add_exr_channels(exrhandle, this->m_layers[i].name, this->m_layers[i].datatype, this->m_viewName, width, this->m_layers[i].outputBuffer);
+
+ for (unsigned int i = 0; i < this->m_layers.size(); ++i) {
+ /* memory can only be freed after we write all views to the file */
+ this->m_layers[i].outputBuffer = NULL;
+ this->m_layers[i].imageInput = NULL;
+ }
+
+ /* ready to close the file */
+ if (BKE_scene_multiview_is_render_view_last(this->m_rd, this->m_viewName)) {
+ IMB_exr_write_channels(exrhandle);
+
+ /* free buffer memory for all the views */
+ for (unsigned int i = 0; i < this->m_layers.size(); ++i) {
+ free_exr_channels(exrhandle, this->m_rd, this->m_layers[i].name, this->m_layers[i].datatype);
+ }
+
+ IMB_exr_close(exrhandle);
+ }
+ }
+}
+
+
+/******************************** Stereo3D ******************************/
+
+OutputStereoOperation::OutputStereoOperation(
+ const RenderData *rd, const bNodeTree *tree, DataType datatype, ImageFormatData *format, const char *path,
+ const char *name, const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings,
+ const char *viewName)
+ : OutputSingleLayerOperation(rd, tree, datatype, format, path, viewSettings, displaySettings, viewName)
+{
+ BLI_strncpy(this->m_name, name, sizeof(this->m_name));
+ this->m_channels = get_datatype_size(datatype);
+}
+
+void *OutputStereoOperation::get_handle(const char *filename)
+{
+ size_t width = this->getWidth();
+ size_t height = this->getHeight();
+ const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
+ size_t i;
+
+ if (width != 0 && height != 0) {
+ void *exrhandle;
+
+ exrhandle = IMB_exr_get_handle_name(filename);
+
+ if (!BKE_scene_multiview_is_render_view_first(this->m_rd, this->m_viewName))
+ return exrhandle;
+
+ IMB_exr_clear_channels(exrhandle);
+
+ for (i = 0; i < 2; i++)
+ IMB_exr_add_view(exrhandle, names[i]);
+
+ return exrhandle;
+ }
+ return NULL;
+}
+
+void OutputStereoOperation::deinitExecution()
+{
+ unsigned int width = this->getWidth();
+ unsigned int height = this->getHeight();
+
+ if (width != 0 && height != 0) {
+ void *exrhandle;
+
+ exrhandle = this->get_handle(this->m_path);
+ float *buf = this->m_outputBuffer;
+
+ /* populate single EXR channel with view data */
+ IMB_exr_add_channel(exrhandle, NULL, this->m_name, this->m_viewName, 1, this->m_channels * width * height, buf);
+
+ this->m_imageInput = NULL;
+ this->m_outputBuffer = NULL;
+
+ /* create stereo ibuf */
+ if (BKE_scene_multiview_is_render_view_last(this->m_rd, this->m_viewName)) {
+ ImBuf *ibuf[3] = {NULL};
+ const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
+ Main *bmain = G.main; /* TODO, have this passed along */
+ char filename[FILE_MAX];
+ int i;
+
+ /* get rectf from EXR */
+ for (i = 0; i < 2; i++) {
+ float *rectf = IMB_exr_channel_rect(exrhandle, NULL, this->m_name, names[i]);
+ ibuf[i] = IMB_allocImBuf(width, height, this->m_format->planes, 0);
+
+ ibuf[i]->channels = this->m_channels;
+ ibuf[i]->rect_float = rectf;
+ ibuf[i]->mall |= IB_rectfloat;
+ ibuf[i]->dither = this->m_rd->dither_intensity;
+
+ /* do colormanagement in the individual views, so it doesn't need to do in the stereo */
+ IMB_colormanagement_imbuf_for_write(ibuf[i], true, false, this->m_viewSettings,
+ this->m_displaySettings, this->m_format);
+ IMB_prepare_write_ImBuf(IMB_isfloat(ibuf[i]), ibuf[i]);
+ }
+
+ /* create stereo buffer */
+ ibuf[2] = IMB_stereo3d_ImBuf(this->m_format, ibuf[0], ibuf[1]);
+
+ BKE_image_path_from_imformat(
+ filename, this->m_path, bmain->name, this->m_rd->cfra, this->m_format,
+ (this->m_rd->scemode & R_EXTENSION) != 0, true, NULL);
+
+ BKE_imbuf_write(ibuf[2], filename, this->m_format);
+
+ /* imbuf knows which rects are not part of ibuf */
+ for (i = 0; i < 3; i++)
+ IMB_freeImBuf(ibuf[i]);
+
+ IMB_exr_close(exrhandle);
+ }
+ }
+}
diff --git a/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.h b/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.h
new file mode 100644
index 00000000000..25716fdb9e1
--- /dev/null
+++ b/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2015, 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
+ * Lukas Tönne
+ * Dalai Felinto
+ */
+
+#ifndef _COM_OutputFileMultiViewOperation_h
+#define _COM_OutputFileMultiViewOperation_h
+#include "COM_NodeOperation.h"
+
+#include "BLI_rect.h"
+#include "BLI_path_util.h"
+
+#include "DNA_color_types.h"
+#include "DNA_userdef_types.h"
+
+#include "intern/openexr/openexr_multi.h"
+
+class OutputOpenExrSingleLayerMultiViewOperation : public OutputSingleLayerOperation {
+private:
+public:
+ OutputOpenExrSingleLayerMultiViewOperation(const RenderData *rd, const bNodeTree *tree, DataType datatype,
+ ImageFormatData *format, const char *path,
+ const ColorManagedViewSettings *viewSettings,
+ const ColorManagedDisplaySettings *displaySettings,
+ const char *viewName);
+
+ void *get_handle(const char *filename);
+ void deinitExecution();
+};
+
+/* Writes inputs into OpenEXR multilayer channels. */
+class OutputOpenExrMultiLayerMultiViewOperation : public OutputOpenExrMultiLayerOperation {
+private:
+public:
+ OutputOpenExrMultiLayerMultiViewOperation(const RenderData *rd, const bNodeTree *tree, const char *path, char exr_codec, const char *viewName);
+
+ void *get_handle(const char *filename);
+ void deinitExecution();
+};
+
+/**/
+class OutputStereoOperation : public OutputSingleLayerOperation {
+private:
+ char m_name[FILE_MAX];
+ size_t m_channels;
+public:
+ OutputStereoOperation(const RenderData *rd, const bNodeTree *tree, DataType datatype,
+ struct ImageFormatData *format, const char *path, const char *name,
+ const ColorManagedViewSettings *viewSettings,
+ const ColorManagedDisplaySettings *displaySettings, const char *viewName);
+ void *get_handle(const char *filename);
+ void deinitExecution();
+};
+
+#endif
diff --git a/source/blender/compositor/operations/COM_OutputFileOperation.cpp b/source/blender/compositor/operations/COM_OutputFileOperation.cpp
index b1c90a6355f..1a7a356f5b4 100644
--- a/source/blender/compositor/operations/COM_OutputFileOperation.cpp
+++ b/source/blender/compositor/operations/COM_OutputFileOperation.cpp
@@ -29,6 +29,7 @@
#include "BKE_image.h"
#include "BKE_global.h"
#include "BKE_main.h"
+#include "BKE_scene.h"
#include "DNA_color_types.h"
@@ -39,7 +40,60 @@ extern "C" {
# include "IMB_imbuf_types.h"
}
-static int get_datatype_size(DataType datatype)
+void add_exr_channels(void *exrhandle, const char *layerName, const DataType datatype, const char *viewName, const size_t width, float *buf)
+{
+ /* create channels */
+ switch (datatype) {
+ case COM_DT_VALUE:
+ IMB_exr_add_channel(exrhandle, layerName, "V", viewName, 1, width, buf ? buf : NULL);
+ break;
+ case COM_DT_VECTOR:
+ IMB_exr_add_channel(exrhandle, layerName, "X", viewName, 3, 3 * width, buf ? buf : NULL);
+ IMB_exr_add_channel(exrhandle, layerName, "Y", viewName, 3, 3 * width, buf ? buf + 1 : NULL);
+ IMB_exr_add_channel(exrhandle, layerName, "Z", viewName, 3, 3 * width, buf ? buf + 2 : NULL);
+ break;
+ case COM_DT_COLOR:
+ IMB_exr_add_channel(exrhandle, layerName, "R", viewName, 4, 4 * width, buf ? buf : NULL);
+ IMB_exr_add_channel(exrhandle, layerName, "G", viewName, 4, 4 * width, buf ? buf + 1 : NULL);
+ IMB_exr_add_channel(exrhandle, layerName, "B", viewName, 4, 4 * width, buf ? buf + 2 : NULL);
+ IMB_exr_add_channel(exrhandle, layerName, "A", viewName, 4, 4 * width, buf ? buf + 3 : NULL);
+ break;
+ default:
+ break;
+ }
+}
+
+void free_exr_channels(void *exrhandle, const RenderData *rd, const char *layerName, const DataType datatype)
+{
+ SceneRenderView *srv;
+
+ /* check renderdata for amount of views */
+ for (srv = (SceneRenderView *) rd->views.first; srv; srv = srv->next) {
+ float *rect = NULL;
+
+ if (BKE_scene_multiview_is_render_view_active(rd, srv) == false)
+ continue;
+
+ /* the pointer is stored in the first channel of each datatype */
+ switch (datatype) {
+ case COM_DT_VALUE:
+ rect = IMB_exr_channel_rect(exrhandle, layerName, "V", srv->name);
+ break;
+ case COM_DT_VECTOR:
+ rect = IMB_exr_channel_rect(exrhandle, layerName, "X", srv->name);
+ break;
+ case COM_DT_COLOR:
+ rect = IMB_exr_channel_rect(exrhandle, layerName, "R", srv->name);
+ break;
+ default:
+ break;
+ }
+ if (rect)
+ MEM_freeN(rect);
+ }
+}
+
+int get_datatype_size(DataType datatype)
{
switch (datatype) {
case COM_DT_VALUE: return 1;
@@ -94,7 +148,7 @@ static void write_buffer_rect(rcti *rect, const bNodeTree *tree,
OutputSingleLayerOperation::OutputSingleLayerOperation(
const RenderData *rd, const bNodeTree *tree, DataType datatype, ImageFormatData *format, const char *path,
- const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings)
+ const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings, const char *viewName)
{
this->m_rd = rd;
this->m_tree = tree;
@@ -110,6 +164,7 @@ OutputSingleLayerOperation::OutputSingleLayerOperation(
this->m_viewSettings = viewSettings;
this->m_displaySettings = displaySettings;
+ this->m_viewName = viewName;
}
void OutputSingleLayerOperation::initExecution()
@@ -131,6 +186,7 @@ void OutputSingleLayerOperation::deinitExecution()
ImBuf *ibuf = IMB_allocImBuf(this->getWidth(), this->getHeight(), this->m_format->planes, 0);
Main *bmain = G.main; /* TODO, have this passed along */
char filename[FILE_MAX];
+ const char *suffix;
ibuf->channels = size;
ibuf->rect_float = this->m_outputBuffer;
@@ -140,10 +196,12 @@ void OutputSingleLayerOperation::deinitExecution()
IMB_colormanagement_imbuf_for_write(ibuf, true, false, m_viewSettings, m_displaySettings,
this->m_format);
+ suffix = BKE_scene_multiview_view_suffix_get(this->m_rd, this->m_viewName);
+
BKE_image_path_from_imformat(
- filename, this->m_path, bmain->name, this->m_rd->cfra,
- this->m_format, (this->m_rd->scemode & R_EXTENSION) != 0, true);
-
+ filename, this->m_path, bmain->name, this->m_rd->cfra, this->m_format,
+ (this->m_rd->scemode & R_EXTENSION) != 0, true, suffix);
+
if (0 == BKE_imbuf_write(ibuf, filename, this->m_format))
printf("Cannot save Node File Output to %s\n", filename);
else
@@ -155,6 +213,7 @@ void OutputSingleLayerOperation::deinitExecution()
this->m_imageInput = NULL;
}
+/******************************* MultiLayer *******************************/
OutputOpenExrLayer::OutputOpenExrLayer(const char *name_, DataType datatype_, bool use_layer_)
{
@@ -168,13 +227,14 @@ OutputOpenExrLayer::OutputOpenExrLayer(const char *name_, DataType datatype_, bo
}
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, const char *viewName)
{
this->m_rd = rd;
this->m_tree = tree;
BLI_strncpy(this->m_path, path, sizeof(this->m_path));
this->m_exr_codec = exr_codec;
+ this->m_viewName = viewName;
}
void OutputOpenExrMultiLayerOperation::add_layer(const char *name, DataType datatype, bool use_layer)
@@ -210,52 +270,21 @@ void OutputOpenExrMultiLayerOperation::deinitExecution()
if (width != 0 && height != 0) {
Main *bmain = G.main; /* TODO, have this passed along */
char filename[FILE_MAX];
+ const char *suffix;
void *exrhandle = IMB_exr_get_handle();
-
+
+ suffix = BKE_scene_multiview_view_suffix_get(this->m_rd, this->m_viewName);
BKE_image_path_from_imtype(
filename, this->m_path, bmain->name, this->m_rd->cfra, R_IMF_IMTYPE_MULTILAYER,
- (this->m_rd->scemode & R_EXTENSION) != 0, true);
+ (this->m_rd->scemode & R_EXTENSION) != 0, true, suffix);
BLI_make_existing_file(filename);
-
+
for (unsigned int i = 0; i < this->m_layers.size(); ++i) {
OutputOpenExrLayer &layer = this->m_layers[i];
if (!layer.imageInput)
continue; /* skip unconnected sockets */
- char channelname[EXR_TOT_MAXNAME];
- BLI_strncpy(channelname, this->m_layers[i].name, sizeof(channelname) - 2);
- char *channelname_ext = channelname + strlen(channelname);
-
- float *buf = this->m_layers[i].outputBuffer;
-
- /* create channels */
- switch (this->m_layers[i].datatype) {
- case COM_DT_VALUE:
- strcpy(channelname_ext, ".V");
- IMB_exr_add_channel(exrhandle, 0, channelname, 1, width, buf);
- break;
- case COM_DT_VECTOR:
- strcpy(channelname_ext, ".X");
- IMB_exr_add_channel(exrhandle, 0, channelname, 3, 3 * width, buf);
- strcpy(channelname_ext, ".Y");
- IMB_exr_add_channel(exrhandle, 0, channelname, 3, 3 * width, buf + 1);
- strcpy(channelname_ext, ".Z");
- IMB_exr_add_channel(exrhandle, 0, channelname, 3, 3 * width, buf + 2);
- break;
- case COM_DT_COLOR:
- strcpy(channelname_ext, ".R");
- IMB_exr_add_channel(exrhandle, 0, channelname, 4, 4 * width, buf);
- strcpy(channelname_ext, ".G");
- IMB_exr_add_channel(exrhandle, 0, channelname, 4, 4 * width, buf + 1);
- strcpy(channelname_ext, ".B");
- IMB_exr_add_channel(exrhandle, 0, channelname, 4, 4 * width, buf + 2);
- strcpy(channelname_ext, ".A");
- IMB_exr_add_channel(exrhandle, 0, channelname, 4, 4 * width, buf + 3);
- break;
- default:
- break;
- }
-
+ add_exr_channels(exrhandle, this->m_layers[i].name, this->m_layers[i].datatype, "", width, this->m_layers[i].outputBuffer);
}
/* when the filename has no permissions, this can fail */
@@ -279,3 +308,4 @@ void OutputOpenExrMultiLayerOperation::deinitExecution()
}
}
}
+
diff --git a/source/blender/compositor/operations/COM_OutputFileOperation.h b/source/blender/compositor/operations/COM_OutputFileOperation.h
index af16f186d9d..58ebf055583 100644
--- a/source/blender/compositor/operations/COM_OutputFileOperation.h
+++ b/source/blender/compositor/operations/COM_OutputFileOperation.h
@@ -34,7 +34,7 @@
/* Writes the image to a single-layer file. */
class OutputSingleLayerOperation : public NodeOperation {
-private:
+protected:
const RenderData *m_rd;
const bNodeTree *m_tree;
@@ -47,9 +47,11 @@ private:
const ColorManagedViewSettings *m_viewSettings;
const ColorManagedDisplaySettings *m_displaySettings;
+
+ const char *m_viewName;
public:
OutputSingleLayerOperation(const RenderData *rd, const bNodeTree *tree, DataType datatype, ImageFormatData *format, const char *path,
- const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings);
+ const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings, const char *viewName);
void executeRegion(rcti *rect, unsigned int tileNumber);
bool isOutputOperation(bool /*rendering*/) const { return true; }
@@ -75,7 +77,7 @@ struct OutputOpenExrLayer {
/* Writes inputs into OpenEXR multilayer channels. */
class OutputOpenExrMultiLayerOperation : public NodeOperation {
-private:
+protected:
typedef std::vector<OutputOpenExrLayer> LayerList;
const RenderData *m_rd;
@@ -84,9 +86,10 @@ private:
char m_path[FILE_MAX];
char m_exr_codec;
LayerList m_layers;
+ const char *m_viewName;
public:
- OutputOpenExrMultiLayerOperation(const RenderData *rd, const bNodeTree *tree, const char *path, char exr_codec);
+ OutputOpenExrMultiLayerOperation(const RenderData *rd, const bNodeTree *tree, const char *path, char exr_codec, const char *viewName);
void add_layer(const char *name, DataType datatype, bool use_layer);
@@ -99,4 +102,8 @@ public:
bool isFileOutputOperation() const { return true; }
};
+void add_exr_channels(void *exrhandle, const char *layerName, const DataType datatype, const char *viewName, const size_t width, float *buf);
+void free_exr_channels(void *exrhandle, const RenderData *rd, const char *layerName, const DataType datatype);
+int get_datatype_size(DataType datatype);
+
#endif
diff --git a/source/blender/compositor/operations/COM_RenderLayersProg.cpp b/source/blender/compositor/operations/COM_RenderLayersProg.cpp
index defbc2ab57f..af176a766ff 100644
--- a/source/blender/compositor/operations/COM_RenderLayersProg.cpp
+++ b/source/blender/compositor/operations/COM_RenderLayersProg.cpp
@@ -23,6 +23,7 @@
#include "COM_RenderLayersProg.h"
#include "BLI_listbase.h"
+#include "BKE_scene.h"
#include "DNA_scene_types.h"
extern "C" {
@@ -57,11 +58,10 @@ void RenderLayersBaseProg::initExecution()
if (srl) {
RenderLayer *rl = RE_GetRenderLayer(rr, srl->name);
- if (rl && rl->rectf) {
- this->m_inputBuffer = RE_RenderLayerGetPass(rl, this->m_renderpass);
-
+ if (rl) {
+ this->m_inputBuffer = RE_RenderLayerGetPass(rl, this->m_renderpass, this->m_viewName);
if (this->m_inputBuffer == NULL && this->m_renderpass == SCE_PASS_COMBINED) {
- this->m_inputBuffer = rl->rectf;
+ this->m_inputBuffer = RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, this->m_viewName);
}
}
}
@@ -195,7 +195,7 @@ void RenderLayersBaseProg::determineResolution(unsigned int resolution[2], unsig
SceneRenderLayer *srl = (SceneRenderLayer *)BLI_findlink(&sce->r.layers, getLayerId());
if (srl) {
RenderLayer *rl = RE_GetRenderLayer(rr, srl->name);
- if (rl && rl->rectf) {
+ if (rl) {
resolution[0] = rl->rectx;
resolution[1] = rl->recty;
}
diff --git a/source/blender/compositor/operations/COM_RenderLayersProg.h b/source/blender/compositor/operations/COM_RenderLayersProg.h
index f73d9de3e27..2ddbc968c01 100644
--- a/source/blender/compositor/operations/COM_RenderLayersProg.h
+++ b/source/blender/compositor/operations/COM_RenderLayersProg.h
@@ -51,7 +51,12 @@ private:
* layerId of the layer where this operation needs to get its data from
*/
short m_layerId;
-
+
+ /**
+ * viewName of the view to use (unless another view is specified by the node
+ */
+ const char *m_viewName;
+
/**
* cached instance to the float buffer inside the layer
*/
@@ -97,6 +102,8 @@ public:
void setRenderData(const RenderData *rd) { this->m_rd = rd; }
void setLayerId(short layerId) { this->m_layerId = layerId; }
short getLayerId() { return this->m_layerId; }
+ void setViewName(const char *viewName) { this->m_viewName = viewName; }
+ const char *getViewName() { return this->m_viewName; }
void initExecution();
void deinitExecution();
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
diff --git a/source/blender/compositor/operations/COM_ViewerOperation.cpp b/source/blender/compositor/operations/COM_ViewerOperation.cpp
index da2706a2244..96ee5ecbb03 100644
--- a/source/blender/compositor/operations/COM_ViewerOperation.cpp
+++ b/source/blender/compositor/operations/COM_ViewerOperation.cpp
@@ -23,6 +23,7 @@
#include "COM_ViewerOperation.h"
#include "BLI_listbase.h"
#include "BKE_image.h"
+#include "BKE_scene.h"
#include "WM_api.h"
#include "WM_types.h"
#include "PIL_time.h"
@@ -57,6 +58,8 @@ ViewerOperation::ViewerOperation() : NodeOperation()
this->m_imageInput = NULL;
this->m_alphaInput = NULL;
this->m_depthInput = NULL;
+ this->m_rd = NULL;
+ this->m_viewName = NULL;
}
void ViewerOperation::initExecution()
@@ -123,8 +126,18 @@ void ViewerOperation::executeRegion(rcti *rect, unsigned int /*tileNumber*/)
void ViewerOperation::initImage()
{
Image *ima = this->m_image;
+ ImageUser iuser = *this->m_imageUser;
void *lock;
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, this->m_imageUser, &lock);
+ ImBuf *ibuf;
+
+ /* make sure the image has the correct number of views */
+ if (ima && BKE_scene_multiview_is_render_view_first(this->m_rd, this->m_viewName)) {
+ BKE_image_verify_viewer_views(this->m_rd, ima, this->m_imageUser);
+ }
+
+ /* local changes to the original ImageUser */
+ iuser.multi_index = BKE_scene_multiview_view_id_get(this->m_rd, this->m_viewName);
+ ibuf = BKE_image_acquire_ibuf(ima, &iuser, &lock);
if (!ibuf) return;
BLI_lock_thread(LOCK_DRAW_IMAGE);
diff --git a/source/blender/compositor/operations/COM_ViewerOperation.h b/source/blender/compositor/operations/COM_ViewerOperation.h
index a17375c2de9..107aee3a82f 100644
--- a/source/blender/compositor/operations/COM_ViewerOperation.h
+++ b/source/blender/compositor/operations/COM_ViewerOperation.h
@@ -40,7 +40,9 @@ private:
bool m_doDepthBuffer;
ImBuf *m_ibuf;
bool m_useAlphaInput;
-
+ const RenderData *m_rd;
+ const char *m_viewName;
+
const ColorManagedViewSettings *m_viewSettings;
const ColorManagedDisplaySettings *m_displaySettings;
@@ -67,6 +69,8 @@ public:
const CompositorPriority getRenderPriority() const;
bool isViewerOperation() const { return true; }
void setUseAlphaInput(bool value) { this->m_useAlphaInput = value; }
+ void setRenderData(const RenderData *rd) { this->m_rd = rd; }
+ void setViewName(const char *viewName) { this->m_viewName = viewName; }
void setViewSettings(const ColorManagedViewSettings *viewSettings) { this->m_viewSettings = viewSettings; }
void setDisplaySettings(const ColorManagedDisplaySettings *displaySettings) { this->m_displaySettings = displaySettings; }