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 'intern/cycles/blender/blender_python.cpp')
-rw-r--r--intern/cycles/blender/blender_python.cpp121
1 files changed, 121 insertions, 0 deletions
diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp
index 9dd0cd4c0bc..bf7605ed5b1 100644
--- a/intern/cycles/blender/blender_python.cpp
+++ b/intern/cycles/blender/blender_python.cpp
@@ -18,9 +18,12 @@
#include "blender/CCL_api.h"
+#include "blender/blender_device.h"
#include "blender/blender_sync.h"
#include "blender/blender_session.h"
+#include "render/denoising.h"
+
#include "util/util_debug.h"
#include "util/util_foreach.h"
#include "util/util_logging.h"
@@ -623,6 +626,121 @@ static PyObject *opencl_disable_func(PyObject * /*self*/, PyObject * /*value*/)
}
#endif
+static bool denoise_parse_filepaths(PyObject *pyfilepaths, vector<string>& filepaths)
+{
+
+ if(PyUnicode_Check(pyfilepaths)) {
+ const char *filepath = PyUnicode_AsUTF8(pyfilepaths);
+ filepaths.push_back(filepath);
+ return true;
+ }
+
+ PyObject *sequence = PySequence_Fast(pyfilepaths, "File paths must be a string or sequence of strings");
+ if(sequence == NULL) {
+ return false;
+ }
+
+ for(Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(sequence); i++) {
+ PyObject *item = PySequence_Fast_GET_ITEM(sequence, i);
+ const char *filepath = PyUnicode_AsUTF8(item);
+ if(filepath == NULL) {
+ PyErr_SetString(PyExc_ValueError, "File paths must be a string or sequence of strings.");
+ Py_DECREF(sequence);
+ return false;
+ }
+ filepaths.push_back(filepath);
+ }
+ Py_DECREF(sequence);
+
+ return true;
+}
+
+static PyObject *denoise_func(PyObject * /*self*/, PyObject *args, PyObject *keywords)
+{
+ static const char *keyword_list[] = {"preferences", "scene", "view_layer",
+ "input", "output",
+ "tile_size", "samples", NULL};
+ PyObject *pypreferences, *pyscene, *pyrenderlayer;
+ PyObject *pyinput, *pyoutput = NULL;
+ int tile_size = 0, samples = 0;
+
+ if (!PyArg_ParseTupleAndKeywords(args, keywords, "OOOO|Oii", (char**)keyword_list,
+ &pypreferences, &pyscene, &pyrenderlayer,
+ &pyinput, &pyoutput,
+ &tile_size, &samples)) {
+ return NULL;
+ }
+
+ /* Get device specification from preferences and scene. */
+ PointerRNA preferencesptr;
+ RNA_pointer_create(NULL, &RNA_UserPreferences, (void*)PyLong_AsVoidPtr(pypreferences), &preferencesptr);
+ BL::UserPreferences b_preferences(preferencesptr);
+
+ PointerRNA sceneptr;
+ RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyscene), &sceneptr);
+ BL::Scene b_scene(sceneptr);
+
+ DeviceInfo device = blender_device_info(b_preferences, b_scene, true);
+
+ /* Get denoising parameters from view layer. */
+ PointerRNA renderlayerptr;
+ RNA_pointer_create((ID*)PyLong_AsVoidPtr(pyscene), &RNA_SceneRenderLayer, PyLong_AsVoidPtr(pyrenderlayer), &renderlayerptr);
+ PointerRNA crenderlayer = RNA_pointer_get(&renderlayerptr, "cycles");
+
+ DenoiseParams params;
+ params.radius = get_int(crenderlayer, "denoising_radius");
+ params.strength = get_float(crenderlayer, "denoising_strength");
+ params.feature_strength = get_float(crenderlayer, "denoising_feature_strength");
+ params.relative_pca = get_boolean(crenderlayer, "denoising_relative_pca");
+ params.neighbor_frames = get_int(crenderlayer, "denoising_neighbor_frames");
+
+ /* Parse file paths list. */
+ vector<string> input, output;
+
+ if(!denoise_parse_filepaths(pyinput, input)) {
+ return NULL;
+ }
+
+ if(pyoutput) {
+ if(!denoise_parse_filepaths(pyoutput, output)) {
+ return NULL;
+ }
+ }
+ else {
+ output = input;
+ }
+
+ if(input.empty()) {
+ PyErr_SetString(PyExc_ValueError, "No input file paths specified.");
+ return NULL;
+ }
+ if(input.size() != output.size()) {
+ PyErr_SetString(PyExc_ValueError, "Number of input and output file paths does not match.");
+ return NULL;
+ }
+
+ /* Create denoiser. */
+ Denoiser denoiser(device);
+ denoiser.params = params;
+ denoiser.input = input;
+ denoiser.output = output;
+
+ if (tile_size > 0) {
+ denoiser.tile_size = make_int2(tile_size, tile_size);
+ }
+ if (samples > 0) {
+ denoiser.samples_override = samples;
+ }
+
+ /* Run denoiser. */
+ if(!denoiser.run()) {
+ PyErr_SetString(PyExc_ValueError, denoiser.error.c_str());
+ return NULL;
+ }
+
+ Py_RETURN_NONE;
+}
+
static PyObject *debug_flags_update_func(PyObject * /*self*/, PyObject *args)
{
PyObject *pyscene;
@@ -783,6 +901,9 @@ static PyMethodDef methods[] = {
{"opencl_disable", opencl_disable_func, METH_NOARGS, ""},
#endif
+ /* Standalone denoising */
+ {"denoise", (PyCFunction)denoise_func, METH_VARARGS|METH_KEYWORDS, ""},
+
/* Debugging routines */
{"debug_flags_update", debug_flags_update_func, METH_VARARGS, ""},
{"debug_flags_reset", debug_flags_reset_func, METH_NOARGS, ""},