Cycles: add cycles.merge_images operator for combing EXR renders.
This is only available through the API, mainly intended for render farms to combine rendered multilayer EXR Files with different samples. The images are currently expected to have the exact same render layers and passes, just with different samples. Variance passes are still simply a weighted average, ideally these should be merged more intelligently. Differential Revision: https://developer.blender.org/D4554
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
#include "blender/blender_session.h"
|
||||
|
||||
#include "render/denoising.h"
|
||||
#include "render/merge.h"
|
||||
|
||||
#include "util/util_debug.h"
|
||||
#include "util/util_foreach.h"
|
||||
@@ -638,9 +639,8 @@ static PyObject *opencl_compile_func(PyObject * /*self*/, PyObject *args)
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool denoise_parse_filepaths(PyObject *pyfilepaths, vector<string>& filepaths)
|
||||
static bool image_parse_filepaths(PyObject *pyfilepaths, vector<string>& filepaths)
|
||||
{
|
||||
|
||||
if(PyUnicode_Check(pyfilepaths)) {
|
||||
const char *filepath = PyUnicode_AsUTF8(pyfilepaths);
|
||||
filepaths.push_back(filepath);
|
||||
@@ -709,12 +709,12 @@ static PyObject *denoise_func(PyObject * /*self*/, PyObject *args, PyObject *key
|
||||
/* Parse file paths list. */
|
||||
vector<string> input, output;
|
||||
|
||||
if(!denoise_parse_filepaths(pyinput, input)) {
|
||||
if(!image_parse_filepaths(pyinput, input)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(pyoutput) {
|
||||
if(!denoise_parse_filepaths(pyoutput, output)) {
|
||||
if(!image_parse_filepaths(pyoutput, output)) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -753,6 +753,42 @@ static PyObject *denoise_func(PyObject * /*self*/, PyObject *args, PyObject *key
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *merge_func(PyObject * /*self*/, PyObject *args, PyObject *keywords)
|
||||
{
|
||||
static const char *keyword_list[] = {"input", "output", NULL};
|
||||
PyObject *pyinput, *pyoutput = NULL;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, keywords, "OO", (char**)keyword_list, &pyinput, &pyoutput)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Parse input list. */
|
||||
vector<string> input;
|
||||
if(!image_parse_filepaths(pyinput, input)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Parse output string. */
|
||||
if(!PyUnicode_Check(pyoutput)) {
|
||||
PyErr_SetString(PyExc_ValueError, "Output must be a string.");
|
||||
return NULL;
|
||||
}
|
||||
string output = PyUnicode_AsUTF8(pyoutput);
|
||||
|
||||
/* Merge. */
|
||||
ImageMerger merger;
|
||||
merger.input = input;
|
||||
merger.output = output;
|
||||
|
||||
if(!merger.run()) {
|
||||
PyErr_SetString(PyExc_ValueError, merger.error.c_str());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
static PyObject *debug_flags_update_func(PyObject * /*self*/, PyObject *args)
|
||||
{
|
||||
PyObject *pyscene;
|
||||
@@ -916,6 +952,7 @@ static PyMethodDef methods[] = {
|
||||
|
||||
/* Standalone denoising */
|
||||
{"denoise", (PyCFunction)denoise_func, METH_VARARGS|METH_KEYWORDS, ""},
|
||||
{"merge", (PyCFunction)merge_func, METH_VARARGS|METH_KEYWORDS, ""},
|
||||
|
||||
/* Debugging routines */
|
||||
{"debug_flags_update", debug_flags_update_func, METH_VARARGS, ""},
|
||||
|
||||
Reference in New Issue
Block a user