[Bf-blender-cvs] [7040a07] soc-2016-cycles_denoising: Cycles Denoising: Add standalone animation denoising call to the Cycles Python API

Lukas Stockner noreply at git.blender.org
Tue Nov 22 04:25:46 CET 2016


Commit: 7040a071cf0e2e4c716d83a95a08b45e71d0cfa7
Author: Lukas Stockner
Date:   Thu Sep 29 20:56:19 2016 +0200
Branches: soc-2016-cycles_denoising
https://developer.blender.org/rB7040a071cf0e2e4c716d83a95a08b45e71d0cfa7

Cycles Denoising: Add standalone animation denoising call to the Cycles Python API

Previously, a build of Cycles Standalone was needed for animation denoising.
Now, it is possible to call it from Python Scripts in Blender or directly from the command line (through --python-expr).

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

M	intern/cycles/app/cycles_denoising.cpp
M	intern/cycles/app/cycles_standalone.cpp
M	intern/cycles/app/cycles_standalone.h
M	intern/cycles/blender/blender_python.cpp
M	intern/cycles/render/CMakeLists.txt
A	intern/cycles/render/denoising.cpp
A	intern/cycles/render/denoising.h

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

diff --git a/intern/cycles/app/cycles_denoising.cpp b/intern/cycles/app/cycles_denoising.cpp
index 3f6c611..a5c0130 100644
--- a/intern/cycles/app/cycles_denoising.cpp
+++ b/intern/cycles/app/cycles_denoising.cpp
@@ -16,218 +16,15 @@
 
 #include "cycles_denoising.h"
 
+#include "denoising.h"
+
 #include "util_image.h"
 
 CCL_NAMESPACE_BEGIN
 
-typedef class PassTypeInfo
-{
-public:
-	PassTypeInfo(DenoiseExtendedTypes type, int num_channels, string channels)
-	 : type(type), num_channels(num_channels), channels(channels) {}
-	PassTypeInfo() : type(EX_TYPE_NONE), num_channels(0), channels("") {}
-
-	DenoiseExtendedTypes type;
-	int num_channels;
-	string channels;
-
-	bool operator<(const PassTypeInfo &other) const {
-		return type < other.type;
-	}
-} PassTypeInfo;
-
-static map<string, PassTypeInfo> denoise_passes_init()
-{
-	map<string, PassTypeInfo> passes;
-
-	passes["DenoiseNormal"]    = PassTypeInfo(EX_TYPE_DENOISE_NORMAL,     3, "XYZ");
-	passes["DenoiseNormalVar"] = PassTypeInfo(EX_TYPE_DENOISE_NORMAL_VAR, 3, "XYZ");
-	passes["DenoiseAlbedo"]    = PassTypeInfo(EX_TYPE_DENOISE_ALBEDO,     3, "RGB");
-	passes["DenoiseAlbedoVar"] = PassTypeInfo(EX_TYPE_DENOISE_ALBEDO_VAR, 3, "RGB");
-	passes["DenoiseDepth"]     = PassTypeInfo(EX_TYPE_DENOISE_DEPTH,      1, "Z");
-	passes["DenoiseDepthVar"]  = PassTypeInfo(EX_TYPE_DENOISE_DEPTH_VAR,  1, "Z");
-	passes["DenoiseShadowA"]   = PassTypeInfo(EX_TYPE_DENOISE_SHADOW_A,   3, "RGB");
-	passes["DenoiseShadowB"]   = PassTypeInfo(EX_TYPE_DENOISE_SHADOW_B,   3, "RGB");
-	passes["DenoiseNoisy"]     = PassTypeInfo(EX_TYPE_DENOISE_NOISY,      3, "RGB");
-	passes["DenoiseNoisyVar"]  = PassTypeInfo(EX_TYPE_DENOISE_NOISY_VAR,  3, "RGB");
-	passes["DenoiseClean"]     = PassTypeInfo(EX_TYPE_DENOISE_CLEAN,      3, "RGB");
-
-	return passes;
-}
-
-static map<string, PassTypeInfo> denoise_passes_map = denoise_passes_init();
-
-static bool split_channel(string full_channel, string &layer, string &pass, string &channel)
-{
-	/* Splits channel name into <layer>.<pass>.<channel> */
-	if(std::count(full_channel.begin(), full_channel.end(), '.') != 2) {
-		return false;
-	}
-
-	int first_dot = full_channel.find(".");
-	int second_dot = full_channel.rfind(".");
-	layer = full_channel.substr(0, first_dot);
-	pass = full_channel.substr(first_dot + 1, second_dot - first_dot - 1);
-	channel = full_channel.substr(second_dot + 1);
-
-	return true;
-}
-
-static int find_channel(string channels, string channel)
-{
-	if(channel.length() != 1) return -1;
-	size_t pos = channels.find(channel);
-	if(pos == string::npos) return -1;
-	return pos;
-}
-
-static RenderBuffers* load_frame(string file, Device *device, RenderBuffers *buffers, int framenum)
-{
-	ImageInput *frame = ImageInput::open(file);
-	if(!frame) {
-		printf("ERROR: Frame %s: Couldn't open file!\n", file.c_str());
-		delete buffers;
-		return NULL;
-	}
-
-	const ImageSpec &spec = frame->spec();
-
-	if(buffers) {
-		if(spec.width != buffers->params.width || spec.height != buffers->params.height) {
-			printf("ERROR: Frame %s: Has different size!\n", file.c_str());
-			delete buffers;
-			return NULL;
-		}
-	}
-
-	/* Find a single RenderLayer to load. */
-	string renderlayer = "";
-	string layer, pass, channel;
-	for(int i = 0; i < spec.nchannels; i++) {
-		if(!split_channel(spec.channelnames[i], layer, pass, channel)) continue;
-		if(pass == "DenoiseNoisy") {
-			renderlayer = layer;
-			break;
-		}
-	}
-
-	if(renderlayer != "") {
-		/* Find all passes that the frame contains. */
-		int passes = EX_TYPE_NONE;
-		map<DenoiseExtendedTypes, int> num_channels;
-		map<PassTypeInfo, int3> channel_ids;
-		for(int i = 0; i < spec.nchannels; i++) {
-			if(!split_channel(spec.channelnames[i], layer, pass, channel)) continue;
-			if(layer != renderlayer) {
-				/* The channel belongs to another RenderLayer. */
-				continue;
-			}
-			if(denoise_passes_map.count(pass)) {
-				PassTypeInfo type = denoise_passes_map[pass];
-				assert(type.num_channels <= 3);
-				/* Pass was found, count the channels. */
-				size_t channel_id = find_channel(type.channels, channel);
-				if(channel_id != -1) {
-					/* This channel is part of the pass, so count it. */
-					num_channels[type.type]++;
-					/* Remember which OIIO channel belongs to which pass. */
-					channel_ids[type][channel_id] = i;
-					if(num_channels[type.type] == type.num_channels) {
-						/* We found all the channels of the pass! */
-						passes |= type.type;
-					}
-				}
-			}
-		}
-
-		/* The frame always needs to include all the required denoising passes.
-		 * If the primary frame also included a clean pass, all the secondary frames need to do so as well. */
-		if((~passes & EX_TYPE_DENOISE_REQUIRED) == 0 && !(buffers && buffers->params.selective_denoising && !(passes & EX_TYPE_DENOISE_CLEAN))) {
-			printf("Frame %s: Found all needed passes!\n", file.c_str());
-
-			if(buffers == NULL) {
-				BufferParams params;
-				params.width  = params.full_width  = params.final_width  = spec.width;
-				params.height = params.full_height = params.final_height = spec.height;
-				params.full_x = params.full_y = 0;
-				params.denoising_passes = true;
-				params.selective_denoising = (passes & EX_TYPE_DENOISE_CLEAN);
-				params.frames = options.filepaths.size();
-
-				buffers = new RenderBuffers(device);
-				buffers->reset(device, params);
-			}
-
-			int4 rect = make_int4(0, 0, buffers->params.width, buffers->params.height);
-			float *pass_data = new float[4*buffers->params.width*buffers->params.height];
-
-			/* Read all the passes from the file. */
-			for(map<PassTypeInfo, int3>::iterator i = channel_ids.begin(); i != channel_ids.end(); i++)
-			{
-				for(int c = 0; c < i->first.num_channels; c++) {
-					int xstride = i->first.num_channels*sizeof(float);
-					int ystride = spec.width * xstride;
-					printf("Reading pass %s!            \r", spec.channelnames[i->second[c]].c_str());
-					fflush(stdout);
-					frame->read_image(i->second[c], i->second[c]+1, TypeDesc::FLOAT, pass_data + c, xstride, ystride);
-				}
-				buffers->get_denoising_rect(i->first.type, 1.0f, options.session_params.samples, i->first.num_channels, rect, pass_data, true, framenum);
-			}
-
-			/* Read combined pass. */
-			int read_combined = 0;
-			for(int i = 0; i < spec.nchannels; i++) {
-				if(!split_channel(spec.channelnames[i], layer, pass, channel)) continue;
-				if(layer != renderlayer || pass != "Combined") continue;
-
-				size_t channel_id = find_channel("RGBA", channel);
-				if(channel_id != -1) {
-					int xstride = 4*sizeof(float);
-					int ystride = spec.width * xstride;
-					printf("Reading pass %s!            \n", spec.channelnames[i].c_str());
-					fflush(stdout);
-					frame->read_image(i, i+1, TypeDesc::FLOAT, pass_data + channel_id, xstride, ystride);
-					read_combined++;
-				}
-			}
-			if(read_combined < 4) {
-				printf("ERROR: Frame %s: Missing combined pass!\n", file.c_str());
-				delete buffers;
-				delete[] pass_data;
-				return NULL;
-			}
-
-			buffers->get_pass_rect(PASS_COMBINED, 1.0f, options.session_params.samples, 4, rect, pass_data, true, framenum);
-
-			delete[] pass_data;
-		}
-		else {
-			printf("ERROR: Frame %s: Missing some pass!\n", file.c_str());
-			delete buffers;
-			return NULL;
-		}
-	}
-	else {
-		printf("ERROR: Frame %s: Didn't fine a suitable RenderLayer!\n", file.c_str());
-		delete buffers;
-		return NULL;
-	}
-
-	frame->close();
-	ImageInput::destroy(frame);
-
-	return buffers;
-}
-
 bool cycles_denoising_session()
 {
-	options.session_params.only_denoise = true;
-	options.session_params.progressive_refine = false;
-	options.session_params.progressive = false;
-	options.session_params.background = true;
-	options.session_params.tile_order = TILE_BOTTOM_TO_TOP;
-	options.session_params.flip_output = false;
-
+	vector<string> frames;
 	if(options.frame_range.y >= options.frame_range.x) {
 		string pattern = options.filepaths[0];
 		size_t pos = pattern.find("%");
@@ -240,43 +37,14 @@ bool cycles_denoising_session()
 		char pad_length = pattern[pos+1];
 		vector<string> new_filepaths;
 		for(int frame = options.frame_range.x; frame <= options.frame_range.y; frame++) {
-
 			string name = pattern.substr(0, pos);
 			name += string_printf(string_printf("%%0%cd", pad_length).c_str(), frame);
 			name += pattern.substr(pos+3);
-			new_filepaths.push_back(name);
+			frames.push_back(name);
 		}
-
-		options.filepaths.swap(new_filepaths);
-
-		options.session_params.prev_frames -= options.frame_range.x;
 	}
 
-	options.session = new Session(options.session_params);
-	options.session->progress.set_update_callback(function_bind(&session_print_status));
-	options.session->set_pause(false);
-
-	RenderBuffers *buffers = NULL;
-	for(int f = 0; f < options.filepaths.size(); f++) {
-		buffers = load_frame(options.filepaths[f], options.session->device, buffers, f);
-		if(!buffers) {
-			delete options.session;
-			return false;
-		}
-	}
-	buffers->copy_to_device();
-
-	options.session->buffers = buffers;
-
-	options.session->start_denoise();
-	options.session->wait();
-
-	/* Required for correct scaling of the output. */
-	options.session->params.samples--;
-
-	delete options.session;
-
-	return true;
+	return denoise_standalone(options.session_params, frames, options.denoise_frame);
 }
 
 CCL_NAMESPACE_END
\ No newline at end of file
diff --git a/intern/cycles/app/cycles_standalone.cpp b/intern/cycles/app/cycles_standalone.cpp
index dc38d0c..95d0120 100644
--- a/intern/cycles/app/cycles_standalone.cpp
+++ b/intern/cycles/app/cycles_standalone.cpp
@@ -367,7 +367,7 @@ static void options_parse(int argc, const char **argv)
 		"--quiet", &options.quiet, "In background mode, don't print progress messages",
 		"--denoise", &denoise, "Denoise the given input file instead of rendering it",
 		"--half-window %d", &options.session_params.half_window, "Size of the denoising window",
-		"--denoise-frame %d", &options.session_params.prev_frames, "Which frame to denoise (together with --frame-range)",
+		"--denoise-frame %d", &options.denoise_frame, "Which frame to denoise (together with --frame-range)",
 		"--frame-range %d %d", &options.frame_range.x, &options.frame_range.y, "Frame Range that's used for deno

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list