//***************************************************************************************** // Truevision - a 3d modeler for gnome and povray // // povfe.cc // // Vincent LE PRINCE // Copyright (C) 2000-2005 Vincent LE PRINCE // This file is part of the TRUEVISION Package // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ //******************************************************************************************* #include #include #include #include #include #include #include "include/povfe.h" #include "include/dlgutils.h" #include "include/preferences.h" #include #include #include "config.h" #include "include/scene.h" #include "include/tvio.h" #if defined(__FreeBSD__) #define O_SYNC O_FSYNC #endif // Output file format definitions const int file_type_num = 4; const char *file_type_list[file_type_num] = { "PNG", "PPM", "TGA", "TGA+RLE" }; const char *file_type_output[file_type_num] = { "N", "P", "T", "C" }; const char *default_ofile = "Untitled"; // Default settings for rendering const int anti_met_num = 2; const char *anti_met_list[anti_met_num] = { N_("Adaptative"), N_("Recursive") }; const int image_max_size = 5000; // Image size presets const int size_presets_num = 7; const char *size_presets_names[ size_presets_num ] = { "None", "160x120", "320x240", "640x480", "800x600", "1024x768", "1280x1024" }; const int size_presets_width[ size_presets_num ] = { 0, 160, 320, 640, 800, 1024, 1280 }; const int size_presets_heigth[ size_presets_num ] = { 0, 120, 240, 480, 600, 768, 1024 }; const char *option_box_help_sections[] = { "sect-gui-rendopt1", "sect-gui-rendopt2", "sect-gui-rendopt3", "sect-gui-rendopt4", "sect-gui-rendopt5", "sect-gui-rendopt6", "sect-gui-rendopt7", "sect-gui-rendopt8" }; // Debug stream //ofstream debug( "debug.txt" ); //************************************************************** // Constructor //************************************************************** PovrayFE::PovrayFE( app_objs *appref ) { app_ref = appref; PREF_DEF start_button = NULL; progress_bar = NULL; pipe_console_name = NULL; options_box = NULL; render_box = NULL; fifo_console = NULL; cons_dlg = NULL; render_status = false; options_selected_page = 0; // Options for rendering process filename = new TvWidget_path( N_("Output file"), "OFILE", NULL, app_ref, default_ofile ); tv_widgets.push_back( filename ); fimage_type = new TvWidget_option_combo( N_("File format"), "FORMAT", NULL, app_ref ); fimage_type->set_list( file_type_list, file_type_num, 0 ); tv_widgets.push_back( fimage_type ); width = new TvWidget_int( N_("Width"), "W", NULL, app_ref, 640 ); width->set_range( image_max_size, 1, 1 ); tv_widgets.push_back( width ); height = new TvWidget_int( N_("Height"), "H", NULL, app_ref, 480 ); height->set_range( image_max_size, 1, 1 ); tv_widgets.push_back( height ); start_col = new TvWidget_int( N_("Starting column"), "SC", NULL, app_ref, 1 ); start_col->set_range( image_max_size, 1, 1 ); tv_widgets.push_back( start_col ); start_row = new TvWidget_int( N_("Starting row"), "SR", NULL, app_ref, 1 ); start_row->set_range( image_max_size, 1, 1 ); tv_widgets.push_back( start_row ); end_col = new TvWidget_int( N_("Ending column"), "EC", NULL, app_ref, image_max_size ); end_col->set_range( image_max_size, 1, 1 ); tv_widgets.push_back( end_col ); end_row = new TvWidget_int( N_("Ending row"), "ER", NULL, app_ref, image_max_size ); end_row->set_range( image_max_size, 1, 1 ); tv_widgets.push_back( end_row ); quality = new TvWidget_int( N_("Quality"), "QUA", NULL, app_ref, 9 ); quality->set_range( 11, 1, 1 ); tv_widgets.push_back( quality ); alpha = new TvWidget_bool( N_("Use alpha (png & tga only)"), "ALPHA", _("Set background as a transparent color"), app_ref, false ); tv_widgets.push_back( alpha ); bits_per_color = new TvWidget_int( N_("Bits per color (png only)"), "BPC", NULL, app_ref, 8 ); bits_per_color->set_range( 16, 5, 1 ); tv_widgets.push_back( bits_per_color ); radiosity = new TvWidget_bool( N_("Use radiosity (experimental)"), "RADIO", NULL, app_ref, false ); tv_widgets.push_back( radiosity ); set_spacing = new TvWidget_bool_activator( N_("Set spacing"), "SSPACE", NULL, app_ref, false ); tv_widgets.push_back( set_spacing ); spacing = new TvWidget_float( N_("Spacing"), "PSPACE", NULL, app_ref, 1 ); spacing->set_range( 100, 0, 0.1, 2 ); tv_widgets.push_back( spacing ); set_count = new TvWidget_bool_activator( N_("Set count"), "SCOUNT", NULL, app_ref, false ); tv_widgets.push_back( set_count ); photon_count = new TvWidget_int( N_("Count"), "PCOUNT", NULL, app_ref, 2000 ); photon_count->set_range( 100000, 0, 10 ); tv_widgets.push_back( photon_count ); use_media = new TvWidget_bool( N_("Use media photons"), "PMEDIA", NULL, app_ref, false ); tv_widgets.push_back( use_media ); max_steps = new TvWidget_int( N_("Max steps"), "PMTSEP", NULL, app_ref, 1 ); spacing->set_range( 100, 0.1, 1 ); tv_widgets.push_back( max_steps ); media_factor = new TvWidget_float( N_("Factor"), "PMFACT", NULL, app_ref, 1.0 ); media_factor->set_range( 100, 0, 0.1, 2 ); tv_widgets.push_back( media_factor ); gather_min = new TvWidget_int( N_("Gather minimum"), "GMAX", NULL, app_ref, 20 ); photon_count->set_range( 1000, 0, 1 ); tv_widgets.push_back( gather_min ); gather_max = new TvWidget_int( N_("Gather maximum"), "GMIN", NULL, app_ref, 100 ); gather_max->set_range( 1000, 0, 1 ); tv_widgets.push_back( gather_max ); set_gradius = new TvWidget_bool_activator( N_("Set gather radius for surfaces"), "SGRADIUS", NULL, app_ref, false ); tv_widgets.push_back( set_gradius ); gradius = new TvWidget_float( N_("Radius"), "GRADIUS", NULL, app_ref, 0 ); gradius->set_range( 100, 0, 0.1, 2 ); tv_widgets.push_back( gradius ); set_gradius_med = new TvWidget_bool_activator( N_("Set gather radius for medias"), "SGRADIUSM", NULL, app_ref, false ); tv_widgets.push_back( set_gradius_med ); gradius_med = new TvWidget_float( N_("Radius"), "GRADIUSM", NULL, app_ref, 0 ); gradius_med->set_range( 100, 0, 0.1, 2 ); tv_widgets.push_back( gradius_med ); gradius_mult = new TvWidget_float( N_("Surfaces radius multiplier"), "GRADMULT", NULL, app_ref, 1 ); gradius_mult->set_range( 1, 0, .1, 2 ); tv_widgets.push_back( gradius_mult ); gradius_med_mult = new TvWidget_float( N_("Medias radius multiplier"), "GRADMULTM", NULL, app_ref, 1 ); gradius_med_mult->set_range( 1, 0, .1, 2 ); tv_widgets.push_back( gradius_med_mult ); photon_jitter = new TvWidget_float( N_("Jitter"), "PJITTER", NULL, app_ref, 0.4 ); photon_jitter->set_range( 50, 0, 0.1, 2 ); tv_widgets.push_back( photon_jitter ); autostop = new TvWidget_float( N_("Auto stop"), "AUTOSTOP", NULL, app_ref, 1.0 ); autostop->set_range( 1, 0, 0.1, 2 ); tv_widgets.push_back( autostop ); photon_adc = new TvWidget_float( N_("ADC bailout"), "PADC", NULL, app_ref, 0.0039 ); photon_adc->set_range( 1, 0, 0.1, 4 ); tv_widgets.push_back( photon_adc ); photon_max_trace = new TvWidget_int( N_("Max trace level"), "PMAXT", NULL, app_ref, 5 ); photon_max_trace->set_range( 100, 1, 1 ); tv_widgets.push_back( photon_max_trace ); photon_thres_perc = new TvWidget_float( N_("Expand thresholds percentage"), "PTHRESP", NULL, app_ref, 0.2 ); photon_thres_perc->set_range( 1, 0, 0.01, 2 ); tv_widgets.push_back( photon_thres_perc ); photon_thres_min = new TvWidget_int( N_("Expand thresholds minimum"), "PTHRESM", NULL, app_ref, 40 ); photon_thres_min->set_range( 1000, 0, 1 ); tv_widgets.push_back( photon_thres_min ); antialias = new TvWidget_bool( N_("Antialiasing"), "ANTI", NULL, app_ref, true ); tv_widgets.push_back( antialias ); anti_met = new TvWidget_option_combo( N_("Method"), "AMET", NULL, app_ref ); anti_met->set_list( anti_met_list, anti_met_num, 0 ); tv_widgets.push_back( anti_met ); anti_depth = new TvWidget_int( N_("Depth (adaptative mode only)"), "ADEPTH", NULL, app_ref, 2 ); anti_depth->set_range( 10, 1, 1 ); tv_widgets.push_back( anti_depth ); threshold = new TvWidget_float( N_("Threshold"), "THRES", NULL, app_ref, 0.3 ); threshold->set_range( 1, 0, 0.1 ); tv_widgets.push_back( threshold ); jitter = new TvWidget_bool( N_("Use jitter"), "JITTER", NULL, app_ref, true ); tv_widgets.push_back( jitter ); jamount = new TvWidget_float( N_("Jitter amount"), "JAMOUNT", NULL, app_ref, 0.5 ); jamount->set_range( 1, 0, 0.1 ); tv_widgets.push_back( jamount ); display = new TvWidget_bool( N_("Display"), "DISP", _("Display computed image during calculation"), app_ref, true ); tv_widgets.push_back( display ); iconified = new TvWidget_bool( N_("Start iconified"), "ICO", NULL, app_ref, false ); tv_widgets.push_back( iconified ); greyscale = new TvWidget_bool( N_("Display as greyscale"), "GREY", NULL, app_ref, false ); tv_widgets.push_back( greyscale ); owncmap = new TvWidget_bool( N_("Use own color map"), "CMAP", NULL, app_ref, false ); tv_widgets.push_back( owncmap ); bounding_thres = new TvWidget_int( N_("Bounding box threshold"), "BBT", NULL, app_ref, 25 ); bounding_thres->set_range( 50, 1, 1 ); tv_widgets.push_back( bounding_thres ); light_buff = new TvWidget_bool( N_("Disable light buffer"), "LIBU", NULL, app_ref, false ); tv_widgets.push_back( light_buff ); vista = new TvWidget_bool( N_("Disable vista buffer"), "VIBU", NULL, app_ref, false ); tv_widgets.push_back( vista ); draw_vista = new TvWidget_bool( N_("Draw vista"), "ICO", NULL, app_ref, false ); tv_widgets.push_back( draw_vista ); adc_bailout = new TvWidget_float( N_("Adc bailout"), "ADCBO", NULL, app_ref, 0.0039 ); adc_bailout->set_range( 1, 0, 0.1, 4 ); tv_widgets.push_back( adc_bailout ); ambient_light = new TvWidget_color( N_("Ambient Light"), "ALIGHT", NULL, app_ref ); ambient_light->set( 1, 1, 1 ); tv_widgets.push_back( ambient_light ); noisegen = new TvWidget_noise_generator( N_("Global noise generator"), "NOISEGEN", NULL, app_ref ); tv_widgets.push_back( noisegen ); hf_gray_16 = new TvWidget_bool( N_("heightfield output"), "HF", NULL, app_ref, false ); tv_widgets.push_back( hf_gray_16 ); irid_wavelength = new TvWidget_color( N_("Irid wavelength"), "IVL", NULL, app_ref ); irid_wavelength->set( 0.25, 0.18, 0.14 ); tv_widgets.push_back( irid_wavelength ); max_trace_level = new TvWidget_int( N_("Max trace level"), "MTL", NULL, app_ref, 5 ); max_trace_level->set_range( 100, 1, 1 ); tv_widgets.push_back( max_trace_level ); max_intersections = new TvWidget_int( N_("Max intersections"), "MITS", NULL, app_ref, 64 ); max_intersections->set_range( 1024, 32, 16 ); tv_widgets.push_back( max_intersections ); number_of_waves = new TvWidget_int( N_("Number of waves"), "NOW", NULL, app_ref, 10 ); number_of_waves->set_range( 100, 0, 1 ); tv_widgets.push_back( number_of_waves ); // Radiosity brightness = new TvWidget_float( N_("Brightness"), "RBRI", NULL, app_ref, 1.0 ); brightness->set_range( 100, 0, 0.11, 3 ); tv_widgets.push_back( brightness ); count = new TvWidget_int( N_("Count"), "COUNT", NULL, app_ref, 35 ); count->set_range( 1000, 1, 10 ); tv_widgets.push_back( count ); error_bound = new TvWidget_float( N_("Error bound"), "EBOUND", NULL, app_ref, 1.8 ); error_bound->set_range( 1, 0, 0.01, 4 ); tv_widgets.push_back( error_bound ); gray_threshold = new TvWidget_float( N_("Gray threshold"), "GRAYT", NULL, app_ref, 0 ); gray_threshold->set_range( 1, 0, 0.01, 4 ); tv_widgets.push_back( gray_threshold ); low_error_factor = new TvWidget_float( N_("Low error factor"), "LEF", NULL, app_ref, 0.5 ); low_error_factor->set_range( 1, 0, 0.01, 4 ); tv_widgets.push_back( low_error_factor ); minimum_reuse = new TvWidget_float( N_("Minimum reuse"), "MINIR", NULL, app_ref, 0.015 ); minimum_reuse->set_range( 1, 0, 0.1, 4 ); tv_widgets.push_back( minimum_reuse ); nearest_count = new TvWidget_int( N_("Nearest count"), "NCOUNT", NULL, app_ref, 5 ); nearest_count->set_range( 10, 0, 1 ); tv_widgets.push_back( nearest_count ); recursion_limit = new TvWidget_int( N_("Recursion limit"), "RECLIM", NULL, app_ref, 3 ); recursion_limit->set_range( 20, 1, 1 ); tv_widgets.push_back( recursion_limit ); rad_adc_bailout = new TvWidget_float( N_("ADC Bailout"), "RADADC", NULL, app_ref, 0.01 ); rad_adc_bailout->set_range( 1, 0, 0.1, 4 ); tv_widgets.push_back( rad_adc_bailout ); always_sample = new TvWidget_bool( N_("Always sample"), "ALWSAMP", NULL, app_ref, true ); tv_widgets.push_back( always_sample ); max_sample = new TvWidget_float( N_("Max sample"), "MAXSAMP", NULL, app_ref, -1 ); max_sample->set_range( 100, -1, 0.1, 4 ); tv_widgets.push_back( max_sample ); rad_media = new TvWidget_bool( N_("Affected by media"), "RADMED", NULL, app_ref, false ); tv_widgets.push_back( rad_media ); rad_normal = new TvWidget_bool( N_("Affected by normal"), "RADNORM", NULL, app_ref, false ); tv_widgets.push_back( rad_normal ); pretrace_start = new TvWidget_float( N_("Pretrace start"), "PRETST", NULL, app_ref, 0.08 ); pretrace_start->set_range( 1, 0, 0.01, 4 ); pretrace_end = new TvWidget_float( N_("Pretrace end"), "PRETED", NULL, app_ref, 0.04 ); pretrace_end->set_range( 1, 0, 0.01, 4 ); // Scene description author = new TvWidget_entry( N_("Author"), "AUTH", NULL, app_ref ); author->set( pref->author->value() ); tv_widgets.push_back( author ); description = new TvWidget_text( N_("Description"), "DESC", NULL, app_ref ); tv_widgets.push_back( description ); } //***************************************************** // Destructor //***************************************************** PovrayFE::~PovrayFE() { if ( fifo_console != NULL ) { pclose( fifo_console ); fifo_console = NULL; } for ( register unsigned int i = 0 ; i < tv_widgets.size() ; i++ ) delete tv_widgets[i]; } //******************************************************** // Progress bar //******************************************************** void PovrayFE::get_progress_bar( GtkWidget *box, bool tt ) { progress_bar = gtk_progress_bar_new(); gtk_box_pack_start( GTK_BOX(box), progress_bar, FALSE, FALSE, 5 ); gtk_progress_bar_update( GTK_PROGRESS_BAR(progress_bar), 0 ); gtk_progress_set_show_text( GTK_PROGRESS(progress_bar), TRUE ); gtk_progress_set_text_alignment( GTK_PROGRESS(progress_bar), 0.5, 0.3 ); } //******************************************************** // Get Pipe line // // Read a line from a pipe // sleep when nothing available //******************************************************** bool PovrayFE::get_pipe_line( int file, char *buffer, int size ) { //debug << "\nStart reading from pipe !"; debug.flush(); char ch; int i = 0; while ( i < size ) { int res = read( file, &ch, 1 ); if ( res == 0 ) continue; if ( res == -1 && errno == EAGAIN ) { sleep(1); continue; } if ( res == -1 ) return false; if ( ch == '\n' || ch == '\r' ) break; buffer[i++] = ch; } buffer[i] = '\0'; //debug << "\nRead one line from pipe !"; debug.flush(); return true; } //***************************************************** // Reset defaults // // used at new scene creation //***************************************************** void PovrayFE::reset_defaults() { options_selected_page = 0; filename->set( (char*)default_ofile ); fimage_type->set( 0 ); width->set( 640 ); height->set( 480 ); start_col->set( 1 ); start_row->set( 1 ); end_col->set( image_max_size ); end_row->set( image_max_size ); quality->set( 9 ); alpha->set( false ); bits_per_color->set( 8 ); radiosity->set( false ); antialias->set( true ); anti_met->set( 0 ); anti_depth->set( 2 ); threshold->set( 0.3 ); jitter->set( true ); jamount->set(0.5); set_spacing->set( false ); spacing->set( 1 ); display->set( true ); iconified->set( false ); greyscale->set( false ); owncmap->set( false ); bounding_thres->set( 25 ); light_buff->set( false ); vista->set( false ); draw_vista->set( false ); adc_bailout->set( 0.0039 ); ambient_light->set( 1, 1, 1 ); noisegen->set( 1 ); hf_gray_16->set( false ); irid_wavelength->set( 0.25, 0.18, 0.14 ); max_trace_level->set( 5 ); max_intersections->set( 64 ); number_of_waves->set(10); brightness->set( 1 ); count->set( 35 ); error_bound->set( 1.8 ); gray_threshold->set( 0 ); low_error_factor->set( 0.5 ); minimum_reuse->set( 0.015 ); nearest_count->set( 5 ); recursion_limit->set( 3 ); rad_adc_bailout->set( 0.01 ); always_sample->set( true ); max_sample->set( -1 ); rad_media->set( false ); rad_normal->set( false ); pretrace_start->set( 0.08 ); pretrace_end->set( 0.04 ); // Scene description description->clear(); PREF_DEF author->set( pref->author->value() ); } //************************************************* // Flush // // Flush widgets at option box close //************************************************* void PovrayFE::flush() { for ( register unsigned int i = 0 ; i < tv_widgets.size() ; i++ ) tv_widgets[i]->flush(); } //************************************************* // Pref changed // // Preferences change notification //************************************************* void PovrayFE::pref_changed() { for ( register unsigned int i = 0 ; i < tv_widgets.size() ; i++ ) tv_widgets[i]->pref_changed(); } //******************************************************** // Options box // // Raise the option box //******************************************************** void PovrayFE::raise_options_box() { if ( GTK_IS_DIALOG(options_box) ) { gdk_window_raise( options_box->window ); return; } opt_applied = false; PREF_DEF bool tt = pref->tooltips->value(); for ( register unsigned int i = 0 ; i < tv_widgets.size() ; i++ ) tv_widgets[i]->store(); options_box = gtk_dialog_new_with_buttons( _("Povray options"), NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_OK, GTK_RESPONSE_OK, GTK_STOCK_APPLY, GTK_RESPONSE_APPLY, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_HELP, GTK_RESPONSE_HELP,NULL ); g_signal_connect( G_OBJECT(options_box), "response", G_CALLBACK(sign_povfe_opt_click), this ); g_signal_connect( G_OBJECT(options_box), "close", G_CALLBACK(sign_povfe_opt_destroy), this ); if ( pref->save_dlg_geo->value() ) { if ( pref->ropt_xpos->value() < 0 ) pref->ropt_xpos->set(0); if ( pref->ropt_ypos->value() < 0 ) pref->ropt_ypos->set(0); gtk_widget_set_uposition( options_box, pref->ropt_xpos->value(), pref->ropt_ypos->value() ); gtk_window_set_default_size( GTK_WINDOW(options_box), pref->ropt_xsize->value(), pref->ropt_ysize->value() ); } // Container options_notebk = gtk_notebook_new(); gtk_notebook_set_scrollable( GTK_NOTEBOOK(options_notebk), TRUE ); gtk_box_pack_start( GTK_BOX(GTK_DIALOG(options_box)->vbox), options_notebk, FALSE, TRUE, 5 ); GtkWidget *box1, *box2, *vbox, *hbox; // PAGE Quality vbox = dlg_new_page( options_notebk, N_("Quality") ); hbox = dlg_simple_box_frame( _("General"), vbox ); dlg_double_box( hbox, box1, box2 ); quality->get_widget( box1, tt ); bits_per_color->get_widget( box1, tt ); alpha->get_widget( box2, tt ); // Frame antialiasing dlg_double_box_frame( _("Antialiasing"), vbox, box1, box2 ); antialias->get_widget( box1, tt ); anti_met->get_widget( box1, tt ); anti_depth->get_widget( box1, tt ); jitter->get_widget( box1, tt ); jamount->get_widget( box2, tt ); threshold->get_widget( box2, tt ); // PAGE Global settings vbox = dlg_new_page( options_notebk, _("Scene settings") ); hbox = dlg_simple_box_frame( _("General"), vbox ); ambient_light->get_widget( hbox, tt ); number_of_waves->get_widget( hbox, tt ); irid_wavelength->get_widget( hbox, tt ); noisegen->get_widget( hbox, tt ); // PAGE Radiosity vbox = dlg_new_page( options_notebk, _("Radiosity") ); hbox = dlg_simple_box_frame( _("General"), vbox ); radiosity->get_widget( hbox, tt ); dlg_double_box( hbox, box1, box2 ); brightness->get_widget( box1, tt ); gray_threshold->get_widget( box1, tt ); count->get_widget( box1, tt ); nearest_count->get_widget( box1, tt ); rad_adc_bailout->get_widget( box1, tt ); always_sample->get_widget( box2, tt ); max_sample->get_widget( box2, tt ); rad_media->get_widget( box1, tt ); rad_normal->get_widget( box1, tt ); minimum_reuse->get_widget( box2, tt ); //distance_maximum->get_widget( box2, tt ); error_bound->get_widget( box2, tt ); low_error_factor->get_widget( box2, tt ); pretrace_start->get_widget( box2, tt ); pretrace_end->get_widget( box2, tt ); // PAGE Photons vbox = dlg_new_page( options_notebk, _("Photons") ); hbox = dlg_simple_box_frame( _("Number of photons"), vbox ); dlg_double_box( hbox, box1, box2 ); GtkWidget *abox = gtk_hbox_new( TRUE, TRUE ); gtk_box_pack_start( GTK_BOX(box2), abox, TRUE, TRUE, 0 ); set_spacing->get_widget( box1, tt ); spacing->get_widget( abox, tt ); set_spacing->set_target( abox ); set_spacing->update_widget(); abox = gtk_hbox_new( TRUE, TRUE ); gtk_box_pack_start( GTK_BOX(box2), abox, TRUE, TRUE, 0 ); set_count->get_widget( box1, tt ); photon_count->get_widget( abox, tt ); set_count->set_target( abox ); set_count->update_widget(); gather_min->get_widget( box1, tt ); gather_max->get_widget( box2, tt ); hbox = dlg_simple_box_frame( _("Media interaction"), vbox ); dlg_double_box( hbox, box1, box2 ); use_media->get_widget( box1, tt ); max_steps->get_widget( box2, tt ); media_factor->get_widget( box2, tt ); hbox = dlg_simple_box_frame( _("Gather radius"), vbox ); dlg_double_box( hbox, box1, box2 ); abox = gtk_hbox_new( TRUE, TRUE ); gtk_box_pack_start( GTK_BOX(box2), abox, TRUE, TRUE, 0 ); set_gradius->get_widget( box1, tt ); gradius->get_widget( abox, tt ); set_gradius->set_target( abox ); set_gradius->update_widget(); gradius_mult->get_widget( box2, tt ); abox = gtk_hbox_new( TRUE, TRUE ); gtk_box_pack_start( GTK_BOX(box2), abox, TRUE, TRUE, 0 ); set_gradius_med->get_widget( box1, tt ); gradius_med->get_widget( abox, tt ); set_gradius_med->set_target( abox ); set_gradius_med->update_widget(); gradius_med_mult->get_widget( box2, tt ); hbox = dlg_simple_box_frame( _("Tracing options"), vbox ); dlg_double_box( hbox, box1, box2 ); photon_jitter->get_widget( box1, tt ); autostop->get_widget( box1, tt ); photon_adc->get_widget( box2, tt ); photon_max_trace->get_widget( box2, tt ); photon_thres_perc->get_widget( box1, tt ); photon_thres_min->get_widget( box2, tt ); // PAGE Performances vbox = dlg_new_page( options_notebk, _("Performances") ); hbox = dlg_simple_box_frame( _("General"), vbox ); dlg_double_box( hbox, box1, box2 ); bounding_thres->get_widget( box1, tt ); light_buff->get_widget( box1, tt ); vista->get_widget( box2, tt ); draw_vista->get_widget( box2, tt ); // Frame Limits hbox = dlg_simple_box_frame( _("Limits"), vbox ); dlg_double_box( hbox, box1, box2 ); adc_bailout->get_widget( box1, tt ); max_trace_level->get_widget( box1, tt ); max_intersections->get_widget( box2, tt ); // PAGE Display vbox = dlg_new_page( options_notebk, _("Display") ); hbox = dlg_simple_box_frame( _("General"), vbox ); display->get_widget( hbox, tt ); //mosaic->get_widget( hbox, tt ); iconified->get_widget( hbox, tt ); owncmap->get_widget( hbox, tt ); greyscale->get_widget( hbox, tt ); // PAGE OUTPUT vbox = dlg_new_page( options_notebk, _("Output") ); // Frame File hbox = dlg_simple_box_frame( _("File options"), vbox ); filename->get_widget( hbox, tt ); fimage_type->get_widget( hbox, tt ); hf_gray_16->get_widget( hbox, tt ); // Frame Size hbox = dlg_simple_box_frame( _("Size"), vbox ); dlg_double_box( hbox, box1, box2 ); width->get_widget( box1, tt ); height->get_widget( box2, tt ); presets = new TvWidget_option_combo( N_("Size presets"), NULL, NULL, app_ref ); presets->set_list( size_presets_names, size_presets_num, 0 ); for ( int i = 0 ; i < size_presets_num ; i++ ) if ( size_presets_width[i] == width->value() && size_presets_heigth[i] == height->value() ) { presets->set(i); break; } presets->get_widget( box1, tt ); presets->connect_signal( GTK_SIGNAL_FUNC(sign_povfe_presets), this ); // Frame partial hbox = dlg_simple_box_frame( _("Partial render"), vbox ); dlg_double_box( hbox, box1, box2 ); start_col->get_widget( box1, tt ); start_row->get_widget( box2, tt ); end_col->get_widget( box1, tt ); end_row->get_widget( box2, tt ); // PAGE MISC vbox = dlg_new_page( options_notebk, _("About scene") ); // Frame partial hbox = dlg_simple_box_frame( _("Description"), vbox ); author->get_widget( hbox, tt ); description->get_widget( hbox, tt ); gtk_widget_show_all(options_box); gtk_notebook_set_page( GTK_NOTEBOOK(options_notebk), options_selected_page ); } //******************************************************** // Options box // // Callbacks //******************************************************** void PovrayFE::opt_box_clicked( int button ) { switch( button ) { case GTK_RESPONSE_OK: flush(); close_opt_box(); break; case GTK_RESPONSE_APPLY: flush(); opt_applied = true; break; case GTK_RESPONSE_HELP: { int sel = gtk_notebook_get_current_page( GTK_NOTEBOOK(options_notebk) ) ; truevision_help_display( "truevision.xml", (char*)option_box_help_sections[sel], NULL ); } break; default: case GTK_RESPONSE_CANCEL: if ( opt_applied ) unapply_opt_box(); close_opt_box(); break; } } //******************************************************** // Close options box //******************************************************** void PovrayFE::close_opt_box() { options_selected_page = gtk_notebook_get_current_page( GTK_NOTEBOOK(options_notebk) ); PREF_DEF if ( pref->save_dlg_geo->value() ) { gint x,y; gdk_window_get_root_origin( options_box->window, &x, &y ); pref->ropt_xpos->set( x ); pref->ropt_ypos->set( y ); pref->ropt_xsize->set( options_box->allocation.width ); pref->ropt_ysize->set( options_box->allocation.height ); } if ( options_box != NULL ) gtk_widget_destroy( options_box ); options_box = NULL; for ( register unsigned int i = 0 ; i < tv_widgets.size() ; i++ ) tv_widgets[i]->clear_widget(); delete presets; } //******************************************************** // Unapply options box //******************************************************** void PovrayFE::unapply_opt_box() { for ( register unsigned int i = 0 ; i < tv_widgets.size() ; i++ ) tv_widgets[i]->restore(); } //******************************************************** // Update width / height from size presets //******************************************************** void PovrayFE::size_preset_choice() { if ( presets == NULL ) return; presets->flush(); int val = presets->value(); if ( val < 1 ) return; width->set( size_presets_width[ val ] ); width->update_widget(); height->set( size_presets_heigth[ val ] ); height->update_widget(); } //**************************************************************************** // Render box // // Raise render box //**************************************************************************** void PovrayFE::raise_render_box() { if ( GTK_IS_WIDGET(render_box) ) { gdk_window_raise( render_box->window ); return; } PREF_DEF bool tt = pref->tooltips->value(); render_box = gtk_window_new( GTK_WINDOW_TOPLEVEL ); gtk_window_set_decorated( GTK_WINDOW(render_box), TRUE ); gtk_window_set_title( GTK_WINDOW(render_box), _("Render") ); gtk_window_set_policy( GTK_WINDOW(render_box), FALSE, FALSE, TRUE ); gtk_signal_connect( GTK_OBJECT(render_box), "delete_event", GTK_SIGNAL_FUNC(sign_povfe_rend_destroy), this ); if ( pref->save_dlg_geo->value() ) { if ( pref->rdlg_xpos->value() < 0 ) pref->rdlg_xpos->set(0); if ( pref->rdlg_ypos->value() < 0 ) pref->rdlg_ypos->set(0); gtk_widget_set_uposition( render_box, pref->rdlg_xpos->value(), pref->rdlg_ypos->value() ); } GtkWidget *vbox = gtk_vbox_new( FALSE, 0 ); gtk_container_set_border_width( GTK_CONTAINER(vbox), 7 ); gtk_container_add( GTK_CONTAINER(render_box), vbox ); GtkWidget *lab = gtk_label_new( _("Persistence of Vision Front-end") ); gtk_box_pack_start( GTK_BOX(vbox), lab, TRUE, TRUE, 0 ); get_progress_bar( vbox, tt ); status = gtk_label_new( _("Click 'start' to render the scene") ); gtk_box_pack_start( GTK_BOX(vbox), status, TRUE, TRUE, 0 ); GtkWidget *hbox = gtk_hbox_new( FALSE, 5 ); gtk_box_pack_start( GTK_BOX(vbox), hbox, FALSE, TRUE, 4 ); time_lab = gtk_label_new( _("Elapsed time : ") ); gtk_box_pack_start( GTK_BOX(hbox), time_lab, FALSE, TRUE, 20 ); time_lab = gtk_label_new( "--:--:--" ); gtk_box_pack_start( GTK_BOX(hbox), time_lab, FALSE, TRUE, 0 ); GtkWidget *label = gtk_label_new( N_("When render is over, click on image") ); gtk_box_pack_start( GTK_BOX(vbox), label, FALSE, TRUE, 0 ); GtkWidget *sep = gtk_hseparator_new(); gtk_box_pack_start( GTK_BOX(vbox), sep, TRUE, TRUE, 8 ); GtkWidget *button_box = gtk_hbutton_box_new(); gtk_button_box_set_layout( GTK_BUTTON_BOX(button_box), GTK_BUTTONBOX_SPREAD ); gtk_button_box_set_spacing( GTK_BUTTON_BOX(button_box), 10 ); gtk_box_pack_start( GTK_BOX(vbox), button_box, FALSE, FALSE, 0 ); start_label = gtk_label_new( _("Start") ); start_button = gtk_button_new(); gtk_signal_connect( GTK_OBJECT(start_button), "clicked", GTK_SIGNAL_FUNC(sign_povfe_start_stop_clicked), this ); gtk_container_add( GTK_CONTAINER(start_button), start_label ); gtk_container_add( GTK_CONTAINER(button_box), start_button ); GtkWidget *button = gtk_button_new_with_label( _("Console") ); gtk_container_add( GTK_CONTAINER(button_box), button ); gtk_signal_connect( GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(sign_povfe_console), this ); button = gtk_button_new_with_label( _("Options") ); gtk_container_add( GTK_CONTAINER(button_box), button ); gtk_signal_connect( GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(sign_options_box), this ); button = gtk_button_new_with_label( _("Close") ); gtk_container_add( GTK_CONTAINER(button_box), button ); gtk_signal_connect( GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(sign_povfe_rend_close), this ); // Console text cons_box = gtk_hbox_new( TRUE, 5 ); cons_text = gtk_text_view_new( ); gtk_container_add( GTK_CONTAINER(cons_box), cons_text ); gtk_widget_show_all( render_box ); } //*************************************************** // Close render box //*************************************************** void PovrayFE::close_render_box() { PREF_DEF if ( pref->save_dlg_geo->value() ) { gint x,y; gdk_window_get_root_origin( render_box->window, &x, &y ); pref->rdlg_xpos->set( x ); pref->rdlg_ypos->set( y ); } stop_rendering_scene( false ); if ( render_box != NULL ) gtk_widget_destroy( render_box ); render_box = NULL; close_console_dlg(); gtk_widget_destroy(cons_box); } //********************************************************* // Start stop // // Start button callback //********************************************************* void PovrayFE::start_stop_clicked() { if ( render_status == false ) // Start start_render(); else // Stop stop_render( ); } //********************************************************* // Start render // // start rendering image // called from button, menu or shortcut //********************************************************* void PovrayFE::start_render() { gtk_label_set_text( GTK_LABEL(status), _("Initialiasing render...") ); gtk_label_set_text( GTK_LABEL(start_label), _("Stop") ); gtk_action_set_sensitive( start_render_action, FALSE ); gtk_action_set_sensitive( stop_render_action, TRUE ); start_rendering_scene(); } //********************************************************* // Stop render // // stop rendering image // called from button, menu or shortcut //********************************************************* void PovrayFE::stop_render() { stop_rendering_scene(false); } //********************************************************* // Start rendering scene // // create a temp pov file & invoke povray //********************************************************* bool PovrayFE::start_rendering_scene() { // Scene SCENE_DEF scene_file = scene->get_temp_povray_file(); render_status = true; // Clear the console GtkTextBuffer *buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(cons_text) ); GtkTextIter start, end; gtk_text_buffer_get_bounds( buffer, &start, &end ); gtk_text_buffer_delete( buffer, &start, &end ); // Check if destination directory exists && output file != NULL bool nodir = false; if ( filename->value() == NULL ) filename->set( (char*)default_ofile ); int len = strlen( filename->value() ); char *path = new char[ len + 1 ]; strcpy( path, filename->value() ); for ( ; path[len] != '/' && len != 0 ; len-- ) {} path[len] = '\0'; if ( access( path, F_OK ) == -1 && len != 0 ) { app_warning( _("Can't write output file to directory"), path ); nodir = true; } // Create pipes int res; pipe_console_name = get_temp_filename(); res = mkfifo( pipe_console_name, S_IRUSR | S_IWUSR ); if ( res != 0 ) { app_warning( _("Can't create output pipe"), path ); return false; } // Create arguments for launching povray PREF_DEF char *args[256]; int arg_num = 0; // Set rendere command to use, from preferences args[arg_num++] = pref->povcmd->value(); // pause when render finished char arg_p[] ="+P"; args[arg_num++] = arg_p; // verbose mode on char arg_v[] = "+V"; args[arg_num++] = arg_v; // Redirect all streams to console pipe char arg_ga[ strlen(pipe_console_name) + 5 ]; sprintf( arg_ga, "+GA%s", pipe_console_name ); args[arg_num++] = arg_ga; // Set povray window title - WARNING X-Window version specific argument char arg_title[] = "-title \"Persistence of vision\""; args[arg_num++] = arg_title; //args[arg_num++] = nodir ? (char*)default_ofile : filename->value(); // Set the scene file char arg_i[ strlen(scene_file) + 5 ]; sprintf( arg_i, "+I%s", scene_file ); args[arg_num++] = arg_i; // Set output file name char *output = nodir ? (char*)default_ofile : filename->value(); char arg_o[ strlen(output) + 5 ]; sprintf( arg_o, "+O%s", output ); args[arg_num++] = arg_o; // Set image height char arg_h[10] ; sprintf( arg_h, "+H%u", height->value() ); args[arg_num++] = arg_h; // Set image width char arg_w[10] ; sprintf( arg_w, "+W%u", width->value() ); args[arg_num++] = arg_w; // Set render quality level char arg_q[10] ; sprintf( arg_q, "+Q%u", quality->value() ); args[arg_num++] = arg_q; // Set image output format char arg_f[4] ; if ( fimage_type->value() == 0 ) { // if we use the png file format, set bit per color option sprintf( arg_f, "+F%s%u", file_type_output[fimage_type->value()], bits_per_color->value() ); args[arg_num++] = arg_f; } else { sprintf( arg_f, "+F%s", file_type_output[fimage_type->value()] ); args[arg_num++] = arg_f; } // Set the starting column char arg_sc[10] ; sprintf( arg_sc, "+SC%u", start_col->value() ); args[arg_num++] = arg_sc; // Set the starting row char arg_sr[10] ; sprintf( arg_sr, "+SR%u", start_row->value() ); args[arg_num++] = arg_sr; // Set the ending col char arg_ec[10] ; sprintf( arg_ec, "+EC%u", end_col->value() ); args[arg_num++] = arg_ec; // Set the ending row char arg_er[10] ; sprintf( arg_er, "+ER%u", end_row->value() ); args[arg_num++] = arg_er; // Shall we use X-window display if ( display->value() ) { if ( ! greyscale->value() ) { char arg_d[] = "+D"; args[arg_num++] = arg_d; } else { char arg_d[] = "+D0G"; args[arg_num++] = arg_d; } } // Shall we start with an iconified display if ( iconified->value() ) { char arg_icon[] = "-iconic"; args[arg_num++] = arg_icon; } // Shall we use our own color map if ( owncmap->value() ) { char arg_cmap[] = "-owncmap"; args[arg_num++] = arg_cmap; } // Set radiosity if ( radiosity->value() ) { char arg_qr[] = "+QR" ; args[arg_num++] = arg_qr; } // Set alpha channel on / off if ( radiosity->value() ) { char arg_ua[] = "+UA" ; args[arg_num++] = arg_ua; } // set antialiasing & parameters if ( antialias->value() ) { // antialiasing & threshold char arg_a[5]; sprintf( arg_a, "+A%1.1f", threshold->value() ); args[arg_num++] = arg_a; // antialiasing method char arg_am[5]; sprintf( arg_am, "+AM%u", anti_met->value()+1 ); args[arg_num++] = arg_am; // antialiasing depth ( recursive mode ) char arg_r[5]; sprintf( arg_r, "+R%u", anti_depth->value() ); args[arg_num++] = arg_r; // Jitter if ( jitter->value() ) { char arg_j[5]; sprintf( arg_j, "+J%1.1f", jamount->value() ); args[arg_num++] = arg_j; } } // Set bounding box threshold if ( bounding_thres->value() != 25 ) { char arg_mb[10]; sprintf( arg_mb, "+MB%u", bounding_thres->value() ); args[arg_num++] = arg_mb; } // Set light buffers on if ( light_buff->value() ) { char arg_ul[] = "+UL"; args[arg_num++] = arg_ul; } // Set light vistas on if ( vista->value() ) { char arg_uv[] = "+UV"; args[arg_num++] = arg_uv; } // Set light vistas display on if ( vista->value() ) { char arg_ud[] = "+UD"; args[arg_num++] = arg_ud; } args[ arg_num++ ] = NULL; // Debug command arguments /*cout << "\ninvoking povray with command : \n\t"; for ( int i = 0 ; i < arg_num-1 ; i++ ) { cout << args[i] << " "; } cout.flush();*/ // Fork and launch povray povray_pid = fork(); if ( povray_pid == -1 ) return false; if ( povray_pid == 0 ) { if ( execve( *args, args, app_ref->envp ) == -1 ) { exit(-1); unlink( pipe_console_name ); } exit(-1); } // Thread de lecture de la console pthread_attr_t thread_attr2; pthread_attr_init( &thread_attr2 ); //pthread_attr_setdetachstate( &thread_attr2, PTHREAD_CREATE_JOINABLE ); pthread_attr_setdetachstate( &thread_attr2, PTHREAD_CREATE_DETACHED ); if( pthread_create( &console_thread, &thread_attr2, read_console_thread, this ) ) { app_warning( _("Cannot create status reading thread !") ); stop_rendering_scene( false ); return false; } return true; } //****************************************************************** // Stop rendering scene // // Kill povray and delete temp file //****************************************************************** void PovrayFE::stop_rendering_scene( bool from_thread ) { if ( render_status == false ) return; kill( povray_pid, 6 ); close( pipe_console_id ); if ( ! from_thread ) pthread_cancel( console_thread ); unlink( scene_file ); unlink( pipe_console_name ); delete pipe_console_name; delete scene_file; waitpid( povray_pid, NULL, 0 ); if ( from_thread ) gdk_threads_enter(); gtk_label_set_text( GTK_LABEL(start_label), _("Start") ); gtk_progress_bar_update( GTK_PROGRESS_BAR(progress_bar), 0 ); gtk_label_set_text( GTK_LABEL(status), _("Done.") ); gtk_label_set_text( GTK_LABEL(time_lab), "--:--:--" ); gdk_flush(); if ( from_thread ) gdk_threads_leave(); render_status = false; //gtk_widget_set_sensitive( start_render_menu_item, TRUE ); //gtk_widget_set_sensitive( stop_render_menu_item, FALSE ); gtk_action_set_sensitive( start_render_action, TRUE ); gtk_action_set_sensitive( stop_render_action, FALSE ); } //****************************************************************** // Read console pipe // // read povray output from pipe //****************************************************************** void PovrayFE::read_console_pipe() { pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, NULL ); //pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS, NULL ); pipe_console_id = open( pipe_console_name, O_RDONLY | O_SYNC | O_NDELAY ); //pipe_console_id = open( pipe_console_name, O_RDONLY ); if ( pipe_console_id== -1 ) { app_warning( _("Cannot read povray output !") ); stop_rendering_scene( false ); return; } // DEBUG Ouverture du fichier //ofstream filez( "pov.log", ios::out ); //filez.setf( ios::fixed, ios::floatfield ); char console_line[255]; bool finished = false; bool print; int image_line = 0; char time[20]; int hauteur = height->value(); int line_num = 0; bool parsing_done = false; bool photons_done= false; bool rendering = false; bool bslabs_done = false; // Parsing povray output while ( finished == false ) { pthread_testcancel(); bool res = get_pipe_line( pipe_console_id, console_line, 254 ); if ( res == false ) finished = true; strcat( console_line, "\n" ); //filez << console_line; filez.flush(); print = true; line_num++; if ( strstr( console_line, "Done" ) != NULL ) { finished = true; gdk_threads_enter(); gtk_progress_bar_update( GTK_PROGRESS_BAR(progress_bar), 1 ); gtk_label_set_text( GTK_LABEL(status), _("Click on image to close it...") ); while ( gtk_events_pending() ) gtk_main_iteration(); gdk_flush(); gdk_threads_leave(); } if ( !parsing_done && strstr( console_line, "Parsing" ) != NULL ) { parsing_done = true; gdk_threads_enter(); gtk_label_set_text( GTK_LABEL(status), _("Parsing...") ); while ( gtk_events_pending() ) gtk_main_iteration(); gdk_flush(); gdk_threads_leave(); } if ( !bslabs_done && strstr( console_line, "Creating bounding slabs" ) != NULL ) { bslabs_done = true; gdk_threads_enter(); gtk_label_set_text( GTK_LABEL(status), _("Creating bounding slabs...") ); while ( gtk_events_pending() ) gtk_main_iteration(); gdk_flush(); gdk_threads_leave(); } if ( !photons_done && strstr( console_line, "Building Photon Maps" ) != NULL ) { photons_done = true; gdk_threads_enter(); gtk_label_set_text( GTK_LABEL(status), _("Building photon maps...") ); while ( gtk_events_pending() ) gtk_main_iteration(); gdk_flush(); gdk_threads_leave(); } if ( !rendering && ( strstr( console_line, "Rendering line" ) != NULL ) ) { rendering = true; gdk_threads_enter(); gtk_label_set_text( GTK_LABEL(status), _("Rendering") ); gtk_progress_bar_update( GTK_PROGRESS_BAR(progress_bar), 0 ); while ( gtk_events_pending() ) gtk_main_iteration(); gdk_flush(); gdk_threads_leave(); } if ( rendering ) { char *substr = strstr( console_line, "Rendering line " ); if ( substr != NULL ) { print = false; sscanf( substr + 15, "%u of", &image_line ); float prog = (float)(image_line) / (float)hauteur; strncpy( time, console_line, 9 ); time[9] = '\0'; gdk_threads_enter(); if ( prog > 0.01 ) gtk_progress_bar_update( GTK_PROGRESS_BAR(progress_bar), prog ); gtk_label_set_text( GTK_LABEL(time_lab), time ); gdk_flush(); gdk_threads_leave(); } } if ( strstr( console_line, "command not found" ) ) { stop_rendering_scene( true ); gdk_threads_enter(); app_warning( _("Povray command not found. Please set path in preferences.") ); gdk_flush(); gdk_threads_leave(); pthread_exit(NULL); } bool error = false; if ( strstr( console_line, "Error" ) != NULL ) error = true; if ( strstr( console_line, "error" ) != NULL ) error = true; if ( strstr( console_line, "Possible" ) != NULL ) error = true; if ( error ) { gdk_threads_enter(); app_warning( _("Error while executing povray ! See console for details") ); gdk_flush(); gdk_threads_leave(); } if ( finished == true && parsing_done == false && error == false ) { gdk_threads_enter(); app_warning( _("Povray command not found. Please set path in preferences.") ); gdk_flush(); gdk_threads_leave(); } // Copy povray output to tv rendering console if ( print ) { gdk_threads_enter(); GtkTextBuffer *buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(cons_text) ); GtkTextIter end; gtk_text_buffer_get_end_iter( buffer, &end ); gtk_text_buffer_insert( buffer, &end, console_line, -1 ); gdk_flush(); gdk_threads_leave(); } } pthread_testcancel(); stop_rendering_scene( true ); //filez.close(); pthread_exit(NULL); } //*********************************************** // Console dialog // // Raise the dialog //*********************************************** void PovrayFE::raise_console_dlg() { if ( cons_dlg != NULL ) return; PREF_DEF cons_dlg = gtk_dialog_new_with_buttons( _("Rendering console"), NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL ); gtk_window_set_policy( GTK_WINDOW(cons_dlg), TRUE, TRUE, FALSE ); g_signal_connect( G_OBJECT(cons_dlg), "close", G_CALLBACK(sign_povfe_cons_click), this ); g_signal_connect( G_OBJECT(cons_dlg), "response", G_CALLBACK(sign_povfe_cons_destroy), this ); if ( pref->save_dlg_geo->value() ) { if ( pref->con_xpos->value() < 0 ) pref->con_xpos->set(0); if ( pref->con_ypos->value() < 0 ) pref->con_ypos->set(0); gtk_widget_set_uposition( cons_dlg, pref->con_xpos->value(), pref->con_ypos->value() ); gtk_window_resize( GTK_WINDOW(cons_dlg), pref->con_xsize->value(), pref->con_ysize->value() ); } GtkWidget *scroll = gtk_scrolled_window_new( NULL, NULL ); gtk_container_set_border_width( GTK_CONTAINER(scroll), 5 ); gtk_container_add( GTK_CONTAINER(GTK_DIALOG(cons_dlg)->vbox), scroll ); gtk_widget_reparent( cons_text, scroll ); gtk_widget_show_all(cons_dlg); } //*********************************************** // Destroy console //*********************************************** void PovrayFE::close_console_dlg() { if ( ! GTK_IS_DIALOG(cons_dlg) ) return; PREF_DEF if ( pref->save_dlg_geo->value() ) { gint x,y; gdk_window_get_root_origin( cons_dlg->window, &x, &y ); pref->con_xpos->set( x ); pref->con_ypos->set( y ); pref->con_xsize->set( cons_dlg->allocation.width ); pref->con_ysize->set( cons_dlg->allocation.height ); } gtk_widget_reparent( cons_text, cons_box ); gtk_widget_destroy( cons_dlg ); cons_dlg = NULL; } //*********************************************** // Save // // Save front end options in scene file //*********************************************** void PovrayFE::save( ofstream & file ) { file << "\nRENDER_OPTIONS{\n"; for ( unsigned int i = 0 ; i < tv_widgets.size() ; i++ ) tv_widgets[i]->save( file ); file << "\n}"; } //*********************************************** // Load // // Load front end options from a scene file //*********************************************** bool PovrayFE::load( ifstream & file, char *ltag ) { if ( strcmp( ltag, "RENDER_OPTIONS" ) ) return false; char * tag = NULL; do { tag = tvio_get_next_tag( file ); bool found = false; if ( tag == NULL ) break; for ( unsigned int i = 0 ; i < tv_widgets.size() ; i++ ) if( tv_widgets[i]->load( file, tag ) ) { found = true; break; } if ( found ) continue; tvio_skip_section(file ); } while ( tag != NULL ); return true; } //*********************************************** // Output to povray // // Output renderer options to povray pov file //*********************************************** void PovrayFE::output_to_povray( ofstream & file ) { PREF_DEF file << "\n\n// Global settings\nglobal_settings {"; file << "\n\tadc_bailout " << adc_bailout->value(); file << "\n\tambient_light "; ambient_light->output_to_povray( file ); noisegen->output_to_povray( file ); file << "\n\tassumed_gamma " << pref->gamma->value(); if ( hf_gray_16->value() ) file << "\n\thf_gray_16 "; file << "\n\tirid_wavelength "; irid_wavelength->output_to_povray( file ); file << "\n\tmax_trace_level " << max_trace_level->value(); file << "\n\tmax_intersections " << max_intersections->value(); file << "\n\tnumber_of_waves " << number_of_waves->value(); if ( radiosity->value() ) { file << "\n\tradiosity {"; file << "\n\t\tbrightness " << brightness->value(); file << "\n\t\tcount " << count->value(); //file << "\n\t\tdistance_maximum " << distance_maximum->value(); file << "\n\t\terror_bound " << error_bound->value(); file << "\n\t\tgray_threshold " << gray_threshold->value(); file << "\n\t\tlow_error_factor " << low_error_factor->value(); file << "\n\t\tminimum_reuse " << minimum_reuse->value(); file << "\n\t\tnearest_count " << nearest_count->value(); file << "\n\t\trecursion_limit " << recursion_limit->value(); file << "\n\t\tadc_bailout " << rad_adc_bailout->value(); file << "\n\t\talways_sample " << always_sample->value(); file << "\n\t\tmax_sample " << max_sample->value(); file << "\n\t\tmedia " << rad_media->value(); file << "\n\t\tnormal " << rad_normal->value(); file << "\n\t\tpretrace_start " << pretrace_start->value(); file << "\n\t\tpretrace_end " << pretrace_end->value(); file << "\n\t\t}"; } // Photons file << "\n\tphotons {"; if ( set_spacing->value() ) file << "\n\t\tspacing " << spacing->value(); if ( set_count->value() ) file << "\n\t\tspacing " << count->value(); file << "\n\t\tgather " << gather_min->value() << "," << gather_max->value(); if ( use_media->value() ) file << "\n\t\tmedia " << max_steps->value() << "," << media_factor->value(); file << "\n\t\tjitter " << jitter->value(); file << "\n\t\tmax_trace_level " << photon_max_trace->value(); file << "\n\t\tadc_bailout " << photon_adc->value(); file << "\n\t\tautostop " << autostop->value(); file << "\n\t\texpand_thresholds " << photon_thres_perc->value() << "," << photon_thres_min->value(); file << "\n\t\tradius "; if ( set_gradius->value() ) file << gradius->value(); file << "," << gradius_mult->value() << ","; if ( set_gradius_med->value() ) file << gradius_med->value(); file << "," << gradius_med_mult->value(); file << "\n\t}"; file << "\n\t}\n\n"; } //*********************************************** // Output to povray // // Output renderer options to povray ini file //*********************************************** void PovrayFE::output_to_povray_ini( ofstream & file, char *fname ) { file << "\n; Input options"; file << "\nInput_File_Name=" << fname; file << "\n\n; Geometry options"; file << "\nHeight=" << height->value(); file << "\nWidth=" << width->value(); file << "\nStart_Column=" << start_col->value(); file << "\nStart_row=" << start_row->value(); file << "\nEnd_Column=" << end_col->value(); file << "\nEnd_Row=" << end_row->value(); file << "\n\n; Display options"; file << "\nDisplay=" << ( display->value() ? "on" : "off" ); file << "\nDraw_vistas=" << ( draw_vista->value() ? "on" : "off" ); file << "\n\n; Output options"; file << "\nOutput_File_Name=" << filename->value(); file << "\nOutput_File_Type=" << file_type_output[fimage_type->value()]; file << "\nOutput_Alpha=" << alpha->value(); file << "\nBits_Per_Color=" << bits_per_color->value(); file << "\nQuality=" << quality->value(); file << "\nRadiosity=" << ( radiosity->value() ? "on" : "off" ); file << "\n\n; Antialiasing options"; file << "\nAntialias=" << ( antialias->value() ? "on" : "off" ); file << "\nSampling_Method=" << anti_met->value(); file << "\nAntialias_threshold=" << threshold->value(); file << "\nJitter=" << ( jitter->value() ? "on" : "off" ); file << "\nJitter_Amount=" << jamount->value(); file << "\nAntialias_Depth=" << anti_depth->value(); file << "\n\n; Bounding control options"; file << "\nBounding_Threshold=" << bounding_thres->value(); file << "\nLight_Buffer=" << ( light_buff->value() ? "on" : "off" ); file << "\nVista_Buffer=" << ( vista->value() ? "on" : "off" ); file << "\n\n; Misc options"; file << "\nContinue_Trace=on"; file << "\nTest_Abort=on"; file << "\nPause_When_Done=on"; }