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