[Bf-blender-cvs] [0d78ac4] soc-2016-cycles_denoising: Cycles: Implement Postprocessing callback

Lukas Stockner noreply at git.blender.org
Wed Jul 6 04:28:56 CEST 2016


Commit: 0d78ac4199d9c6d8786019710632100ecfd8df58
Author: Lukas Stockner
Date:   Wed Jul 6 04:20:12 2016 +0200
Branches: soc-2016-cycles_denoising
https://developer.blender.org/rB0d78ac4199d9c6d8786019710632100ecfd8df58

Cycles: Implement Postprocessing callback

This commit finally uses all the work from the earlier commits to implement
the postprocess callback, which triggers a denoising pass on the current
RenderResult.

Note that this does not work on GPUs yet - they can be used for rendering,
but the Device setting has to be switched to CPU rendering before using the
postprocess button.

One other remaining problem is that the Image editor view isn't updated automatically,
you have to switch to another pass/layer and back to see the change.

Also, the feature should eventually be implemeted as a Job to get a progress bar and a
responding UI during denoising.

===================================================================

M	intern/cycles/blender/addon/__init__.py
M	intern/cycles/blender/addon/engine.py
M	intern/cycles/blender/blender_python.cpp
M	intern/cycles/blender/blender_session.cpp
M	intern/cycles/blender/blender_session.h
M	source/blender/editors/space_image/image_ops.c
M	source/blender/render/extern/include/RE_engine.h
M	source/blender/render/intern/source/external_engine.c

===================================================================

diff --git a/intern/cycles/blender/addon/__init__.py b/intern/cycles/blender/addon/__init__.py
index ef4342a..80841eb 100644
--- a/intern/cycles/blender/addon/__init__.py
+++ b/intern/cycles/blender/addon/__init__.py
@@ -93,7 +93,7 @@ class CyclesRender(bpy.types.RenderEngine):
         return engine.can_postprocess(result)
 
     def postprocess(self, scene, result):
-        engine.postprocess(scene, result);
+        engine.postprocess(self, scene, result);
 
 
 def engine_exit():
diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py
index 61eb891..15453d0 100644
--- a/intern/cycles/blender/addon/engine.py
+++ b/intern/cycles/blender/addon/engine.py
@@ -194,6 +194,8 @@ def can_postprocess(result):
     import _cycles
     return _cycles.can_postprocess(result.as_pointer())
 
-def postprocess(scene, result):
+def postprocess(engine, scene, result):
+    import bpy
     import _cycles
-    _cycles.postprocess(scene.as_pointer(), result.as_pointer())
+    userpref = bpy.context.user_preferences.as_pointer()
+    _cycles.postprocess(engine.as_pointer(), userpref, scene.as_pointer(), result.as_pointer())
diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp
index e501941..9fb39bd 100644
--- a/intern/cycles/blender/blender_python.cpp
+++ b/intern/cycles/blender/blender_python.cpp
@@ -694,20 +694,31 @@ static PyObject *can_postprocess_func(PyObject * /*self*/, PyObject *args)
 
 static PyObject *postprocess_func(PyObject * /*self*/, PyObject *args)
 {
-	PyObject *pyresult, *pyscene;
+	PyObject *pyresult, *pyengine, *pyuserpref, *pyscene;
 
-	if(!PyArg_ParseTuple(args, "OO", &pyscene, &pyresult))
+	if(!PyArg_ParseTuple(args, "OOOO", &pyengine, &pyuserpref, &pyscene, &pyresult))
 		return NULL;
 
 	/* RNA */
+	PointerRNA engineptr;
+	RNA_pointer_create(NULL, &RNA_RenderEngine, (void*)PyLong_AsVoidPtr(pyengine), &engineptr);
+	BL::RenderEngine engine(engineptr);
+
+	PointerRNA userprefptr;
+	RNA_pointer_create(NULL, &RNA_UserPreferences, (void*)PyLong_AsVoidPtr(pyuserpref), &userprefptr);
+	BL::UserPreferences userpref(userprefptr);
+
 	PointerRNA sceneptr;
-	RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyscene), &sceneptr);
+	RNA_pointer_create(NULL, &RNA_Scene, (void*)PyLong_AsVoidPtr(pyscene), &sceneptr);
 	BL::Scene scene(sceneptr);
 
 	PointerRNA resultptr;
 	RNA_pointer_create(NULL, &RNA_RenderResult, (void*)PyLong_AsVoidPtr(pyresult), &resultptr);
 	BL::RenderResult b_rr(resultptr);
 
+	BlenderSession session(engine, userpref, scene);
+	session.denoise(b_rr);
+
 	Py_RETURN_NONE;
 }
 
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index 63f5626..585617c 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -94,6 +94,30 @@ BlenderSession::BlenderSession(BL::RenderEngine& b_engine,
 	start_resize_time = 0.0;
 }
 
+BlenderSession::BlenderSession(BL::RenderEngine& b_engine,
+                               BL::UserPreferences& b_userpref,
+                               BL::Scene& b_scene)
+: b_engine(b_engine),
+  b_userpref(b_userpref),
+  b_data(PointerRNA_NULL),
+  b_render(PointerRNA_NULL),
+  b_scene(b_scene),
+  b_v3d(PointerRNA_NULL),
+  b_rv3d(PointerRNA_NULL),
+  python_thread_state(NULL)
+{
+	width = 0;
+	height = 0;
+
+	sync = NULL;
+	session = NULL;
+	scene = NULL;
+
+	background = true;
+	last_redraw_time = 0.0;
+	start_resize_time = 0.0;
+}
+
 BlenderSession::~BlenderSession()
 {
 	free_session();
@@ -1325,6 +1349,49 @@ void BlenderSession::update_resumable_tile_manager(int num_samples)
 	session->tile_manager.range_num_samples = range_num_samples;
 }
 
+void BlenderSession::denoise(BL::RenderResult& b_rr)
+{
+	PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
+
+	SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, true);
+	session_params.only_denoise = true;
+	session_params.progressive_refine = false;
+	session_params.progressive = false;
+	session_params.samples = 1;
+	session_params.start_resolution = 1;
+	session = new Session(session_params);
+	session->set_pause(false);
+
+	session->write_render_tile_cb = function_bind(&BlenderSession::write_render_tile, this, _1);
+	session->update_render_tile_cb = function_bind(&BlenderSession::update_render_tile, this, _1, _2);
+
+	BL::RenderResult::layers_iterator b_layer_iter;
+	for(b_rr.layers.begin(b_layer_iter); b_layer_iter != b_rr.layers.end(); ++b_layer_iter) {
+		/* Search corresponding scene layer to get the half window. */
+		BL::RenderSettings r = b_scene.render();
+		BL::RenderSettings::layers_iterator b_s_layer_iter;
+		int half_window = -1;
+		for(r.layers.begin(b_s_layer_iter); b_s_layer_iter != r.layers.end(); ++b_s_layer_iter) {
+			if(b_s_layer_iter->name() == b_layer_iter->name()) {
+				half_window = b_s_layer_iter->half_window();
+				break;
+			}
+		}
+		assert(half_window != -1);
+
+		session->params.half_window = half_window;
+		session->params.samples = get_int(cscene, "samples");
+
+		session->buffers = BlenderSync::get_render_buffer(session->device, *b_layer_iter, b_rr, session->params.samples);
+
+		session->start_denoise();
+		session->wait();
+
+		delete session->buffers;
+		session->buffers = NULL;
+	}
+}
+
 bool can_denoise_render_result(BL::RenderResult& b_rr)
 {
 	/* Since the RenderResult may contain multiple layers,
diff --git a/intern/cycles/blender/blender_session.h b/intern/cycles/blender/blender_session.h
index 32093d9..e579f55 100644
--- a/intern/cycles/blender/blender_session.h
+++ b/intern/cycles/blender/blender_session.h
@@ -46,6 +46,10 @@ public:
 	               BL::RegionView3D& b_rv3d,
 	               int width, int height);
 
+	BlenderSession(BL::RenderEngine& b_engine,
+	               BL::UserPreferences& b_userpref,
+	               BL::Scene& b_scene);
+
 	~BlenderSession();
 
 	void create();
@@ -57,6 +61,9 @@ public:
 	void reset_session(BL::BlendData& b_data,
 	                   BL::Scene& b_scene);
 
+	/* denoising */
+	void denoise(BL::RenderResult& b_rr);
+
 	/* offline render */
 	void render();
 
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 7ed8152..2c4c5f3 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -3697,13 +3697,15 @@ static int postprocess_exec(bContext *C, wmOperator *UNUSED(op))
 	Scene *scene = CTX_data_scene(C);
 	Image *ima = CTX_data_edit_image(C);
 	RenderResult *rr = BKE_image_acquire_renderresult(scene, ima);
-	RenderEngineType *type = RE_engines_find(scene->r.engine);
-	RenderEngine *engine = RE_engine_create(type);
 
-	type->postprocess(engine, scene, rr);
+	RE_engine_postprocess(scene, rr);
 
 	BKE_image_release_renderresult(scene, ima);
-	RE_engine_free(engine);
+
+	BKE_image_multilayer_index(rr, &CTX_wm_space_image(C)->iuser);
+	WM_event_add_notifier(C, NC_IMAGE | ND_DRAW, NULL);
+
+	ED_region_tag_redraw(CTX_wm_region(C));
 
 	return OPERATOR_FINISHED;
 }
diff --git a/source/blender/render/extern/include/RE_engine.h b/source/blender/render/extern/include/RE_engine.h
index 70d5279..2a1a2fb 100644
--- a/source/blender/render/extern/include/RE_engine.h
+++ b/source/blender/render/extern/include/RE_engine.h
@@ -160,6 +160,7 @@ void RE_engine_update_memory_stats(RenderEngine *engine, float mem_used, float m
 void RE_engine_report(RenderEngine *engine, int type, const char *msg);
 void RE_engine_set_error_message(RenderEngine *engine, const char *msg);
 
+void RE_engine_postprocess(struct Scene *scene, struct RenderResult *rr);
 int RE_engine_render(struct Render *re, int do_all);
 
 bool RE_engine_is_external(struct Render *re);
diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c
index bac6dfb..a5d452d 100644
--- a/source/blender/render/intern/source/external_engine.c
+++ b/source/blender/render/intern/source/external_engine.c
@@ -598,6 +598,23 @@ static bool render_layer_exclude_animated(Scene *scene, SceneRenderLayer *srl)
 	return RNA_property_animated(&ptr, prop);
 }
 
+void RE_engine_postprocess(Scene *scene, RenderResult *rr)
+{
+	RenderEngineType *type = RE_engines_find(scene->r.engine);
+	RenderEngine *engine = RE_engine_create(type);
+
+	Render *re = RE_NewRender(scene->id.name);
+
+	engine->re = re;
+	engine->re->result = rr;
+	engine->tile_x = scene->r.tilex;
+	engine->tile_y = scene->r.tiley;
+
+	type->postprocess(engine, scene, rr);
+
+	RE_engine_free(engine);
+}
+
 int RE_engine_render(Render *re, int do_all)
 {
 	RenderEngineType *type = RE_engines_find(re->r.engine);




More information about the Bf-blender-cvs mailing list