1 | /*************************************** 2 | $Header: /cvsroot/petscgraphics/tsview-ng.c,v 1.65 2006/02/05 21:27:20 hazelsct Exp $ 3 | 4 | This program views the output of a time series saved using 5 | +latex+{\tt IlluMultiSave()}. 6 | +html+ <tt>IlluMultiSave()</tt>. 7 | It basically just switches between timesteps; future versions may be more 8 | interesting. The neat part of it is that it loads multiprocessor data and 9 | displays it on a single CPU. 10 | ***************************************/ 11 | 12 | static char help[] = "Displays the output of of a timestep series saved using IlluMultiSave().\n\ 13 | Usage:\n\ 14 | \n\ 15 | tsview <basename> [-no_transparency]\n\ 16 | \n\ 17 | Then interactively flip through the timesteps (h or ? lists commands).\n"; 18 | 19 | #include "illuminator.h" 20 | #include <glade/glade.h> 21 | #include <gnome.h> 22 | #include <libgnomeui/libgnomeui.h> 23 | #include <sys/dir.h> /* For scandir(), alphasort, struct dirent */ 24 | #include <libgen.h> /* For dirname(), basename() */ 25 | #include <string.h> /* For strdup() */ 26 | 27 | /* Build with -DDEBUG for debugging output */ 28 | #undef DPRINTF 29 | #ifdef DEBUG 30 | #define DPRINTF(fmt, args...) PetscPrintf (PETSC_COMM_WORLD, "%s: " fmt, __FUNCT__, args) 31 | #else 32 | #define DPRINTF(fmt, args...) 33 | #endif 34 | 35 | /*+ Declared in illuminator.c, these give the current number of triangles on 36 | this node and corner coordinates and color information for each triangle. +*/ 37 | 38 | GladeXML *xml; 39 | ISurface Surf; 40 | IDisplay Disp [1] = { NULL }; 41 | 42 | /* Filename list and time/log info */ 43 | int entrynum=0, total_entries=0, current_timestep; 44 | char *the_basename, *basedirname, **stepnames=NULL; 45 | double current_time; 46 | char *log_text=NULL; 47 | 48 | /* Ternary diffusion path color, and supplementary diffusion path data: there 49 | are dp_supp_colors colors, each corresponding to a color and a number of 50 | points in the big A and B arrays. */ 51 | PetscScalar ternary_dp_color[4] = { 0.,0.,0.,1. }; 52 | int dp_supp_colors=0, *dp_supp_color_points=NULL; 53 | PetscScalar *dp_supp_red=NULL, *dp_supp_green=NULL, *dp_supp_blue=NULL, 54 | *dp_supp_alpha=NULL; 55 | PetscScalar *dp_supp_AB=NULL; 56 | 57 | /* Window parameters and drawables */ 58 | #define DEFAULT_RENDER_SIZE 300 59 | #define SCALE_WIDTH 200 60 | #define SCALE_HEIGHT 200 61 | #define SCALE_BPP 3 62 | int width=0, height=0, bpp=3, nx, ny, transform, dataview_count=1; 63 | GtkWidget *dataviews [1]; 64 | IDisplay scalar_disp, ternary_square_disp, ternary_triangle_disp, ternary_disp, 65 | vector_disp, shear_disp; 66 | gboolean scalar_auto_set=TRUE, ternary_auto_set=TRUE, ternary_square_set=FALSE, 67 | vector_auto_set=TRUE, shear_auto_set=TRUE; 68 | gdouble sizemag; 69 | PetscTruth transp; 70 | 71 | /* PETSc structures etc. */ 72 | DA theda; 73 | Vec global; 74 | PetscScalar minmax[6] = { 0.,1., 0.,1., 0.,1. }; 75 | PetscScalar scales[15]; /* 2 scalar, 6 tritern, 4 sqtern, 2 vector, 1 tensor */ 76 | field_plot_type *fieldtypes; 77 | int dimensions, num_fields, current_field, *field_index, num_variables[1], 78 | **variable_indices; 79 | 80 | /* First some primary functions which do stuff, then callbacks, then main(). */ 81 | 82 | #undef __FUNCT__ 83 | #define __FUNCT__ "render_dataviews" 84 | 85 | /* Width and height are reversed if rotated, so use these macros with render */ 86 | #define RENDER_WIDTH ((transform & ROTATE_LEFT) ? height : width) 87 | #define RENDER_HEIGHT ((transform & ROTATE_LEFT) ? width : height) 88 | 89 | int render_dataviews () 90 | { 91 | int viewnum, nx,ny,nz, ierr; 92 | 93 | DPRINTF ("Rendering dataviews\n",0); 94 | if (dataview_count != 1) 95 | { 96 | printf ("dataview_count != 1 is not yet supported\n"); 97 | exit(0); 98 | } 99 | for (viewnum=0; viewnum<dataview_count; viewnum++) 100 | { 101 | int nx,ny, xs,ys, xm,ym, i; 102 | PetscScalar minval, maxval, refmag, *global_array; 103 | GtkType type; 104 | char thestatus [100]; 105 | 106 | /* (Re)allocate buffer */ 107 | if (!Disp[0]) 108 | { 109 | DPRINTF ("Allocating IDisplay RGB buffer\n",0); 110 | if (IDispCreate (Disp, width, height, width, bpp, 0)) { 111 | printf ("ERROR: can't allocate RGB buffer\n"); 112 | exit (1); } 113 | } 114 | else 115 | { 116 | DPRINTF ("Reallocating IDisplay RGB buffer\n",0); 117 | if (IDispResize (Disp[0], width, height, width, bpp, 0)) { 118 | printf ("ERROR: can't reallocate RGB buffer\n"); 119 | exit (1); } 120 | } 121 | DPRINTF ("Done, (re)sizing drawing area\n",0); 122 | 123 | /* Make sure the drawing area is the right size */ 124 | gtk_drawing_area_size (GTK_DRAWING_AREA (dataviews[viewnum]), 125 | width, height); 126 | 127 | /* Render into Disp [viewnum] */ 128 | ierr = DAGetInfo (theda, PETSC_NULL, &nx,&ny,PETSC_NULL, 129 | PETSC_NULL,PETSC_NULL,PETSC_NULL, PETSC_NULL, 130 | PETSC_NULL,PETSC_NULL,PETSC_NULL); CHKERRQ (ierr); 131 | ierr = DAGetCorners (theda, &xs,&ys,PETSC_NULL, &xm,&ym,PETSC_NULL); 132 | CHKERRQ (ierr); 133 | 134 | DPRINTF ("Rendering %dx%d buffer with transform %d\n", RENDER_WIDTH, 135 | RENDER_HEIGHT, transform); 136 | if (dimensions == 2) 137 | { 138 | char maxes [6][20]; 139 | 140 | ierr = VecGetArray (global, &global_array); CHKERRQ (ierr); 141 | 142 | /* Plot with automatic or manual scaling, as appropriate */ 143 | switch (fieldtypes [current_field]) 144 | { 145 | case FIELD_SCALAR: 146 | if (scalar_auto_set) 147 | { 148 | auto_scale (global_array, xm*ym, num_fields, current_field, 149 | FIELD_SCALAR, 2, scales); 150 | snprintf (maxes[0], 19, "%g", scales[0]); 151 | snprintf (maxes[1], 19, "%g", scales[1]); 152 | gtk_entry_set_text (GTK_ENTRY (glade_xml_get_widget 153 | (xml, "scalar_min_entry")), 154 | maxes[0]); 155 | gtk_entry_set_text (GTK_ENTRY (glade_xml_get_widget 156 | (xml, "scalar_max_entry")), 157 | maxes[1]); 158 | } 159 | ierr = render_rgb_local_2d 160 | (Disp[0], global_array, num_fields,current_field, FIELD_SCALAR, 161 | scales, nx,ny, xs,ys, xm,ym, transform, NULL,0,0,0,0); 162 | CHKERRQ (ierr); 163 | break; 164 | 165 | case FIELD_TERNARY: 166 | case FIELD_TERNARY_SQUARE: 167 | if (!ternary_square_set) /* Ternary triangle */ 168 | { 169 | GtkWidget *ternary_scale_area = glade_xml_get_widget 170 | (xml, "ternary_scale_area"); 171 | int color, point, i; 172 | 173 | if (ternary_auto_set) 174 | { 175 | auto_scale (global_array, xm*ym, num_fields, 176 | current_field, FIELD_TERNARY, 2, scales+2); 177 | snprintf (maxes[0], 19, "%g", scales[2]); 178 | snprintf (maxes[1], 19, "%g", scales[3]); 179 | snprintf (maxes[2], 19, "%g", scales[4]); 180 | snprintf (maxes[3], 19, "%g", scales[5]); 181 | snprintf (maxes[4], 19, "%g", scales[6]); 182 | snprintf (maxes[5], 19, "%g", scales[7]); 183 | gtk_entry_set_text (GTK_ENTRY (glade_xml_get_widget 184 | (xml,"ternary_1A_entry")), 185 | maxes[0]); 186 | gtk_entry_set_text (GTK_ENTRY (glade_xml_get_widget 187 | (xml,"ternary_1B_entry")), 188 | maxes[1]); 189 | gtk_entry_set_text (GTK_ENTRY (glade_xml_get_widget 190 | (xml,"ternary_2A_entry")), 191 | maxes[2]); 192 | gtk_entry_set_text (GTK_ENTRY (glade_xml_get_widget 193 | (xml,"ternary_2B_entry")), 194 | maxes[3]); 195 | gtk_entry_set_text (GTK_ENTRY (glade_xml_get_widget 196 | (xml,"ternary_3A_entry")), 197 | maxes[4]); 198 | gtk_entry_set_text (GTK_ENTRY (glade_xml_get_widget 199 | (xml,"ternary_3B_entry")), 200 | maxes[5]); 201 | } 202 | 203 | /* Start with blank ternary scale */ 204 | render_scale_2d (ternary_triangle_disp, FIELD_TERNARY, 1); 205 | /* Overlay diffusion path supplements on scale */ 206 | for (color=0, i=0; color<dp_supp_colors; 207 | i+=dp_supp_color_points[color++]) 208 | render_composition_path 209 | (ternary_triangle_disp, dp_supp_AB+i*2, 210 | dp_supp_color_points[color], 2, FIELD_TERNARY, scales+2, 211 | dp_supp_red[color], dp_supp_green[color], 212 | dp_supp_blue[color], dp_supp_alpha[color]); 213 | /* Render diagram, add diffusion path to scale */ 214 | ierr = render_rgb_local_2d 215 | (Disp[0], global_array, num_fields, current_field, 216 | FIELD_TERNARY, scales+2, nx,ny, xs,ys, xm,ym, transform, 217 | ternary_triangle_disp, 218 | ternary_dp_color[0],ternary_dp_color[1], 219 | ternary_dp_color[2],ternary_dp_color[3]); 220 | CHKERRQ (ierr); 221 | IDispDrawGdk (ternary_triangle_disp, ternary_scale_area, 222 | GDK_RGB_DITHER_MAX); 223 | } 224 | else /* Ternary square */ 225 | { 226 | GtkWidget *ternary_scale_area = glade_xml_get_widget 227 | (xml, "ternary_scale_area"); 228 | 229 | if (ternary_auto_set) 230 | { 231 | auto_scale (global_array, xm*ym, num_fields, 232 | current_field, FIELD_TERNARY_SQUARE, 2, 233 | scales+8); 234 | snprintf (maxes[0], 19, "%g", scales[8]); 235 | snprintf (maxes[1], 19, "%g", scales[9]); 236 | snprintf (maxes[2], 19, "%g", scales[10]); 237 | snprintf (maxes[3], 19, "%g", scales[11]); 238 | gtk_entry_set_text (GTK_ENTRY (glade_xml_get_widget 239 | (xml,"ternary_1A_entry")), 240 | maxes[0]); 241 | gtk_entry_set_text (GTK_ENTRY (glade_xml_get_widget 242 | (xml,"ternary_1B_entry")), 243 | maxes[1]); 244 | gtk_entry_set_text (GTK_ENTRY (glade_xml_get_widget 245 | (xml,"ternary_2A_entry")), 246 | maxes[2]); 247 | gtk_entry_set_text (GTK_ENTRY (glade_xml_get_widget 248 | (xml,"ternary_2B_entry")), 249 | maxes[3]); 250 | } 251 | 252 | render_scale_2d (ternary_triangle_disp, FIELD_TERNARY, 1); 253 | ierr = render_rgb_local_2d 254 | (Disp[0], global_array, num_fields, current_field, 255 | FIELD_TERNARY_SQUARE, scales+8, nx,ny, xs,ys, xm,ym, 256 | transform, ternary_square_disp, 257 | ternary_dp_color[0], ternary_dp_color[1], 258 | ternary_dp_color[2], ternary_dp_color[3]); CHKERRQ (ierr); 259 | IDispDrawGdk (ternary_square_disp, ternary_scale_area, 260 | GDK_RGB_DITHER_MAX); 261 | } 262 | break; 263 | 264 | case FIELD_VECTOR: 265 | if (vector_auto_set) 266 | { 267 | auto_scale (global_array, xm*ym, num_fields, current_field, 268 | FIELD_VECTOR, 2, scales+12); 269 | snprintf (maxes[0], 19, "%g", scales[13]); 270 | gtk_entry_set_text (GTK_ENTRY (glade_xml_get_widget 271 | (xml, "vector_max_entry")), 272 | maxes[0]); 273 | } 274 | ierr = render_rgb_local_2d 275 | (Disp[0], global_array, num_fields, current_field, 276 | FIELD_VECTOR, scales+12, nx,ny, xs,ys, xm,ym, transform, 277 | NULL,0,0,0,0); CHKERRQ (ierr); 278 | break; 279 | 280 | case FIELD_TENSOR_SHEAR: 281 | if (shear_auto_set) 282 | { 283 | auto_scale (global_array, xm*ym, num_fields, current_field, 284 | fieldtypes [current_field], 2, scales+14); 285 | snprintf (maxes[0], 19, "%g", scales[14]); 286 | gtk_entry_set_text (GTK_ENTRY (glade_xml_get_widget 287 | (xml, "shear_max_entry")), 288 | maxes[0]); 289 | } 290 | ierr = render_rgb_local_2d 291 | (Disp[0], global_array, num_fields, current_field, 292 | FIELD_TENSOR_SHEAR,scales+14, nx,ny, xs,ys, xm,ym, transform, 293 | NULL,0,0,0,0); CHKERRQ (ierr); 294 | break; 295 | } 296 | 297 | ierr = VecRestoreArray (global, &global_array); CHKERRQ (ierr); 298 | } 299 | else /* Three dimensions */ 300 | { 301 | /* Fixed negative z-direction for now */ 302 | PetscScalar eye[3], dir[3] = {0, 0, -1.}, right[3] = {.5, 0., 0.}; 303 | guchar bgcolor[4] = { 0x50, 0x50, 0x50, 0xFF }; 304 | eye[0] = 0.5*(minmax[0]+minmax[1]); 305 | eye[1] = 0.5*(minmax[2]+minmax[3]); 306 | eye[2] = minmax[5] + minmax[1]-minmax[0]; 307 | 308 | if (!Surf) 309 | ierr = SurfCreate (&Surf); CHKERRQ (ierr); 310 | 311 | ierr = DATriangulate 312 | (Surf, theda, global, current_field, minmax, PETSC_DECIDE, 313 | PETSC_NULL, PETSC_NULL, PETSC_FALSE, PETSC_FALSE, PETSC_FALSE); 314 | CHKERRQ(ierr); 315 | 316 | IDispFill (Disp[0], bgcolor); 317 | ierr = render_rgb_local_3d (Disp, Surf, eye, dir, right); 318 | ierr = SurfClear (Surf); CHKERRQ (ierr); 319 | } 320 | 321 | /* Draw IDisplay object onto window */ 322 | DPRINTF ("Painting %dx%d rgb%s buffer onto window\n", 323 | RENDER_WIDTH, RENDER_HEIGHT, (bpp==4) ? "_32" : ""); 324 | if (!dataviews [viewnum]) 325 | dataviews [viewnum] = glade_xml_get_widget (xml, "plot_area"); 326 | IDispDrawGdk (Disp[0], dataviews [viewnum], GDK_RGB_DITHER_MAX); 327 | } 328 | } 329 | 330 | 331 | #undef __FUNCT__ 332 | #define __FUNCT__ "myfilter" 333 | 334 | /*+ Little variable for myfilter() and refresh_stepnames(). +*/ 335 | static char *basefilename; 336 | 337 | /*++++++++++++++++++++++++++++++++++++++ 338 | This function returns non-zero for "qualifying" file names which start with 339 | the stored files' basename.time and end with 340 | +latex+{\tt .cpu0000.meta}. 341 | +html+ <tt>.cpu0000.meta</tt>. 342 | It is used as the 343 | +latex+{\tt select()} function for {\tt scandir()} in {\tt main()}. 344 | +html+ <tt>select()</tt> function for <tt>scandir()</tt> in <tt>main()</tt>. 345 | 346 | int my_time_filter Returns non-zero for qualifying filenames. 347 | 348 | const struct dirent *direntry Directory entry with filename to test. 349 | ++++++++++++++++++++++++++++++++++++++*/ 350 | 351 | int my_time_filter (const struct dirent *direntry) 352 | { 353 | if ((!strncmp (direntry->d_name, basefilename, strlen(basefilename))) && 354 | (!strncmp (direntry->d_name + strlen(basefilename), ".time", 5))) 355 | return (!strncmp (direntry->d_name + strlen(direntry->d_name) - 13, 356 | ".cpu0000.meta", 13)); 357 | return 0; 358 | } 359 | 360 | 361 | /*++++++++++++++++++++++++++++++++++++++ 362 | This function returns non-zero for "qualifying" file names which start with 363 | the stored files' basename and end with 364 | +latex+{\tt .cpu0000.meta}. 365 | +html+ <tt>.cpu0000.meta</tt>. 366 | It is used as the 367 | +latex+{\tt select()} function for {\tt scandir()} in {\tt main()}. 368 | +html+ <tt>select()</tt> function for <tt>scandir()</tt> in <tt>main()</tt>. 369 | 370 | int my_notime_filter Returns non-zero for qualifying filenames. 371 | 372 | const struct dirent *direntry Directory entry with filename to test. 373 | ++++++++++++++++++++++++++++++++++++++*/ 374 | 375 | int my_notime_filter (const struct dirent *direntry) 376 | { 377 | if ((!strncmp (direntry->d_name, basefilename, strlen(basefilename)))) 378 | return (!strncmp (direntry->d_name + strlen(direntry->d_name) - 13, 379 | ".cpu0000.meta", 13)); 380 | return 0; 381 | } 382 | 383 | 384 | /*++++++++++++++++++++++++++++++++++++++ 385 | This loads the names of the files into a long list. 386 | ++++++++++++++++++++++++++++++++++++++*/ 387 | 388 | int refresh_stepnames () 389 | { 390 | struct dirent **namelist; 391 | char *filec, *dirc, totalsteps[14]; 392 | int i, ierr; 393 | 394 | filec = strdup (the_basename); 395 | dirc = strdup (the_basename); 396 | basefilename = basename (filec); 397 | basedirname = dirname (dirc); 398 | 399 | /* Default: scan for a timestep sequence */ 400 | total_entries = scandir (basedirname, &namelist, my_time_filter, alphasort); 401 | if (total_entries < 0) 402 | { 403 | ierr = PetscPrintf (PETSC_COMM_WORLD, "Error scanning directory %s\n", 404 | basedirname); CHKERRQ (ierr); 405 | return 1; 406 | } 407 | if (!total_entries) 408 | { 409 | /* Perhaps this is not a timestep sequence */ 410 | total_entries = scandir (basedirname, &namelist, my_notime_filter, 411 | alphasort); 412 | if (total_entries < 0) 413 | { 414 | ierr= PetscPrintf (PETSC_COMM_WORLD, "Error scanning directory %s\n", 415 | basedirname); CHKERRQ (ierr); 416 | return 1; 417 | } 418 | if (!total_entries) 419 | { 420 | ierr = PetscPrintf (PETSC_COMM_WORLD, "No such files\n"); 421 | CHKERRQ (ierr); 422 | return 1; 423 | } 424 | } 425 | DPRINTF ("%d eligible files:\n", total_entries); 426 | snprintf (totalsteps, 14, "/%d", total_entries-1); 427 | gtk_label_set_text (GTK_LABEL (glade_xml_get_widget 428 | (xml, "total_label")), totalsteps); 429 | 430 | if (!(stepnames = (char **) realloc 431 | (stepnames, total_entries*sizeof (char *)))) 432 | { 433 | ierr = PetscPrintf (PETSC_COMM_WORLD, "Error allocating memory\n"); 434 | CHKERRQ (ierr); 435 | return 1; 436 | } 437 | for (i=0; i<total_entries; i++) 438 | { 439 | int filength = strlen(namelist[i]->d_name); 440 | 441 | stepnames [i] = (char *) malloc ((filength-12)*sizeof(char)); 442 | strncpy (stepnames [i], namelist[i]->d_name, filength-13); 443 | stepnames [i] [filength-13] = '\0'; 444 | free (namelist[i]); 445 | DPRINTF ("[%d] %s\n", i, stepnames [i]); 446 | if (ierr) 447 | printf ("myfilter() Error: %d\n", ierr); 448 | /* CHKERRQ (ierr); */ 449 | } 450 | 451 | free (namelist); 452 | return 0; 453 | } 454 | 455 | void on_plot_area_expose_event 456 | (GtkWidget *widget, GdkEventExpose *event, gpointer user_data) 457 | { IDispDrawGdk (Disp[0], widget, GDK_RGB_DITHER_MAX); } 458 | 459 | void on_scalar_scale_area_expose_event 460 | (GtkWidget *widget, GdkEventExpose *event, gpointer user_data) 461 | { IDispDrawGdk (scalar_disp, widget, GDK_RGB_DITHER_MAX); } 462 | 463 | void on_ternary_scale_area_expose_event 464 | (GtkWidget *widget, GdkEventExpose *event, gpointer user_data) 465 | { IDispDrawGdk (ternary_disp, widget, GDK_RGB_DITHER_MAX); } 466 | 467 | void on_vector_scale_area_expose_event 468 | (GtkWidget *widget, GdkEventExpose *event, gpointer user_data) 469 | { IDispDrawGdk (vector_disp, widget, GDK_RGB_DITHER_MAX); } 470 | 471 | void on_shear_scale_area_expose_event 472 | (GtkWidget *widget, GdkEventExpose *event, gpointer user_data) 473 | { IDispDrawGdk (shear_disp, widget, GDK_RGB_DITHER_MAX); } 474 | 475 | void on_scalar_auto_checkbutton_toggled 476 | (GtkWidget *thebutton, gpointer user_data) 477 | { 478 | scalar_auto_set = gtk_toggle_button_get_active 479 | (GTK_TOGGLE_BUTTON (thebutton)); 480 | if (scalar_auto_set) 481 | { 482 | gtk_widget_set_sensitive 483 | (glade_xml_get_widget (xml, "scalar_min_label"), FALSE); 484 | gtk_widget_set_sensitive 485 | (glade_xml_get_widget (xml, "scalar_max_label"), FALSE); 486 | gtk_widget_set_sensitive 487 | (glade_xml_get_widget (xml, "scalar_min_entry"), FALSE); 488 | gtk_widget_set_sensitive 489 | (glade_xml_get_widget (xml, "scalar_max_entry"), FALSE); 490 | } 491 | else 492 | { 493 | gtk_widget_set_sensitive 494 | (glade_xml_get_widget (xml, "scalar_min_label"), TRUE); 495 | gtk_widget_set_sensitive 496 | (glade_xml_get_widget (xml, "scalar_max_label"), TRUE); 497 | gtk_widget_set_sensitive 498 | (glade_xml_get_widget (xml, "scalar_min_entry"), TRUE); 499 | gtk_widget_set_sensitive 500 | (glade_xml_get_widget (xml, "scalar_max_entry"), TRUE); 501 | } 502 | } 503 | 504 | void on_ternary_auto_checkbutton_toggled 505 | (GtkWidget *thebutton, gpointer user_data) 506 | { 507 | ternary_auto_set = gtk_toggle_button_get_active 508 | (GTK_TOGGLE_BUTTON (thebutton)); 509 | if (ternary_auto_set) 510 | { 511 | gtk_widget_set_sensitive 512 | (glade_xml_get_widget (xml, "ternary_1A_label"), FALSE); 513 | gtk_widget_set_sensitive 514 | (glade_xml_get_widget (xml, "ternary_1B_label"), FALSE); 515 | gtk_widget_set_sensitive 516 | (glade_xml_get_widget (xml, "ternary_2A_label"), FALSE); 517 | gtk_widget_set_sensitive 518 | (glade_xml_get_widget (xml, "ternary_2B_label"), FALSE); 519 | gtk_widget_set_sensitive 520 | (glade_xml_get_widget (xml, "ternary_3A_label"), FALSE); 521 | gtk_widget_set_sensitive 522 | (glade_xml_get_widget (xml, "ternary_3B_label"), FALSE); 523 | gtk_widget_set_sensitive 524 | (glade_xml_get_widget (xml, "ternary_1A_entry"), FALSE); 525 | gtk_widget_set_sensitive 526 | (glade_xml_get_widget (xml, "ternary_1B_entry"), FALSE); 527 | gtk_widget_set_sensitive 528 | (glade_xml_get_widget (xml, "ternary_2A_entry"), FALSE); 529 | gtk_widget_set_sensitive 530 | (glade_xml_get_widget (xml, "ternary_2B_entry"), FALSE); 531 | gtk_widget_set_sensitive 532 | (glade_xml_get_widget (xml, "ternary_3A_entry"), FALSE); 533 | gtk_widget_set_sensitive 534 | (glade_xml_get_widget (xml, "ternary_3B_entry"), FALSE); 535 | } 536 | else 537 | { 538 | gtk_widget_set_sensitive 539 | (glade_xml_get_widget (xml, "ternary_1A_label"), TRUE); 540 | gtk_widget_set_sensitive 541 | (glade_xml_get_widget (xml, "ternary_1B_label"), TRUE); 542 | gtk_widget_set_sensitive 543 | (glade_xml_get_widget (xml, "ternary_2A_label"), TRUE); 544 | gtk_widget_set_sensitive 545 | (glade_xml_get_widget (xml, "ternary_2B_label"), TRUE); 546 | gtk_widget_set_sensitive 547 | (glade_xml_get_widget (xml, "ternary_3A_label"), TRUE); 548 | gtk_widget_set_sensitive 549 | (glade_xml_get_widget (xml, "ternary_3B_label"), TRUE); 550 | gtk_widget_set_sensitive 551 | (glade_xml_get_widget (xml, "ternary_1A_entry"), TRUE); 552 | gtk_widget_set_sensitive 553 | (glade_xml_get_widget (xml, "ternary_1B_entry"), TRUE); 554 | gtk_widget_set_sensitive 555 | (glade_xml_get_widget (xml, "ternary_2A_entry"), TRUE); 556 | gtk_widget_set_sensitive 557 | (glade_xml_get_widget (xml, "ternary_2B_entry"), TRUE); 558 | gtk_widget_set_sensitive 559 | (glade_xml_get_widget (xml, "ternary_3A_entry"), TRUE); 560 | gtk_widget_set_sensitive 561 | (glade_xml_get_widget (xml, "ternary_3B_entry"), TRUE); 562 | } 563 | } 564 | 565 | void on_ternary_square_checkbutton_toggled 566 | (GtkWidget *thebutton, gpointer user_data) 567 | { 568 | int field; 569 | char maxes [6][20]; 570 | 571 | ternary_square_set = gtk_toggle_button_get_active 572 | (GTK_TOGGLE_BUTTON (thebutton)); 573 | 574 | for (field=0; field<num_fields; field++) 575 | if (fieldtypes [field] == FIELD_TERNARY || 576 | fieldtypes [field] == FIELD_TERNARY_SQUARE) 577 | fieldtypes [field] = 578 | ternary_square_set ? FIELD_TERNARY_SQUARE : FIELD_TERNARY; 579 | render_dataviews (); 580 | 581 | if (ternary_square_set) 582 | { 583 | gtk_widget_hide (glade_xml_get_widget (xml, "ternary_3A_label")); 584 | gtk_widget_hide (glade_xml_get_widget (xml, "ternary_3A_entry")); 585 | gtk_widget_hide (glade_xml_get_widget (xml, "ternary_3B_label")); 586 | gtk_widget_hide (glade_xml_get_widget (xml, "ternary_3B_entry")); 587 | gtk_label_set_text (GTK_LABEL (glade_xml_get_widget 588 | (xml, "ternary_1A_label")), "Min A"); 589 | gtk_label_set_text (GTK_LABEL (glade_xml_get_widget 590 | (xml, "ternary_1B_label")), "Max B"); 591 | gtk_label_set_text (GTK_LABEL (glade_xml_get_widget 592 | (xml, "ternary_2A_label")), "Min A"); 593 | gtk_label_set_text (GTK_LABEL (glade_xml_get_widget 594 | (xml, "ternary_2B_label")), "Max B"); 595 | snprintf (maxes[0], 19, "%g", scales[8]); 596 | snprintf (maxes[1], 19, "%g", scales[9]); 597 | snprintf (maxes[2], 19, "%g", scales[10]); 598 | snprintf (maxes[3], 19, "%g", scales[11]); 599 | gtk_entry_set_text (GTK_ENTRY (glade_xml_get_widget 600 | (xml, "ternary_1A_entry")), maxes[0]); 601 | gtk_entry_set_text (GTK_ENTRY (glade_xml_get_widget 602 | (xml, "ternary_1B_entry")), maxes[1]); 603 | gtk_entry_set_text (GTK_ENTRY (glade_xml_get_widget 604 | (xml, "ternary_2A_entry")), maxes[2]); 605 | gtk_entry_set_text (GTK_ENTRY (glade_xml_get_widget 606 | (xml, "ternary_2B_entry")), maxes[3]); 607 | 608 | ternary_disp = ternary_square_disp; 609 | } 610 | else 611 | { 612 | gtk_widget_show (glade_xml_get_widget (xml, "ternary_3A_label")); 613 | gtk_widget_show (glade_xml_get_widget (xml, "ternary_3A_entry")); 614 | gtk_widget_show (glade_xml_get_widget (xml, "ternary_3B_label")); 615 | gtk_widget_show (glade_xml_get_widget (xml, "ternary_3B_entry")); 616 | gtk_label_set_text (GTK_LABEL (glade_xml_get_widget 617 | (xml, "ternary_1A_label")), "Red A"); 618 | gtk_label_set_text (GTK_LABEL (glade_xml_get_widget 619 | (xml, "ternary_1B_label")), "Red B"); 620 | gtk_label_set_text (GTK_LABEL (glade_xml_get_widget 621 | (xml, "ternary_2A_label")), "Green A"); 622 | gtk_label_set_text (GTK_LABEL (glade_xml_get_widget 623 | (xml, "ternary_2B_label")), "Green B"); 624 | snprintf (maxes[0], 19, "%g", scales[2]); 625 | snprintf (maxes[1], 19, "%g", scales[3]); 626 | snprintf (maxes[2], 19, "%g", scales[4]); 627 | snprintf (maxes[3], 19, "%g", scales[5]); 628 | snprintf (maxes[4], 19, "%g", scales[6]); 629 | snprintf (maxes[5], 19, "%g", scales[7]); 630 | gtk_entry_set_text (GTK_ENTRY (glade_xml_get_widget 631 | (xml, "ternary_1A_entry")), maxes[0]); 632 | gtk_entry_set_text (GTK_ENTRY (glade_xml_get_widget 633 | (xml, "ternary_1B_entry")), maxes[1]); 634 | gtk_entry_set_text (GTK_ENTRY (glade_xml_get_widget 635 | (xml, "ternary_2A_entry")), maxes[2]); 636 | gtk_entry_set_text (GTK_ENTRY (glade_xml_get_widget 637 | (xml, "ternary_2B_entry")), maxes[3]); 638 | gtk_entry_set_text (GTK_ENTRY (glade_xml_get_widget 639 | (xml, "ternary_3A_entry")), maxes[4]); 640 | gtk_entry_set_text (GTK_ENTRY (glade_xml_get_widget 641 | (xml, "ternary_3B_entry")), maxes[5]); 642 | 643 | ternary_disp = ternary_triangle_disp; 644 | } 645 | on_ternary_scale_area_expose_event 646 | (glade_xml_get_widget (xml, "ternary_scale_area"), NULL, NULL); 647 | } 648 | 649 | void on_vector_auto_checkbutton_toggled 650 | (GtkWidget *thebutton, gpointer user_data) 651 | { 652 | vector_auto_set = gtk_toggle_button_get_active 653 | (GTK_TOGGLE_BUTTON (thebutton)); 654 | if (vector_auto_set) 655 | { 656 | gtk_widget_set_sensitive 657 | (glade_xml_get_widget (xml, "vector_max_label"), FALSE); 658 | gtk_widget_set_sensitive 659 | (glade_xml_get_widget (xml, "vector_symm_label"), FALSE); 660 | gtk_widget_set_sensitive 661 | (glade_xml_get_widget (xml, "vector_max_entry"), FALSE); 662 | gtk_widget_set_sensitive 663 | (glade_xml_get_widget (xml, "vector_symm_spinbutton"), FALSE); 664 | } 665 | else 666 | { 667 | gtk_widget_set_sensitive 668 | (glade_xml_get_widget (xml, "vector_max_label"), TRUE); 669 | gtk_widget_set_sensitive 670 | (glade_xml_get_widget (xml, "vector_symm_label"), TRUE); 671 | gtk_widget_set_sensitive 672 | (glade_xml_get_widget (xml, "vector_max_entry"), TRUE); 673 | gtk_widget_set_sensitive 674 | (glade_xml_get_widget (xml, "vector_symm_spinbutton"), TRUE); 675 | } 676 | } 677 | 678 | void on_shear_auto_checkbutton_toggled 679 | (GtkWidget *thebutton, gpointer user_data) 680 | { 681 | shear_auto_set = gtk_toggle_button_get_active 682 | (GTK_TOGGLE_BUTTON (thebutton)); 683 | if (shear_auto_set) 684 | { 685 | gtk_widget_set_sensitive 686 | (glade_xml_get_widget (xml, "shear_max_label"), FALSE); 687 | gtk_widget_set_sensitive 688 | (glade_xml_get_widget (xml, "shear_max_entry"), FALSE); 689 | } 690 | else 691 | { 692 | gtk_widget_set_sensitive 693 | (glade_xml_get_widget (xml, "shear_max_label"), TRUE); 694 | gtk_widget_set_sensitive 695 | (glade_xml_get_widget (xml, "shear_max_entry"), TRUE); 696 | } 697 | } 698 | 699 | void on_scalar_min_entry_changed (GtkWidget *theentry, gpointer user_data) 700 | { G_CONST_RETURN gchar *entrytext = gtk_entry_get_text (GTK_ENTRY (theentry)); 701 | sscanf (entrytext, "%lf", scales); } 702 | 703 | void on_scalar_max_entry_changed (GtkWidget *theentry, gpointer user_data) 704 | { G_CONST_RETURN gchar *entrytext = gtk_entry_get_text (GTK_ENTRY (theentry)); 705 | sscanf (entrytext, "%lf", scales+1); } 706 | 707 | void on_ternary_1A_entry_changed (GtkWidget *theentry, gpointer user_data) 708 | { G_CONST_RETURN gchar *entrytext = gtk_entry_get_text (GTK_ENTRY (theentry)); 709 | sscanf (entrytext, "%lf", ternary_square_set ? scales+8 : scales+2); } 710 | 711 | void on_ternary_1B_entry_changed (GtkWidget *theentry, gpointer user_data) 712 | { G_CONST_RETURN gchar *entrytext = gtk_entry_get_text (GTK_ENTRY (theentry)); 713 | sscanf (entrytext, "%lf", ternary_square_set ? scales+9 : scales+3); } 714 | 715 | void on_ternary_2A_entry_changed (GtkWidget *theentry, gpointer user_data) 716 | { G_CONST_RETURN gchar *entrytext = gtk_entry_get_text (GTK_ENTRY (theentry)); 717 | sscanf (entrytext, "%lf", ternary_square_set ? scales+10 : scales+4); } 718 | 719 | void on_ternary_2B_entry_changed (GtkWidget *theentry, gpointer user_data) 720 | { G_CONST_RETURN gchar *entrytext = gtk_entry_get_text (GTK_ENTRY (theentry)); 721 | sscanf (entrytext, "%lf", ternary_square_set ? scales+11 : scales+5); } 722 | 723 | void on_ternary_3A_entry_changed (GtkWidget *theentry, gpointer user_data) 724 | { G_CONST_RETURN gchar *entrytext = gtk_entry_get_text (GTK_ENTRY (theentry)); 725 | sscanf (entrytext, "%lf", scales+6); } 726 | 727 | void on_ternary_3B_entry_changed (GtkWidget *theentry, gpointer user_data) 728 | { G_CONST_RETURN gchar *entrytext = gtk_entry_get_text (GTK_ENTRY (theentry)); 729 | sscanf (entrytext, "%lf", scales+7); } 730 | 731 | void on_ternary_dp_red_entry_changed (GtkWidget *theentry, gpointer user_data) 732 | { G_CONST_RETURN gchar *entrytext = gtk_entry_get_text (GTK_ENTRY (theentry)); 733 | sscanf (entrytext, "%lf", ternary_dp_color); } 734 | 735 | void on_ternary_dp_green_entry_changed(GtkWidget *theentry, gpointer user_data) 736 | { G_CONST_RETURN gchar *entrytext = gtk_entry_get_text (GTK_ENTRY (theentry)); 737 | sscanf (entrytext, "%lf", ternary_dp_color+1); } 738 | 739 | void on_ternary_dp_blue_entry_changed (GtkWidget *theentry, gpointer user_data) 740 | { G_CONST_RETURN gchar *entrytext = gtk_entry_get_text (GTK_ENTRY (theentry)); 741 | sscanf (entrytext, "%lf", ternary_dp_color+2); } 742 | 743 | void on_ternary_dp_alpha_entry_changed(GtkWidget *theentry, gpointer user_data) 744 | { G_CONST_RETURN gchar *entrytext = gtk_entry_get_text (GTK_ENTRY (theentry)); 745 | sscanf (entrytext, "%lf", ternary_dp_color+3); } 746 | 747 | void on_path_filename_entry_activate (GtkWidget *theentry, gpointer user) { 748 | G_CONST_RETURN gchar *entrytext = gtk_entry_get_text (GTK_ENTRY (theentry)); 749 | FILE *path_file; 750 | gchar linebuf[200]; 751 | int color=-1, point=0, point_array_size=0, ierr; 752 | DPRINTF ("Filename entered: %s\n", entrytext); 753 | 754 | if (!(path_file=fopen(entrytext, "r"))) { 755 | ierr=PetscPrintf (PETSC_COMM_WORLD, "Unable to open: %s\n", entrytext); 756 | CHKERRQ (ierr); 757 | return; } 758 | 759 | dp_supp_colors=0; 760 | while (fgets (linebuf, 199, path_file)) 761 | { 762 | if (linebuf[0] == 'c' || linebuf[0] == 'C') 763 | { 764 | /* Expand the color buffers */ 765 | dp_supp_colors++; 766 | dp_supp_color_points = realloc 767 | (dp_supp_color_points, dp_supp_colors*sizeof(int)); 768 | dp_supp_red = realloc 769 | (dp_supp_red, dp_supp_colors*sizeof(PetscScalar)); 770 | dp_supp_green = realloc 771 | (dp_supp_green, dp_supp_colors*sizeof(PetscScalar)); 772 | dp_supp_blue = realloc 773 | (dp_supp_blue, dp_supp_colors*sizeof(PetscScalar)); 774 | dp_supp_alpha = realloc 775 | (dp_supp_alpha, dp_supp_colors*sizeof(PetscScalar)); 776 | 777 | /* Properties of the new color entry */ 778 | color = dp_supp_colors-1; 779 | dp_supp_color_points [color] = 0; 780 | sscanf (linebuf, "%*s %lf %lf %lf %lf", dp_supp_red+color, 781 | dp_supp_green+color,dp_supp_blue+color,dp_supp_alpha+color); 782 | } 783 | if (((linebuf[0] >= '0' && linebuf[0] <= '9') || linebuf[0] == '.') && 784 | color > -1) 785 | { 786 | if (point >= point_array_size) 787 | dp_supp_AB = realloc 788 | (dp_supp_AB, 789 | (point_array_size=(point_array_size?point_array_size*2:100))* 790 | 2*sizeof(PetscScalar)); 791 | sscanf (linebuf, "%lf %lf", dp_supp_AB+2*point, 792 | dp_supp_AB+2*point+1); 793 | dp_supp_color_points[color]++; 794 | point++; 795 | } 796 | } 797 | fclose (path_file); 798 | 799 | #ifdef DEBUG 800 | ierr=PetscPrintf (PETSC_COMM_WORLD, "Loaded path supplement:\n"); 801 | CHKERRQ (ierr); 802 | for (color=0, point=0; color<dp_supp_colors; color++) 803 | { 804 | ierr=PetscPrintf (PETSC_COMM_WORLD, "%d: %d points, color %g %g %g %g\n", 805 | color, dp_supp_color_points[color], dp_supp_red[color], 806 | dp_supp_green[color], dp_supp_blue[color], 807 | dp_supp_alpha[color]); 808 | CHKERRQ (ierr); 809 | for (ierr=0; ierr<dp_supp_color_points[color]; ierr++, point++) 810 | PetscPrintf (PETSC_COMM_WORLD, " %g %g\n", dp_supp_AB [point*2], 811 | dp_supp_AB [point*2+1]); 812 | } 813 | #endif 814 | 815 | render_dataviews(); 816 | } 817 | 818 | void on_vector_max_entry_changed (GtkWidget *theentry, gpointer user_data) 819 | { G_CONST_RETURN gchar *entrytext = gtk_entry_get_text (GTK_ENTRY (theentry)); 820 | sscanf (entrytext, "%lf", scales+13); } 821 | 822 | void on_vector_symm_spinbutton_changed (GtkWidget *theentry,gpointer user_data) 823 | { int symmetry; 824 | G_CONST_RETURN gchar *entrytext = gtk_entry_get_text (GTK_ENTRY (theentry)); 825 | sscanf (entrytext, "%d", &symmetry); 826 | /* Because this sometimes sends events with outrageous symmetry numbers */ 827 | if (symmetry <= 10) { 828 | render_scale_2d (vector_disp, FIELD_VECTOR, symmetry); 829 | on_vector_scale_area_expose_event 830 | (glade_xml_get_widget (xml, "vector_scale_area"), NULL, user_data); }} 831 | 832 | void on_shear_max_entry_changed (GtkWidget *theentry, gpointer user_data) 833 | { G_CONST_RETURN gchar *entrytext = gtk_entry_get_text (GTK_ENTRY (theentry)); 834 | sscanf (entrytext, "%lf", scales+14); } 835 | 836 | void change_variable (GtkWidget *widget, gpointer user_data) 837 | { 838 | current_field = GPOINTER_TO_INT (widget); 839 | DPRINTF ("Switching to variable %d\n", current_field); 840 | gtk_notebook_set_current_page 841 | (GTK_NOTEBOOK (glade_xml_get_widget (xml, "scale_notebook")), 842 | fieldtypes [current_field] >> 4); 843 | render_dataviews(); 844 | } 845 | 846 | void on_mag_spin_value_changed (GtkWidget *mag_spin, gpointer user_data) { 847 | G_CONST_RETURN gchar *entrytext; 848 | entrytext = gtk_entry_get_text (GTK_ENTRY (mag_spin)); 849 | sscanf (entrytext, "%lf", &sizemag); 850 | width = (int) (minmax [1] * sizemag); 851 | height = (int) (minmax [3] * sizemag); 852 | 853 | if (width == 0) 854 | width = DEFAULT_RENDER_SIZE; 855 | if (height == 0) 856 | height = DEFAULT_RENDER_SIZE; 857 | 858 | render_dataviews(); 859 | } 860 | 861 | 862 | void display_timestep (int usermetacount, char **usermetanames, 863 | char **usermetadata) 864 | { 865 | int i; 866 | static char step_buffer [20], time_buffer [20]; 867 | 868 | for (i=0; i<usermetacount; i++) 869 | { 870 | if (!strncmp (usermetanames [i], "timestep", 8)) 871 | sscanf (usermetadata [i], "%d", ¤t_timestep); 872 | else if (!strncmp (usermetanames [i], "time", 4)) 873 | sscanf (usermetadata [i], "%lf", ¤t_time); 874 | } 875 | snprintf (step_buffer, 19, "Timestep: %d", current_timestep); 876 | gtk_label_set_text (GTK_LABEL (glade_xml_get_widget (xml, "timestep_label")), 877 | step_buffer); 878 | snprintf (time_buffer, 19, "Time: %g", current_time); 879 | gtk_label_set_text (GTK_LABEL (glade_xml_get_widget (xml, "time_label")), 880 | time_buffer); 881 | 882 | on_mag_spin_value_changed (glade_xml_get_widget (xml, "mag_spin"), NULL); 883 | } 884 | 885 | 886 | void on_save_activate (GtkWidget *widget, gpointer user_data) 887 | { 888 | int i, ierr; 889 | char filename [200], number[10]; 890 | 891 | strncpy (filename, basedirname, 198); 892 | strcat (filename, "/"); 893 | strncat (filename, stepnames [entrynum], 198 - strlen (filename)); 894 | snprintf (number, 9, "-f%d", current_field); 895 | strncat (filename, number, 198 - strlen (filename)); 896 | strncat (filename, ".ppm", 198 - strlen (filename)); 897 | 898 | DPRINTF ("Saving image with filename %s\n", filename); 899 | IDispWritePPM (Disp[0], filename); 900 | } 901 | 902 | 903 | void on_timestep_spin_value_changed (GtkWidget *timestep_spin, gpointer user_data) { 904 | int usermetacount, ierr; 905 | G_CONST_RETURN gchar *entrytext; 906 | char **usermetanames, **usermetadata, filename [200], **field_name; 907 | GtkWidget *variable_options, *variable_menu, **variable_item; 908 | 909 | entrytext = gtk_entry_get_text (GTK_ENTRY (timestep_spin)); 910 | sscanf (entrytext, "%d", &entrynum); 911 | 912 | /* Bound the entrynum between 0 and total_entries-1; -11 is the minimum of 913 | the widget (from jump), 1000001 is the maximum. */ 914 | if ((entrynum < 0 && entrynum != -11) || entrynum == 1000001) 915 | entrynum = total_entries-1; 916 | if ((entrynum >= total_entries && entrynum != 1000001) || entrynum == -11) 917 | entrynum = 0; 918 | gtk_spin_button_set_value (GTK_SPIN_BUTTON (timestep_spin), 919 | (gfloat) entrynum); 920 | 921 | strncpy (filename, basedirname, 198); 922 | strcat (filename, "/"); 923 | strncat (filename, stepnames [entrynum], 198 - strlen (filename)); 924 | 925 | ierr = IlluMultiRead (PETSC_COMM_WORLD, theda, global, filename, 926 | &usermetacount,&usermetanames, &usermetadata); 927 | CHKERRQ (ierr); 928 | 929 | display_timestep (usermetacount, usermetanames, usermetadata); 930 | } 931 | 932 | 933 | void on_transform_activate (GtkWidget *widget, gpointer user_data) 934 | { 935 | GtkWidget *timestep_spin = glade_xml_get_widget (xml, "timestep_spin"), 936 | *flip_horiz = glade_xml_get_widget (xml, "flip_horiz"), 937 | *flip_vertical = glade_xml_get_widget (xml, "flip_vertical"), 938 | *rotate_left = glade_xml_get_widget (xml, "rotate_left"); 939 | 940 | transform = 941 | (gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (flip_horiz)) ? 942 | FLIP_HORIZONTAL : 0) | 943 | (gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (flip_vertical)) ? 944 | FLIP_VERTICAL : 0) | 945 | (gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (rotate_left)) ? 946 | ROTATE_LEFT : 0); 947 | 948 | render_dataviews (); 949 | } 950 | 951 | 952 | void on_save_all_activate (GtkWidget *none, gpointer user_data) { 953 | GtkWidget *timestep_spin = glade_xml_get_widget (xml, "timestep_spin"); 954 | int i, temp = entrynum; 955 | 956 | for (i=0; i<total_entries; i++) 957 | { 958 | gchar appbar_message [30]; 959 | gtk_spin_button_set_value (GTK_SPIN_BUTTON (timestep_spin), (gfloat) i); 960 | on_timestep_spin_value_changed (timestep_spin, user_data); 961 | 962 | sprintf (appbar_message, "Saving image %d/%d", i+1, total_entries); 963 | gnome_appbar_set_status 964 | (GNOME_APPBAR (glade_xml_get_widget (xml, "main_appbar")), 965 | appbar_message); 966 | gnome_appbar_set_progress_percentage 967 | (GNOME_APPBAR (glade_xml_get_widget (xml, "main_appbar")), 968 | (gfloat) (i+1)/total_entries); 969 | while (gtk_events_pending ()) 970 | gtk_main_iteration (); 971 | 972 | on_save_activate (timestep_spin, user_data); 973 | } 974 | 975 | gnome_appbar_set_progress_percentage 976 | (GNOME_APPBAR (glade_xml_get_widget (xml, "main_appbar")), 0.); 977 | gnome_appbar_refresh (GNOME_APPBAR(glade_xml_get_widget(xml,"main_appbar"))); 978 | gtk_spin_button_set_value (GTK_SPIN_BUTTON (timestep_spin), (gfloat) temp); 979 | on_timestep_spin_value_changed (timestep_spin, user_data); 980 | } 981 | 982 | 983 | void on_save_all_scale_activate (GtkWidget *none, gpointer user_data) { 984 | GtkWidget *timestep_spin = glade_xml_get_widget (xml, "timestep_spin"); 985 | int i,j, ierr, temp = entrynum; 986 | char filename [200], number [10]; 987 | IDisplay scale_image; 988 | 989 | if (!(scale_image = 990 | (fieldtypes [current_field] == FIELD_SCALAR) ? scalar_disp : 991 | ((fieldtypes [current_field] == FIELD_VECTOR) ? vector_disp : 992 | ((fieldtypes [current_field] == FIELD_TENSOR_SHEAR) ? shear_disp : 993 | ((fieldtypes [current_field] == FIELD_TERNARY_SQUARE || 994 | fieldtypes [current_field] == FIELD_TERNARY) ? ternary_disp : 995 | NULL))))) 996 | return; 997 | 998 | for (i=0; i<total_entries; i++) 999 | { 1000 | gchar appbar_message [30]; 1001 | gtk_spin_button_set_value (GTK_SPIN_BUTTON (timestep_spin), (gfloat) i); 1002 | on_timestep_spin_value_changed (timestep_spin, user_data); 1003 | 1004 | sprintf (appbar_message, "Saving image %d/%d", i+1, total_entries); 1005 | gnome_appbar_set_status 1006 | (GNOME_APPBAR (glade_xml_get_widget (xml, "main_appbar")), 1007 | appbar_message); 1008 | gnome_appbar_set_progress_percentage 1009 | (GNOME_APPBAR (glade_xml_get_widget (xml, "main_appbar")), 1010 | (gfloat) (i+1)/total_entries); 1011 | while (gtk_events_pending ()) 1012 | gtk_main_iteration (); 1013 | 1014 | strncpy (filename, basedirname, 198); 1015 | strcat (filename, "/"); 1016 | strncat (filename, stepnames [entrynum], 198 - strlen (filename)); 1017 | snprintf (number, 9, "-s%d", current_field); 1018 | strncat (filename, number, 198 - strlen (filename)); 1019 | strncat (filename, ".ppm", 198 - strlen (filename)); 1020 | 1021 | DPRINTF ("Saving image with filename %s\n", filename); 1022 | IDispWritePPM (scale_image, filename); 1023 | } 1024 | 1025 | gnome_appbar_set_progress_percentage 1026 | (GNOME_APPBAR (glade_xml_get_widget (xml, "main_appbar")), 0.); 1027 | gnome_appbar_refresh (GNOME_APPBAR(glade_xml_get_widget(xml,"main_appbar"))); 1028 | gtk_spin_button_set_value (GTK_SPIN_BUTTON (timestep_spin), (gfloat) temp); 1029 | on_timestep_spin_value_changed (timestep_spin, user_data); 1030 | } 1031 | 1032 | 1033 | void on_refresh_activate (GtkWidget *none, gpointer user_data) { 1034 | if (refresh_stepnames ()) exit (1); } 1035 | 1036 | 1037 | /*++++++++++++++++++++++++++++++++++++++ 1038 | This reloads the .log file. 1039 | 1040 | GtkWidget *none Empty GtkWidget (unusable because it's a menu item). 1041 | 1042 | gpointer user_data Empty pointer. 1043 | ++++++++++++++++++++++++++++++++++++++*/ 1044 | 1045 | void on_log_reload_button_clicked (GtkWidget *none, gpointer user_data) 1046 | { 1047 | FILE *run_log; 1048 | unsigned char run_log_filename [300], run_log_buffer [300]; 1049 | int log_size=0, nextchar=0; 1050 | 1051 | strcpy ((char *) run_log_buffer, "Loading new log info"); 1052 | gtk_label_set_text (GTK_LABEL (glade_xml_get_widget (xml, "log_text_label")), 1053 | (char *) run_log_buffer); 1054 | 1055 | strncpy ((char *) run_log_filename, the_basename, 298-strlen(".log")); 1056 | strcat ((char *) run_log_filename, ".log"); 1057 | DPRINTF ("Loading log file %s\n", run_log_filename); 1058 | if (!(run_log = fopen ((char *) run_log_filename, "r"))) 1059 | { 1060 | printf ("Can't find log file %s\n", run_log_filename); 1061 | return; 1062 | } 1063 | 1064 | /* There's probably a MUCH better way to slurp a file into a string... */ 1065 | while (nextchar != EOF) 1066 | { 1067 | int i,j; 1068 | for (i=0; i<300 && nextchar != EOF; i++) 1069 | run_log_buffer[i] = nextchar = fgetc (run_log); 1070 | log_text = (char *) realloc 1071 | (log_text, (log_size += i) * sizeof (char)); 1072 | for (j=0; j<i; j++) 1073 | log_text [log_size-i+j] = run_log_buffer [j]; 1074 | } 1075 | log_text [log_size-1] = '\0'; 1076 | fclose (run_log); 1077 | gtk_label_set_text (GTK_LABEL (glade_xml_get_widget (xml, "log_text_label")), 1078 | log_text); 1079 | } 1080 | 1081 | 1082 | void on_run_log_activate (GtkWidget *none, gpointer user_data) { 1083 | if (!log_text) 1084 | on_log_reload_button_clicked (none, user_data); 1085 | gtk_widget_show (glade_xml_get_widget (xml, "log_window")); } 1086 | 1087 | 1088 | void on_about_activate (GtkWidget *none, gpointer user_data) { 1089 | gtk_widget_show (glade_xml_get_widget (xml, "about")); } 1090 | 1091 | 1092 | #undef __FUNCT__ 1093 | #define __FUNCT__ "main" 1094 | 1095 | /*++++++++++++++++++++++++++++++++++++++ 1096 | This is 1097 | +latex+{\tt main()}. 1098 | +html+ <tt>main()</tt>. 1099 | 1100 | int main It returns an int to the OS. 1101 | 1102 | int argc Argument count. 1103 | 1104 | char *argv[] Arguments. 1105 | ++++++++++++++++++++++++++++++++++++++*/ 1106 | 1107 | int main (int argc, char *argv[]) 1108 | { 1109 | int usermetacount=0, i, ierr; 1110 | char **usermetanames, **usermetadata, filename [200], **field_name; 1111 | GtkWidget *variable_options, *variable_menu, **variable_item; 1112 | 1113 | /*+ After 1114 | +latex+{\tt PETSc} 1115 | +html+ <tt>PETSc</tt> 1116 | and glade/GNOME initialization, it gets the list of files matching the 1117 | basename. +*/ 1118 | ierr = PetscInitialize (&argc, &argv, (char *)0, help); CHKERRQ (ierr); 1119 | 1120 | if (argc<2) 1121 | { 1122 | ierr = PetscPrintf (PETSC_COMM_WORLD, "Usage: tsview basename\n"); 1123 | CHKERRQ (ierr); 1124 | return 1; 1125 | } 1126 | 1127 | #ifdef DEBUG 1128 | ierr = PetscPrintf (PETSC_COMM_WORLD, "Command line:"); CHKERRQ (ierr); 1129 | for (i=0; i<argc; i++) 1130 | { 1131 | ierr = PetscPrintf (PETSC_COMM_WORLD, " %s", argv[i]); CHKERRQ (ierr); 1132 | } 1133 | ierr = PetscPrintf (PETSC_COMM_WORLD, "\n"); CHKERRQ (ierr); 1134 | #endif 1135 | 1136 | /* Initial settings */ 1137 | ierr = PetscOptionsHasName (PETSC_NULL, "-no_transparency", &transp); 1138 | CHKERRQ (ierr); 1139 | transp = !transp; 1140 | Surf = NULL; 1141 | transform = 0; 1142 | 1143 | /* Kludge alert! Setting argc to avoid gnome_program_init errors; 1144 | fix: use GNOME arguments instead of PETSc. */ 1145 | argc=2; 1146 | 1147 | DPRINTF ("Running gnome_program_init with argc=%d\n", argc); 1148 | gnome_program_init ("TSView", VERSION, LIBGNOMEUI_MODULE, argc, argv, NULL); 1149 | 1150 | strncpy (filename, GLADE_DIRECTORY, 187); 1151 | strcat (filename, "/tsview.glade"); 1152 | DPRINTF ("Loading Glade file %s\n", filename); 1153 | xml = glade_xml_new (filename, NULL, NULL); 1154 | glade_xml_signal_autoconnect (xml); 1155 | 1156 | if (argc>1) 1157 | the_basename = argv[1]; 1158 | else 1159 | { 1160 | /* Put in filter for .time0000000.cpu0000.meta */ 1161 | gtk_widget_show (glade_xml_get_widget (xml, "open_fileselect")); 1162 | } 1163 | 1164 | DPRINTF ("Loading list of timestep names\n",0); 1165 | if (refresh_stepnames ()) 1166 | { 1167 | ierr = PetscFinalize (); CHKERRQ(ierr); 1168 | exit (1); 1169 | } 1170 | 1171 | DPRINTF ("Loading first timestep, creating distributed array\n",0); 1172 | strncpy (filename, basedirname, 198); 1173 | strcat (filename, "/"); 1174 | strncat (filename, stepnames [0], 198 - strlen (stepnames [0])); 1175 | ierr = IlluMultiLoad 1176 | (PETSC_COMM_WORLD, filename, &theda, minmax+1,minmax+3,minmax+5, 1177 | &fieldtypes, &usermetacount, &usermetanames, &usermetadata); 1178 | CHKERRQ (ierr); 1179 | 1180 | /* Usermetadata xwidth, ywidth, zwidth override minmax in case IlluMulti 1181 | version of saved data is 0.1. */ 1182 | DPRINTF ("Checking usermetadata for width information\n",0); 1183 | for (i=0; i<usermetacount; i++) 1184 | { 1185 | if (!strncmp (usermetanames [i], "xwidth", 6)) 1186 | sscanf (usermetadata [i], "%lf", minmax+1); 1187 | else if (!strncmp (usermetanames [i], "ywidth", 6)) 1188 | sscanf (usermetadata [i], "%lf", minmax+3); 1189 | else if (!strncmp (usermetanames [i], "zwidth", 6)) 1190 | sscanf (usermetadata [i], "%lf", minmax+5); 1191 | } 1192 | 1193 | DPRINTF ("Getting distributed array global vector and info\n",0); 1194 | ierr = DAGetGlobalVector (theda, &global); CHKERRQ (ierr); 1195 | ierr = DAGetInfo (theda, &dimensions, PETSC_NULL,PETSC_NULL,PETSC_NULL, 1196 | PETSC_NULL,PETSC_NULL,PETSC_NULL, &num_fields, 1197 | PETSC_NULL,PETSC_NULL,PETSC_NULL); CHKERRQ (ierr); 1198 | if (dimensions == 1) 1199 | SETERRQ (PETSC_ERR_ARG_OUTOFRANGE, "tsview-ng only supports 2-D or 3-D distributed arrays.") 1200 | else if (dimensions == 2) 1201 | bpp = 3; 1202 | else 1203 | { 1204 | bpp = 4; 1205 | gtk_widget_hide (glade_xml_get_widget (xml, "flip_horiz")); 1206 | gtk_widget_hide (glade_xml_get_widget (xml, "flip_vertical")); 1207 | gtk_widget_hide (glade_xml_get_widget (xml, "rotate_left")); 1208 | } 1209 | 1210 | /* Build menu of field variables */ 1211 | variable_options = glade_xml_get_widget (xml, "variable_menu"); 1212 | gtk_option_menu_remove_menu (GTK_OPTION_MENU (variable_options)); 1213 | variable_menu = gtk_menu_new (); 1214 | variable_item = (GtkWidget **) malloc (num_fields * sizeof (GtkWidget *)); 1215 | field_name = (char **) malloc (num_fields * sizeof (char *)); 1216 | field_index = (int *) malloc (num_fields * sizeof (int)); 1217 | /* For now, use scalar plots for all types in 3-D */ 1218 | if (dimensions == 2) 1219 | field_indices (num_fields, dimensions, fieldtypes, field_index); 1220 | else 1221 | for (i=0; i<num_fields; i++) 1222 | field_index[i] = i; 1223 | DPRINTF ("Field indices:\n",0); 1224 | for (i=0; i<num_fields && field_index [i] != -1; i++) 1225 | { 1226 | ierr = DAGetFieldName (theda, field_index [i], field_name+i); 1227 | CHKERRQ (ierr); 1228 | DPRINTF ("%d index %d name %s\n", i, field_index [i], field_name [i]); 1229 | variable_item [i] = gtk_menu_item_new_with_label (field_name [i]); 1230 | gtk_menu_append (GTK_MENU (variable_menu), variable_item [i]); 1231 | gtk_signal_connect_object (GTK_OBJECT (variable_item [i]), "activate", 1232 | GTK_SIGNAL_FUNC (change_variable), 1233 | GINT_TO_POINTER (field_index [i])); 1234 | gtk_widget_show (variable_item [i]); 1235 | } 1236 | gtk_option_menu_set_menu (GTK_OPTION_MENU (variable_options), variable_menu); 1237 | gtk_widget_show (variable_menu); 1238 | gtk_widget_show (variable_options); 1239 | 1240 | /* Scale images */ 1241 | IDispCreate (&scalar_disp, SCALE_WIDTH,SCALE_HEIGHT,SCALE_WIDTH,SCALE_BPP,0); 1242 | IDispCreate (&vector_disp, SCALE_WIDTH,SCALE_HEIGHT,SCALE_WIDTH,SCALE_BPP,0); 1243 | IDispCreate (&shear_disp, SCALE_WIDTH,SCALE_HEIGHT,SCALE_WIDTH,SCALE_BPP,0); 1244 | IDispCreate (&ternary_triangle_disp, SCALE_WIDTH, SCALE_HEIGHT, SCALE_WIDTH, 1245 | SCALE_BPP, 0); 1246 | IDispCreate (&ternary_square_disp, SCALE_WIDTH, SCALE_HEIGHT, SCALE_WIDTH, 1247 | SCALE_BPP, 0); 1248 | ternary_disp = ternary_triangle_disp; 1249 | render_scale_2d (scalar_disp, FIELD_SCALAR, 1); 1250 | render_scale_2d (vector_disp, FIELD_VECTOR, 1); 1251 | render_scale_2d (shear_disp, FIELD_TENSOR_SHEAR, 1); 1252 | 1253 | gtk_notebook_set_current_page 1254 | (GTK_NOTEBOOK (glade_xml_get_widget (xml, "scale_notebook")), 1255 | fieldtypes [0] >> 4); 1256 | 1257 | /* Main window title */ 1258 | { 1259 | char main_window_title[100] = "TSView: "; 1260 | GtkWidget *main_window = glade_xml_get_widget (xml, "main_window"); 1261 | 1262 | strncat (main_window_title, basename (the_basename), 90); 1263 | gtk_window_set_title (GTK_WINDOW (main_window), main_window_title); 1264 | gtk_widget_show (main_window); 1265 | } 1266 | 1267 | /* Set initial magnification */ 1268 | sizemag = DEFAULT_RENDER_SIZE/PetscMax(minmax[1],minmax[3]); 1269 | DPRINTF ("Max dimension is %g, setting magnification to %g\n", 1270 | PetscMax(minmax[1],minmax[3]), sizemag); 1271 | gtk_spin_button_set_value 1272 | (GTK_SPIN_BUTTON (glade_xml_get_widget (xml, "mag_spin")), sizemag); 1273 | 1274 | DPRINTF ("Displaying first timestep\n",0); 1275 | display_timestep (usermetacount, usermetanames, usermetadata); 1276 | 1277 | DPRINTF ("Running main loop\n",0); 1278 | gtk_main(); 1279 | 1280 | DPRINTF ("Finalizing and exiting.\n",0); 1281 | if (Surf) { 1282 | ierr = ISurfDestroy (Surf); CHKERRQ (ierr); } 1283 | if (Disp[0]) { 1284 | ierr = IDispDestroy (Disp[0]); CHKERRQ (ierr); } 1285 | ierr = PetscFinalize (); CHKERRQ(ierr); 1286 | return 0; 1287 | }