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:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2019-03-19 16:38:57 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2019-03-19 20:23:19 +0300
commit83de13f75aafca7d4e1d58ddd36cca19121aa84f (patch)
treeb8215ab3ba18ca729d0f3119e0f5cd6540054e33 /intern/cycles/blender
parent5b7b7101c81ca104111e0df76cccf5b1c88bd3f6 (diff)
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
Diffstat (limited to 'intern/cycles/blender')
-rw-r--r--intern/cycles/blender/addon/operators.py41
-rw-r--r--intern/cycles/blender/blender_python.cpp45
-rw-r--r--intern/cycles/blender/blender_util.h1
3 files changed, 81 insertions, 6 deletions
diff --git a/intern/cycles/blender/addon/operators.py b/intern/cycles/blender/addon/operators.py
index 28657de24d4..f8511dc8de4 100644
--- a/intern/cycles/blender/addon/operators.py
+++ b/intern/cycles/blender/addon/operators.py
@@ -124,9 +124,48 @@ class CYCLES_OT_denoise_animation(Operator):
return {'FINISHED'}
+class CYCLES_OT_merge_images(Operator):
+ "Combine OpenEXR multilayer images rendered with different sample" \
+ "ranges into one image with reduced noise."
+ bl_idname = "cycles.merge_images"
+ bl_label = "Merge Images"
+
+ input_filepath1: StringProperty(
+ name='Input Filepath',
+ description='File path for image to merge',
+ default='',
+ subtype='FILE_PATH')
+
+ input_filepath2: StringProperty(
+ name='Input Filepath',
+ description='File path for image to merge',
+ default='',
+ subtype='FILE_PATH')
+
+ output_filepath: StringProperty(
+ name='Output Filepath',
+ description='File path for merged image',
+ default='',
+ subtype='FILE_PATH')
+
+ def execute(self, context):
+ in_filepaths = [self.input_filepath1, self.input_filepath2]
+ out_filepath = self.output_filepath
+
+ import _cycles
+ try:
+ _cycles.merge(input=in_filepaths, output=out_filepath)
+ except Exception as e:
+ self.report({'ERROR'}, str(e))
+ return {'FINISHED'}
+
+ return {'FINISHED'}
+
+
classes = (
CYCLES_OT_use_shading_nodes,
- CYCLES_OT_denoise_animation
+ CYCLES_OT_denoise_animation,
+ CYCLES_OT_merge_images
)
def register():
diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp
index 647e7c6374b..063b0ede92b 100644
--- a/intern/cycles/blender/blender_python.cpp
+++ b/intern/cycles/blender/blender_python.cpp
@@ -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, ""},
diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h
index eb7019f45bc..a2c1a68c454 100644
--- a/intern/cycles/blender/blender_util.h
+++ b/intern/cycles/blender/blender_util.h
@@ -32,7 +32,6 @@
* todo: clean this up ... */
extern "C" {
-size_t BLI_timecode_string_from_time_simple(char *str, size_t maxlen, double time_seconds);
void BKE_image_user_frame_calc(void *iuser, int cfra, int fieldnr);
void BKE_image_user_file_path(void *iuser, void *ima, char *path);
unsigned char *BKE_image_get_pixels_for_frame(void *image, int frame);