Commit: 4f1e311d1b39d27fc2227b790714b81697e57ded Author: Dalai Felinto Date: Fri Aug 22 19:32:49 2014 +0200 Branches: multiview https://developer.blender.org/rB4f1e311d1b39d27fc2227b790714b81697e57ded
Compositor: File Output File output working for stereo output (so each individual input can be outputted as a separated stereo format) Not supported at the moment: * Multilayer + stereo output Not fully working (though it should): * Multiview =================================================================== M source/blender/compositor/nodes/COM_OutputFileNode.cpp M source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cpp M source/blender/compositor/operations/COM_OutputFileMultiViewOperation.h M source/blender/compositor/operations/COM_OutputFileOperation.cpp M source/blender/compositor/operations/COM_OutputFileOperation.h M source/blender/imbuf/intern/openexr/openexr_api.cpp M source/blender/imbuf/intern/openexr/openexr_multi.h M source/blender/imbuf/intern/openexr/openexr_stub.cpp =================================================================== diff --git a/source/blender/compositor/nodes/COM_OutputFileNode.cpp b/source/blender/compositor/nodes/COM_OutputFileNode.cpp index 70bb548..3dd25e6 100644 --- a/source/blender/compositor/nodes/COM_OutputFileNode.cpp +++ b/source/blender/compositor/nodes/COM_OutputFileNode.cpp @@ -26,6 +26,8 @@ #include "COM_OutputFileMultiViewOperation.h" #include "COM_ExecutionSystem.h" +#include "BKE_scene.h" + #include "BLI_path_util.h" OutputFileNode::OutputFileNode(bNode *editorNode) : Node(editorNode) @@ -84,16 +86,30 @@ void OutputFileNode::convertToOperations(NodeConverter &converter, const Composi NodeImageMultiFileSocket *sockdata = (NodeImageMultiFileSocket *)input->getbNodeSocket()->storage; ImageFormatData *format = (sockdata->use_node_format ? &storage->format : &sockdata->format); char path[FILE_MAX]; - + /* combine file path for the input */ BLI_join_dirfile(path, FILE_MAX, storage->base_path, sockdata->path); - - OutputSingleLayerOperation *outputOperation = new OutputSingleLayerOperation( - context.getRenderData(), context.getbNodeTree(), input->getDataType(), format, path, - context.getViewSettings(), context.getDisplaySettings(), context.getViewId()); + + NodeOperation *outputOperation = NULL; + + if (format->imtype == R_IMF_IMTYPE_MULTIVIEW) { + outputOperation = new OutputOpenExrMultiViewOperation( + context.getRenderData(), context.getbNodeTree(), path, format->exr_codec, context.getViewId()); + } + else if (format->views_output == R_IMF_VIEWS_INDIVIDUAL) { + outputOperation = new OutputSingleLayerOperation( + context.getRenderData(), context.getbNodeTree(), input->getDataType(), format, path, + context.getViewSettings(), context.getDisplaySettings(), context.getViewId()); + } + else { /* R_IMF_VIEWS_STEREO_3D */ + outputOperation = new OutputStereoOperation( + context.getRenderData(), context.getbNodeTree(), input->getDataType(), format, path, + sockdata->layer, context.getViewSettings(), context.getDisplaySettings(), context.getViewId()); + } + converter.addOperation(outputOperation); - converter.mapInputSocket(input, outputOperation->getInputSocket(0)); + if (!previewAdded) { converter.addNodeInputPreview(input); previewAdded = true; diff --git a/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cpp b/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cpp index 0f1543a..1e34db4 100644 --- a/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cpp +++ b/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.cpp @@ -32,6 +32,7 @@ #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" @@ -138,7 +139,7 @@ void OutputOpenExrMultiViewOperation::deinitExecution() char filename[FILE_MAX]; BKE_makepicstring_from_type(filename, this->m_path, bmain->name, this->m_rd->cfra, R_IMF_IMTYPE_MULTIVIEW, - (this->m_rd->scemode & R_EXTENSION), true, ""); + (this->m_rd->scemode & R_EXTENSION), true, ""); exrhandle = this->get_handle(filename); @@ -198,3 +199,115 @@ void OutputOpenExrMultiViewOperation::deinitExecution() IMB_exr_close(exrhandle); } } + + +/******************************** Stereo3D ******************************/ + +static int get_datatype_size(DataType datatype) +{ + switch (datatype) { + case COM_DT_VALUE: return 1; + case COM_DT_VECTOR: return 3; + case COM_DT_COLOR: return 4; + default: return 0; + } +} + +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 int actview): + OutputSingleLayerOperation(rd, tree, datatype, format, path, viewSettings, displaySettings, actview) +{ + 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 (this->m_actview > 0) { + 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; + char view[64]; + + exrhandle = this->get_handle(m_path); + IMB_exr_get_multiView_name(exrhandle, this->m_actview, view); + + float *buf = this->m_outputBuffer; + + /* populate single EXR channel with view data */ + IMB_exr_add_channel(exrhandle, NULL, m_name, view, 1, this-> m_channels * width * height, buf); + + this->m_imageInput = NULL; + this->m_outputBuffer = NULL; + + /* create stereo ibuf */ + if (this->m_actview >= BKE_render_num_views(this->m_rd) - 1) { + 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_stereoImBuf(this->m_format, ibuf[0], ibuf[1]); + + BKE_makepicstring(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); + + /* cleanup */ + /* 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 index bb22bcd..c7246bb 100644 --- a/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.h +++ b/source/blender/compositor/operations/COM_OutputFileMultiViewOperation.h @@ -30,6 +30,7 @@ #include "BLI_path_util.h" #include "DNA_color_types.h" +#include "DNA_userdef_types.h" #include "intern/openexr/openexr_multi.h" @@ -43,4 +44,18 @@ public: 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, int actview); + 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 879f746..c004188 100644 --- a/source/blender/compositor/operations/COM_OutputFileOperation.cpp +++ b/source/blender/compositor/operations/COM_OutputFileOperation.cpp @@ -182,6 +182,7 @@ void OutputSingleLayerOperation::deinitExecution() this->m_imageInput = NULL; } +/******************************* MultiLayer *******************************/ OutputOpenExrLayer::OutputOpenExrLayer(const char *name_, DataType datatype_, bool use_layer_) { diff --git a/source/blender/compositor/operations/COM_OutputFileOperation.h b/source/blender/compositor/operations/COM_OutputFileOperation.h index 875e47f..8d882b7 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; diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp index be1f232..f8e0c16 100644 --- a/source/blender/imbuf/intern/openexr/openexr_api.cpp +++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp @@ -1056,6 +1056,34 @@ void IMB_exr_set_channel(void *handle, const char *layname, const char *passname printf("IMB_exr_set_channel error %s\n", name); } +float *IMB_exr_channel_rect(void *handle, const char *layname, const char *passname, const char *view) +{ + ExrHandle *data = (ExrHandle *)handle; + ExrChannel *echan; + char name[EXR_TOT_MAXNAME + 1]; + + if (layname) { + char lay[EXR_LAY_MAXNAME + 1], pass[EXR_PASS_MAXNAME + 1]; + BLI_strncpy(lay, layname, EXR_LAY_MAXNAME); + BLI_strncpy(pass, passname, EXR_PASS_MAXNAME); + + BLI_snprintf(name, sizeof(name), "%s.%s", lay, pass); + } + else + BLI_strncpy(name, passname, EXR_TOT_MAXNAME - 1); + + /* name has to be unique, thus it's a combination of layer, pass, view, and channel */ + std::string raw_name = imb_exr_insert_view_name(name, view); + BLI_strncpy(name, raw_name.c @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org http://lists.blender.org/mailman/listinfo/bf-blender-cvs