/* render.c - height field rendering interface * * Copyright (C) 2001, 2006 Patrice St-Gelais * patrstg@users.sourceforge.net * http://geomorph.sourceforge.net * * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "render.h" #include "../utils/utils.h" #include "../utils/menus_n_tools.h" #include "hf_wrapper.h" #include "camera.h" #include // Toolbar for rendering commands #include "../icons/run2.xpm" #include "../icons/run2_with_choice.xpm" #include "../icons/stop.xpm" extern gchar *HF_OUTPUT_FOR_RENDERING, *OUTPUT_PREFIX; command_item_struct render_commands[NBRENDERCOM] = { "Render", "Choose & Run", "Choose a scene (.pov) and render it", 0, (gchar **) run2_with_choice_xpm, GDK_LEFT_PTR, run_with_choice_callb,NULL, NULL, FALSE, "Render", "Run", "Render the current scene (.pov)", 0, (gchar **) run2_xpm, GDK_LEFT_PTR, run_callb,NULL, NULL, FALSE, "Render", "Stop", "Stop the scene rendering", 0, (gchar **) stop_xpm, GDK_LEFT_PTR, stop_callb,NULL, NULL, FALSE }; #define NB_SCENE_EXT 2 omenu_list_type scene_ext_list[NB_SCENE_EXT] = { NULL,0,NULL,gettext_noop("POV"),filetype_sel_callback_fn, NULL,0,NULL,gettext_noop(""),filetype_sel_callback_fn, }; GtkWidget *create_render_bar (GtkWidget *window, GtkTooltips *tooltips, gpointer data) { GtkWidget *bar; bar = standard_toolbar_new(NBRENDERCOM, render_commands, tooltips, window, data, GTK_ORIENTATION_HORIZONTAL, GTK_TOOLBAR_ICONS, FALSE); return bar; } void save_render_options_inc (hf_wrapper_struct *hfw) { // Private method, added 2007-01-01 // Save some render options in render_options.inc, in the current directory // those that are not camera related // and that cannot be specified on the command line FILE *fin; gchar *loc, *msg_buf; if (!(fin=fopen("render_options.inc","wb"))) { msg_buf = (gchar *) malloc(sizeof(gchar) + strlen("render_options.inc") + strlen(_("Not able to open '%s' file for writing"))+5); sprintf(msg_buf,_("Not able to open '%s' file for writing"),"render_options.inc"); my_msg(msg_buf,WARNING); } else { // loc = setlocale(LC_NUMERIC,""); // Povray uses "." as decimal separator instead of "," // setlocale(LC_NUMERIC,"C"); if (hfw->creation_mode || *hfw->if_modified) fprintf(fin,"#declare hf_to_render = %c%s%c;\n",'\"',HF_OUTPUT_FOR_RENDERING,'\"'); else // If the current height field has not been changed, we render the source file fprintf(fin,"#declare hf_to_render = %c%s%c;\n",'\"',*hfw->filename,'\"'); fprintf(fin,"#declare current_directory = %c%s%c;\n",'\"',*hfw->dirname,'\"'); // setlocale(LC_NUMERIC,loc); fclose(fin); } } void render_pov(hf_wrapper_struct *hfw) { // buf is the string array passed to the exec function // It MUST have one index more than the number of required arguments, // and the last index MUST be NULL static char *buf[] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; gchar *fname, *dname; // gchar msg_buf[255]; gint i; // 2007-01-01 - Check next line - filename now is not supposed to contain a path fname = get_file_name (*hfw->filename, FILESEP); // 2007-01-01 Dir name required to be used as a Library path // We extract the dir name to remove the file separator at the end if (*hfw->dirname) { dname = get_dir_name (*hfw->dirname, FILESEP); // sprintf(msg_buf,"DNAME: %s\n",dname); // my_msg(msg_buf,INFO); // Remove spaces i = strlen(fname)-1; while ((fname[i]==' ') && (i>0)) i--; fname[i+1]='\0'; // Remove last "/" i = strlen(dname)-1; while ((dname[i]==FILESEP) && (i>0)) i--; dname[i+1]='\0'; } // sprintf(msg_buf,"DIRNAME: %d - %s; FNAME: %d - %s; FILENAME: %d - %s; %d\n",strlen(*hfw->dirname), *hfw->dirname,strlen(fname), fname, strlen(*hfw->filename), *hfw->filename, fname[10]); // my_msg(msg_buf,INFO); save_render_options_inc (hfw); // 2004-12-23 Arguments separated for compatibility with MDK10.1 buf[0] = RENDERER; buf[1] = (gchar *) malloc(strlen(SCENE)+5); buf[2] = (gchar *) malloc(15); buf[3] = (gchar *) malloc(15); buf[4] = (gchar *) malloc(strlen(fname)+strlen(OUTPUT_PREFIX)+5); buf[5] = (gchar *) malloc(strlen(dname)+5); buf[6] = OTHER_RENDER_OPTIONS; sprintf(buf[1],"+I%s",SCENE); sprintf(buf[2],"+W%05d",RENDER_WIDTH); sprintf(buf[3],"+H%05d",RENDER_HEIGHT); sprintf(buf[4],"+O%s%s",OUTPUT_PREFIX,fname); sprintf(buf[5],"+L%s",dname); // printf("CURRENT_DIR: %s\n",get_current_dir_name()); // printf("POV: str: %s; W: %s; H: %s; Output: %s; Dname: %s; RENDER_OPTIONS: %s\n",buf[1],buf[2],buf[3], buf[4], buf[5], buf[6]); hfw->hf_options->povray_pid = execution(buf[0],buf); // printf("PID: %d\n",hfw->hf_options->povray_pid); if (buf[1]) { free(buf[1]); buf[1]=NULL; } if (buf[2]) { free(buf[2]); buf[2]=NULL; } if (buf[3]) { free(buf[3]); buf[3]=NULL; } if (buf[4]) { free(buf[4]); buf[4]=NULL; if (fname) free(fname); } if (buf[5]) { free(buf[5]); buf[5]=NULL; if (dname) free(dname); } } void run_callb(GtkWidget *wdg, gpointer data) { // Render a povray image, display only // First we save the image under HF_OUTPUT_FOR_RENDERING // (usually test.png) in the current directory gchar *dir; gfloat ar; hf_wrapper_struct *hfw; if (wdg) if (GTK_IS_TOGGLE_BUTTON(wdg)) if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wdg))) return; if (!data) return; hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data; if (!hfw) return; // commit_pending_record(hfw); // hfw->hf_options->current_cursor = gdk_cursor_new(GDK_LEFT_PTR); // printf("OUTPUT: %s\n",HF_OUTPUT_FOR_RENDERING); dir = (gchar *) get_current_dir_name(); chdir(POV_DIR); // If the current height field has not been changed, we render the source file if (hfw->creation_mode || *hfw->if_modified) hf_wrapper_save(hfw, HF_OUTPUT_FOR_RENDERING); // Patch 2005-05 - Deduce aspect ratio from image size, // backup the original (which is the preview W/H ratio), maybe for the future... ar = hfw->gl_preview->cameras[hfw->gl_preview->current_camera_id]->aspect_ratio; hfw->gl_preview->cameras[hfw->gl_preview->current_camera_id]->aspect_ratio = ((gfloat) RENDER_WIDTH) / (gfloat) RENDER_HEIGHT; gl_save_camera_inc (hfw->gl_preview->cameras[hfw->gl_preview->current_camera_id]); hfw->gl_preview->cameras[hfw->gl_preview->current_camera_id]->aspect_ratio = ar; render_pov(hfw); chdir(dir); free(dir); } void run_with_choice_callb(GtkWidget *wdg, gpointer data) { // Render a povray image after choosing a scene file gchar *path_n_file; if (wdg) if (GTK_IS_TOGGLE_BUTTON(wdg)) if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wdg))) return; path_n_file = GetFilename( scene_ext_list, NB_SCENE_EXT, _("Open"), POV_DIR, EXISTING_FILE, scene_ext_list[0].lbl); if (path_n_file) SCENE = path_n_file; else return; POV_DIR = get_dir_name(path_n_file,FILESEP); // It could be dangerous to free SCENE before reinitializing it // It could contain a default #define value (check this... small memory leakage here). // However path_n_file is always "malloced" in GetFilename run_callb(wdg, data); } void stop_callb(GtkWidget *wdg, gpointer data) { hf_wrapper_struct *hfw; if (!wdg) return; if (GTK_IS_TOGGLE_BUTTON(wdg)) if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wdg))) return; if (!data) return; hfw = (hf_wrapper_struct *) * (hf_wrapper_struct **) data; if (!hfw) return; if (hfw->hf_options->povray_pid<=0) return; kill((pid_t) hfw->hf_options->povray_pid, SIGKILL); hfw->hf_options->povray_pid = 0; }