2
* Copyright 2011, Blender Foundation.
4
* This program is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU General Public License
6
* as published by the Free Software Foundation; either version 2
7
* of the License, or (at your option) any later version.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software Foundation,
16
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
27
#include "util_args.h"
28
#include "util_foreach.h"
29
#include "util_function.h"
30
#include "util_path.h"
31
#include "util_progress.h"
32
#include "util_string.h"
33
#include "util_time.h"
34
#include "util_view.h"
36
#include "cycles_xml.h"
45
SceneParams scene_params;
46
SessionParams session_params;
50
static void session_print(const string& str)
52
/* print with carriage return to overwrite previous */
53
printf("\r%s", str.c_str());
55
/* add spaces to overwrite longer previous print */
56
static int maxlen = 0;
58
maxlen = max(len, maxlen);
60
for(int i = len; i < maxlen; i++)
63
/* flush because we don't write an end of line */
67
static void session_print_status()
70
double total_time, sample_time;
71
string status, substatus;
74
sample = options.session->progress.get_sample();
75
options.session->progress.get_tile(tile, total_time, sample_time);
76
options.session->progress.get_status(status, substatus);
79
status += ": " + substatus;
82
status = string_printf("Sample %d %s", sample, status.c_str());
83
session_print(status);
86
static BufferParams& session_buffer_params()
88
static BufferParams buffer_params;
89
buffer_params.width = options.width;
90
buffer_params.height = options.height;
91
buffer_params.full_width = options.width;
92
buffer_params.full_height = options.height;
97
static void session_init()
99
options.session = new Session(options.session_params);
100
options.session->reset(session_buffer_params(), options.session_params.samples);
101
options.session->scene = options.scene;
103
if(options.session_params.background && !options.quiet)
104
options.session->progress.set_update_callback(function_bind(&session_print_status));
106
options.session->progress.set_update_callback(function_bind(&view_redraw));
108
options.session->start();
110
options.scene = NULL;
113
static void scene_init(int width, int height)
115
options.scene = new Scene(options.scene_params, options.session_params.device);
116
xml_read_file(options.scene, options.filepath.c_str());
118
if (width == 0 || height == 0) {
119
options.width = options.scene->camera->width;
120
options.height = options.scene->camera->height;
124
static void session_exit()
126
if(options.session) {
127
delete options.session;
128
options.session = NULL;
131
delete options.scene;
132
options.scene = NULL;
135
if(options.session_params.background && !options.quiet) {
136
session_print("Finished Rendering.");
141
static void display_info(Progress& progress)
143
static double latency = 0.0;
144
static double last = 0;
145
double elapsed = time_dt();
148
latency = (elapsed - last);
152
double total_time, sample_time;
153
string status, substatus;
155
sample = progress.get_sample();
156
progress.get_tile(tile, total_time, sample_time);
157
progress.get_status(status, substatus);
160
status += ": " + substatus;
162
str = string_printf("latency: %.4f sample: %d total: %.4f average: %.4f %s",
163
latency, sample, total_time, sample_time, status.c_str());
165
view_display_info(str.c_str());
168
static void display()
170
options.session->draw(session_buffer_params());
172
display_info(options.session->progress);
175
static void resize(int width, int height)
177
options.width = width;
178
options.height = height;
181
options.session->reset(session_buffer_params(), options.session_params.samples);
184
void keyboard(unsigned char key)
187
options.session->reset(session_buffer_params(), options.session_params.samples);
188
else if(key == 27) // escape
189
options.session->progress.set_cancel("Cancelled");
192
static int files_parse(int argc, const char *argv[])
195
options.filepath = argv[0];
200
static void options_parse(int argc, const char **argv)
204
options.filepath = "";
205
options.session = NULL;
206
options.quiet = false;
209
string device_names = "";
210
string devicename = "cpu";
213
vector<DeviceType>& types = Device::available_types();
215
foreach(DeviceType type, types) {
216
if(device_names != "")
217
device_names += ", ";
219
device_names += Device::string_from_type(type);
223
string ssname = "svm";
224
string shadingsystems = "Shading system to use: svm";
227
shadingsystems += ", osl";
234
ap.options ("Usage: cycles_test [options] file.xml",
235
"%*", files_parse, "",
236
"--device %s", &devicename, ("Devices to use: " + device_names).c_str(),
237
"--shadingsys %s", &ssname, "Shading system to use: svm, osl",
238
"--background", &options.session_params.background, "Render in background, without user interface",
239
"--quiet", &options.quiet, "In background mode, don't print progress messages",
240
"--samples %d", &options.session_params.samples, "Number of samples to render",
241
"--output %s", &options.session_params.output_path, "File path to write output image",
242
"--threads %d", &options.session_params.threads, "CPU Rendering Threads",
243
"--width %d", &options.width, "Window width in pixel",
244
"--height %d", &options.height, "Window height in pixel",
245
"--list-devices", &list, "List information about all available devices",
246
"--help", &help, "Print help message",
249
if(ap.parse(argc, argv) < 0) {
250
fprintf(stderr, "%s\n", ap.geterror().c_str());
255
vector<DeviceInfo>& devices = Device::available_devices();
256
printf("Devices:\n");
258
foreach(DeviceInfo& info, devices) {
260
info.description.c_str(),
261
(info.display_device)? " (display)": "");
266
else if(help || options.filepath == "") {
272
options.scene_params.shadingsystem = SceneParams::OSL;
273
else if(ssname == "svm")
274
options.scene_params.shadingsystem = SceneParams::SVM;
276
/* Progressive rendering */
277
options.session_params.progressive = true;
279
/* find matching device */
280
DeviceType device_type = Device::type_from_string(devicename.c_str());
281
vector<DeviceInfo>& devices = Device::available_devices();
282
DeviceInfo device_info;
283
bool device_available = false;
285
foreach(DeviceInfo& device, devices) {
286
if(device_type == device.type) {
287
options.session_params.device = device;
288
device_available = true;
293
/* handle invalid configurations */
294
if(options.session_params.device.type == DEVICE_NONE || !device_available) {
295
fprintf(stderr, "Unknown device: %s\n", devicename.c_str());
299
else if(!(ssname == "osl" || ssname == "svm")) {
301
else if(!(ssname == "svm")) {
303
fprintf(stderr, "Unknown shading system: %s\n", ssname.c_str());
306
else if(options.scene_params.shadingsystem == SceneParams::OSL && options.session_params.device.type != DEVICE_CPU) {
307
fprintf(stderr, "OSL shading system only works with CPU device\n");
310
else if(options.session_params.samples < 0) {
311
fprintf(stderr, "Invalid number of samples: %d\n", options.session_params.samples);
314
else if(options.filepath == "") {
315
fprintf(stderr, "No file path specified\n");
320
scene_init(options.width, options.height);
327
int main(int argc, const char **argv)
331
options_parse(argc, argv);
333
if(options.session_params.background) {
335
options.session->wait();
339
string title = "Cycles: " + path_filename(options.filepath);
341
/* init/exit are callback so they run while GL is initialized */
342
view_main_loop(title.c_str(), options.width, options.height,
343
session_init, session_exit, resize, display, keyboard);