Blender V2.61 - r43446
|
00001 /* 00002 * Copyright 2011, Blender Foundation. 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 */ 00018 00019 #include <stdio.h> 00020 00021 #include "buffers.h" 00022 #include "camera.h" 00023 #include "device.h" 00024 #include "scene.h" 00025 #include "session.h" 00026 00027 #include "util_args.h" 00028 #include "util_foreach.h" 00029 #include "util_function.h" 00030 #include "util_path.h" 00031 #include "util_progress.h" 00032 #include "util_string.h" 00033 #include "util_time.h" 00034 #include "util_view.h" 00035 00036 #include "cycles_xml.h" 00037 00038 CCL_NAMESPACE_BEGIN 00039 00040 struct Options { 00041 Session *session; 00042 Scene *scene; 00043 string filepath; 00044 int width, height; 00045 SceneParams scene_params; 00046 SessionParams session_params; 00047 bool quiet; 00048 } options; 00049 00050 static void session_print(const string& str) 00051 { 00052 /* print with carriage return to overwrite previous */ 00053 printf("\r%s", str.c_str()); 00054 00055 /* add spaces to overwrite longer previous print */ 00056 static int maxlen = 0; 00057 int len = str.size(); 00058 maxlen = max(len, maxlen); 00059 00060 for(int i = len; i < maxlen; i++) 00061 printf(" "); 00062 00063 /* flush because we don't write an end of line */ 00064 fflush(stdout); 00065 } 00066 00067 static void session_print_status() 00068 { 00069 int sample; 00070 double total_time, sample_time; 00071 string status, substatus; 00072 00073 /* get status */ 00074 options.session->progress.get_sample(sample, total_time, sample_time); 00075 options.session->progress.get_status(status, substatus); 00076 00077 if(substatus != "") 00078 status += ": " + substatus; 00079 00080 /* print status */ 00081 status = string_printf("Sample %d %s", sample, status.c_str()); 00082 session_print(status); 00083 } 00084 00085 static BufferParams& session_buffer_params() 00086 { 00087 static BufferParams buffer_params; 00088 buffer_params.width = options.width; 00089 buffer_params.height = options.height; 00090 buffer_params.full_width = options.width; 00091 buffer_params.full_height = options.height; 00092 00093 return buffer_params; 00094 } 00095 00096 static void session_init() 00097 { 00098 options.session = new Session(options.session_params); 00099 options.session->reset(session_buffer_params(), options.session_params.samples); 00100 options.session->scene = options.scene; 00101 00102 if(options.session_params.background && !options.quiet) 00103 options.session->progress.set_update_callback(function_bind(&session_print_status)); 00104 else 00105 options.session->progress.set_update_callback(function_bind(&view_redraw)); 00106 00107 options.session->start(); 00108 00109 options.scene = NULL; 00110 } 00111 00112 static void scene_init(int width, int height) 00113 { 00114 options.scene = new Scene(options.scene_params); 00115 xml_read_file(options.scene, options.filepath.c_str()); 00116 00117 if (width == 0 || height == 0) { 00118 options.width = options.scene->camera->width; 00119 options.height = options.scene->camera->height; 00120 } 00121 } 00122 00123 static void session_exit() 00124 { 00125 if(options.session) { 00126 delete options.session; 00127 options.session = NULL; 00128 } 00129 if(options.scene) { 00130 delete options.scene; 00131 options.scene = NULL; 00132 } 00133 00134 if(options.session_params.background && !options.quiet) { 00135 session_print("Finished Rendering."); 00136 printf("\n"); 00137 } 00138 } 00139 00140 static void display_info(Progress& progress) 00141 { 00142 static double latency = 0.0; 00143 static double last = 0; 00144 double elapsed = time_dt(); 00145 string str; 00146 00147 latency = (elapsed - last); 00148 last = elapsed; 00149 00150 int sample; 00151 double total_time, sample_time; 00152 string status, substatus; 00153 00154 progress.get_sample(sample, total_time, sample_time); 00155 progress.get_status(status, substatus); 00156 00157 if(substatus != "") 00158 status += ": " + substatus; 00159 00160 str = string_printf("latency: %.4f sample: %d total: %.4f average: %.4f %s", 00161 latency, sample, total_time, sample_time, status.c_str()); 00162 00163 view_display_info(str.c_str()); 00164 } 00165 00166 static void display() 00167 { 00168 options.session->draw(session_buffer_params()); 00169 00170 display_info(options.session->progress); 00171 } 00172 00173 static void resize(int width, int height) 00174 { 00175 options.width= width; 00176 options.height= height; 00177 00178 if(options.session) 00179 options.session->reset(session_buffer_params(), options.session_params.samples); 00180 } 00181 00182 void keyboard(unsigned char key) 00183 { 00184 if(key == 'r') 00185 options.session->reset(session_buffer_params(), options.session_params.samples); 00186 else if(key == 27) // escape 00187 options.session->progress.set_cancel("Cancelled"); 00188 } 00189 00190 static int files_parse(int argc, const char *argv[]) 00191 { 00192 if(argc > 0) 00193 options.filepath = argv[0]; 00194 00195 return 0; 00196 } 00197 00198 static void options_parse(int argc, const char **argv) 00199 { 00200 options.width= 0; 00201 options.height= 0; 00202 options.filepath = ""; 00203 options.session = NULL; 00204 options.quiet = false; 00205 00206 /* device names */ 00207 string device_names = ""; 00208 string devicename = "cpu"; 00209 bool list = false; 00210 00211 vector<DeviceType>& types = Device::available_types(); 00212 00213 foreach(DeviceType type, types) { 00214 if(device_names != "") 00215 device_names += ", "; 00216 00217 device_names += Device::string_from_type(type); 00218 } 00219 00220 /* shading system */ 00221 string ssname = "svm"; 00222 string shadingsystems = "Shading system to use: svm"; 00223 00224 #ifdef WITH_OSL 00225 shadingsystems += ", osl"; 00226 #endif 00227 00228 /* parse options */ 00229 ArgParse ap; 00230 bool help = false; 00231 00232 ap.options ("Usage: cycles_test [options] file.xml", 00233 "%*", files_parse, "", 00234 "--device %s", &devicename, ("Devices to use: " + device_names).c_str(), 00235 "--shadingsys %s", &ssname, "Shading system to use: svm, osl", 00236 "--background", &options.session_params.background, "Render in background, without user interface", 00237 "--quiet", &options.quiet, "In background mode, don't print progress messages", 00238 "--samples %d", &options.session_params.samples, "Number of samples to render", 00239 "--output %s", &options.session_params.output_path, "File path to write output image", 00240 "--threads %d", &options.session_params.threads, "CPU Rendering Threads", 00241 "--width %d", &options.width, "Window width in pixel", 00242 "--height %d", &options.height, "Window height in pixel", 00243 "--list-devices", &list, "List information about all available devices", 00244 "--help", &help, "Print help message", 00245 NULL); 00246 00247 if(ap.parse(argc, argv) < 0) { 00248 fprintf(stderr, "%s\n", ap.error_message().c_str()); 00249 ap.usage(); 00250 exit(EXIT_FAILURE); 00251 } 00252 else if(list) { 00253 vector<DeviceInfo>& devices = Device::available_devices(); 00254 printf("Devices:\n"); 00255 00256 foreach(DeviceInfo& info, devices) { 00257 printf(" %s%s\n", 00258 info.description.c_str(), 00259 (info.display_device)? " (display)": ""); 00260 } 00261 00262 exit(EXIT_SUCCESS); 00263 } 00264 else if(help || options.filepath == "") { 00265 ap.usage(); 00266 exit(EXIT_SUCCESS); 00267 } 00268 00269 if(ssname == "osl") 00270 options.scene_params.shadingsystem = SceneParams::OSL; 00271 else if(ssname == "svm") 00272 options.scene_params.shadingsystem = SceneParams::SVM; 00273 00274 /* find matching device */ 00275 DeviceType device_type = Device::type_from_string(devicename.c_str()); 00276 vector<DeviceInfo>& devices = Device::available_devices(); 00277 DeviceInfo device_info; 00278 bool device_available = false; 00279 00280 foreach(DeviceInfo& device, devices) { 00281 if(device_type == device.type) { 00282 options.session_params.device = device; 00283 device_available = true; 00284 break; 00285 } 00286 } 00287 00288 /* handle invalid configurations */ 00289 if(options.session_params.device.type == DEVICE_NONE || !device_available) { 00290 fprintf(stderr, "Unknown device: %s\n", devicename.c_str()); 00291 exit(EXIT_FAILURE); 00292 } 00293 #ifdef WITH_OSL 00294 else if(!(ssname == "osl" || ssname == "svm")) { 00295 #else 00296 else if(!(ssname == "svm")) { 00297 #endif 00298 fprintf(stderr, "Unknown shading system: %s\n", ssname.c_str()); 00299 exit(EXIT_FAILURE); 00300 } 00301 else if(options.scene_params.shadingsystem == SceneParams::OSL && options.session_params.device.type != DEVICE_CPU) { 00302 fprintf(stderr, "OSL shading system only works with CPU device\n"); 00303 exit(EXIT_FAILURE); 00304 } 00305 else if(options.session_params.samples < 0) { 00306 fprintf(stderr, "Invalid number of samples: %d\n", options.session_params.samples); 00307 exit(EXIT_FAILURE); 00308 } 00309 else if(options.filepath == "") { 00310 fprintf(stderr, "No file path specified\n"); 00311 exit(EXIT_FAILURE); 00312 } 00313 00314 /* load scene */ 00315 scene_init(options.width, options.height); 00316 } 00317 00318 CCL_NAMESPACE_END 00319 00320 using namespace ccl; 00321 00322 int main(int argc, const char **argv) 00323 { 00324 path_init("../build/bin/2.59/scripts/addons/cycles/"); 00325 00326 options_parse(argc, argv); 00327 00328 if(options.session_params.background) { 00329 session_init(); 00330 options.session->wait(); 00331 session_exit(); 00332 } 00333 else { 00334 string title = "Cycles: " + path_filename(options.filepath); 00335 00336 /* init/exit are callback so they run while GL is initialized */ 00337 view_main_loop(title.c_str(), options.width, options.height, 00338 session_init, session_exit, resize, display, keyboard); 00339 } 00340 00341 return 0; 00342 } 00343