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 | }