1 /*****************************************************************************/
4 /* 8888 888o^88, o88^^o Y88b o / d8b d8b o88^^8o */
5 /* "Y88b 888 888 d888 b Y88b d8b / d888bdY88b d888 88b */
6 /* "Y88b, 888 888 8888 8 Y888/Y88b/ / Y88Y Y888b 8888oo888 */
7 /* o 8888 888 888 q888 p Y8/ Y8/ / YY Y888b q888 */
8 /* "oo88P" 888 888 "88oo" Y Y / Y888b "88oooo" */
10 /* A Display Program for Meshes and More. */
17 /* Jonathan Richard Shewchuk */
18 /* School of Computer Science */
19 /* Carnegie Mellon University */
20 /* 5000 Forbes Avenue */
21 /* Pittsburgh, Pennsylvania 15213-3891 */
24 /* This program may be freely redistributed under the condition that the */
25 /* copyright notices (including this entire header and the copyright */
26 /* notice printed when the `-h' switch is selected) are not removed, and */
27 /* no compensation is received. Private, research, and institutional */
28 /* use is free. You may distribute modified versions of this code UNDER */
29 /* THE CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE TO IT IN THE */
30 /* SAME FILE REMAIN UNDER COPYRIGHT OF THE ORIGINAL AUTHOR, BOTH SOURCE */
31 /* AND OBJECT CODE ARE MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR */
32 /* NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution of this code as */
33 /* part of a commercial system is permissible ONLY BY DIRECT ARRANGEMENT */
34 /* WITH THE AUTHOR. (If you are not directly supplying this code to a */
35 /* customer, and you are instead telling them how they can obtain it for */
36 /* free, then you are not required to make any arrangement with me.) */
38 /* Hypertext instructions for Triangle are available on the Web at */
40 /* http://www.cs.cmu.edu/~quake/showme.html */
42 /* Show Me was created as part of the Archimedes project in the School of */
43 /* Computer Science at Carnegie Mellon University. Archimedes is a */
44 /* system for compiling parallel finite element solvers. For further */
45 /* information, see Anja Feldmann, Omar Ghattas, John R. Gilbert, Gary L. */
46 /* Miller, David R. O'Hallaron, Eric J. Schwabe, Jonathan R. Shewchuk, */
47 /* and Shang-Hua Teng. "Automated Parallel Solution of Unstructured PDE */
48 /* Problems." To appear in Communications of the ACM, we hope. */
50 /* If you make any improvements to this code, please please please let me */
51 /* know, so that I may obtain the improvements. Even if you don't change */
52 /* the code, I'd still love to hear what it's being used for. */
54 /* Disclaimer: Neither I nor Carnegie Mellon warrant this code in any way */
55 /* whatsoever. Use at your own risk. */
57 /*****************************************************************************/
59 /* For single precision (which will save some memory and reduce paging), */
60 /* write "#define SINGLE" below. */
62 /* For double precision (which will allow you to display triangulations of */
63 /* a finer resolution), leave SINGLE undefined. */
73 /* Maximum number of characters in a file name (including the null). */
75 #define FILENAMESIZE 1024
77 /* Maximum number of characters in a line read from a file (including the */
80 #define INPUTLINESIZE 512
82 #define STARTWIDTH 414
83 #define STARTHEIGHT 414
86 #define BUTTONHEIGHT 21
88 #define PANELHEIGHT (BUTTONHEIGHT * BUTTONROWS)
101 #define STARTEXPLOSION 0.5
105 #include <X11/Xlib.h>
106 #include <X11/Xutil.h>
107 #include <X11/Xatom.h>
109 /* The following obscenity seems to be necessary to ensure that this program */
110 /* will port to Dec Alphas running OSF/1, because their stdio.h file commits */
111 /* the unpardonable sin of including stdlib.h. Hence, malloc(), free(), and */
112 /* exit() may or may not already be defined at this point. I declare these */
113 /* functions explicitly because some non-ANSI C compilers lack stdlib.h. */
116 extern char *malloc();
119 extern double strtod();
120 extern long strtol();
123 /* A necessary forward declaration. */
143 Window widthminuswin;
144 Window versionpluswin;
145 Window versionminuswin;
153 Window voronoiwin[2];
161 int showme_foreground;
166 int colors[MAXCOLORS];
167 XColor rgb[MAXCOLORS];
170 int start_image, current_image;
171 int start_inc, current_inc;
174 int loaded[2][IMAGE_TYPES];
175 REAL xlo[2][IMAGE_TYPES], ylo[2][IMAGE_TYPES];
176 REAL xhi[2][IMAGE_TYPES], yhi[2][IMAGE_TYPES];
178 REAL xoffset, yoffset;
181 int nodes[2], node_dim[2];
183 int polynodes[2], poly_dim[2], polyedges[2], polyholes[2];
184 REAL *polynodeptr[2], *polyholeptr[2];
186 int elems[2], ele_corners[2];
193 REAL *partcenter[2], *partshift[2];
194 int adjsubdomains[2];
196 int vnodes[2], vnode_dim[2];
203 int quiet, fillelem, bw_ps, explode;
206 char filename[FILENAMESIZE];
207 char nodefilename[2][FILENAMESIZE];
208 char polyfilename[2][FILENAMESIZE];
209 char elefilename[2][FILENAMESIZE];
210 char edgefilename[2][FILENAMESIZE];
211 char partfilename[2][FILENAMESIZE];
212 char adjfilename[2][FILENAMESIZE];
213 char vnodefilename[2][FILENAMESIZE];
214 char vedgefilename[2][FILENAMESIZE];
216 char *colorname[] = {"aquamarine", "red", "green yellow", "magenta",
217 "yellow", "green", "orange", "blue",
218 "white", "sandy brown", "cyan", "moccasin",
219 "cadet blue", "coral", "cornflower blue", "sky blue",
220 "firebrick", "forest green", "gold", "goldenrod",
221 "gray", "hot pink", "chartreuse", "pale violet red",
222 "indian red", "khaki", "lavender", "light blue",
223 "light gray", "light steel blue", "lime green", "azure",
224 "maroon", "medium aquamarine", "dodger blue", "honeydew",
225 "medium orchid", "medium sea green", "moccasin",
226 "medium slate blue", "medium spring green",
227 "medium turquoise", "medium violet red",
228 "orange red", "chocolate", "light goldenrod",
229 "orchid", "pale green", "pink", "plum",
230 "purple", "salmon", "sea green",
231 "sienna", "slate blue", "spring green",
232 "steel blue", "tan", "thistle", "turquoise",
233 "violet", "violet red", "wheat",
238 printf("showme [-bfw_Qh] input_file\n");
239 printf(" -b Black and white PostScript (default is color).\n");
240 printf(" -f Fill triangles of partitioned mesh with color.\n");
241 printf(" -w Set line width to some specified number.\n");
242 printf(" -Q Quiet: No terminal output except errors.\n");
243 printf(" -h Help: Detailed instructions for Show Me.\n");
250 printf("A Display Program for Meshes and More.\n");
251 printf("Version 1.3\n\n");
253 "Copyright 1996 Jonathan Richard Shewchuk (bugs/comments to jrs@cs.cmu.edu)\n"
255 printf("School of Computer Science / Carnegie Mellon University\n");
256 printf("5000 Forbes Avenue / Pittsburgh, Pennsylvania 15213-3891\n");
258 "Created as part of the Archimedes project (tools for parallel FEM).\n");
260 "Supported in part by NSF Grant CMS-9318163 and an NSERC 1967 Scholarship.\n");
261 printf("There is no warranty whatsoever. Use at your own risk.\n");
263 printf("This executable is compiled for single precision arithmetic.\n\n\n");
265 printf("This executable is compiled for double precision arithmetic.\n\n\n");
268 "Show Me graphically displays the contents of geometric files, especially\n");
270 "those generated by Triangle, my two-dimensional quality mesh generator and\n"
273 "Delaunay triangulator. Show Me can also write images in PostScript form.\n");
275 "Show Me is also useful for checking the consistency of the files you create\n"
278 "as input to Triangle; Show Me does these checks more thoroughly than\n");
279 printf("Triangle does. The command syntax is:\n\n");
280 printf("showme [-bfw_Qh] input_file\n\n");
282 "The underscore indicates that a number should follow the -w switch.\n");
284 "input_file may be one of several types of file. It must have extension\n");
286 ".node, .poly, .ele, .edge, .part, or .adj. If no extension is provided,\n");
288 "Show Me will assume the extension .ele. A .node file represents a set of\n");
290 "points; a .poly file represents a Planar Straight Line Graph; an .ele file\n"
293 "(coupled with a .node file) represents the elements of a mesh or the\n");
295 "triangles of a triangulation; an .edge file (coupled with a .node file)\n");
297 "represents a set of edges; a .part file specifies a partition of a mesh;\n");
299 "and a .adj file represents the adjacency graph defined by a partition.\n");
301 printf("Command Line Switches:\n");
304 " -b Makes all PostScript output black and white. If this switch is not\n"
307 " selected, color PostScript is used for partitioned meshes and\n");
308 printf(" adjacency graphs (.part and .adj files).\n");
310 " -f On color displays and in color PostScript, displays partitioned\n");
312 " meshes by filling triangles with color, rather than by coloring the\n"
315 " edges. This switch will result in a clearer picture if all\n");
317 " triangles are reasonably large, and a less clear picture if small\n");
319 " triangles are present. (There is also a button to toggle this\n");
320 printf(" behavior.)\n");
322 " -w Followed by an integer, specifies the line width used in all\n");
324 " images. (There are also buttons to change the line width.)\n");
326 " -Q Quiet: Suppresses all explanation of what Show Me is doing, unless\n"
328 printf(" an error occurs.\n");
329 printf(" -h Help: Displays these instructions.\n");
331 printf("Controls:\n");
334 " To zoom in on an image, point at the location where you want a closer\n");
336 " look, and click the left mouse button. To zoom out, click the right\n");
338 " mouse button. In either case, the point you click on will be centered in\n"
341 " the window. If you want to know the coordinates of a point, click the\n");
343 " middle mouse button; the coordinates will be printed on the terminal you\n"
345 printf(" invoked Show Me from.\n\n");
347 " If you resize the window, the image will grow or shrink to match.\n");
350 " There is a panel of control buttons at the bottom of the Show Me window:\n"
353 printf(" Quit: Shuts down Show Me.\n");
354 printf(" <, >, ^, v: Moves the image in the indicated direction.\n");
356 " Reset: Unzooms and centers the image in the window. When you switch from\n"
359 " one image to another, the viewing region does not change, so you may\n");
361 " need to reset the new image to make it fully visible. This often is\n");
363 " the case when switching between Delaunay triangulations and their\n");
365 " corresponding Voronoi diagrams, as Voronoi vertices can be far from the\n"
367 printf(" initial point set.\n");
369 " Width+, -: Increases or decreases the width of all lines and points.\n");
371 " Exp, +, -: These buttons appear only when you are viewing a partitioned\n"
374 " mesh (.part file). `Exp' toggles between an exploded and non-exploded\n"
377 " image of the mesh. The non-exploded image will not show the partition\n"
380 " on a black and white monitor. `+' and `-' allow you to adjust the\n");
382 " spacing between pieces of the mesh to better distinguish them.\n");
384 " Fill: This button appears only when you are viewing a partitioned mesh\n");
386 " (.part file). It toggles between color-filled triangles and colored\n");
388 " edges (as the -f switch does). Filled triangles look better when all\n");
390 " triangles are reasonably large; colored edges look better when there\n");
391 printf(" are very small triangles present.\n");
393 " PS: Creates a PostScript file containing the image you are viewing. If\n"
396 " the -b switch is selected, all PostScript output will be black and\n");
398 " white; otherwise, .part.ps and .adj.ps files will be color, independent\n"
401 " of whether you are using a color monitor. Normally the output will\n");
403 " preserve the properties of the image you see on the screen, including\n");
405 " zoom and line width; however, if black and white output is selected (-b\n"
408 " switch), partitioned meshes will always be drawn exploded. The output\n"
411 " file name depends on the image being viewed. If you want several\n");
413 " different snapshots (zooming in on different parts) of the same object,\n"
416 " you'll have to rename each file after Show Me creates it so that it\n");
417 printf(" isn't overwritten by the next snapshot.\n");
419 " EPS: Creates an encapsulated PostScript file, suitable for inclusion in\n"
422 " documents. Otherwise, this button is just like the PS button. (The\n");
424 " main difference is that .eps files lack a `showpage' command at the\n");
425 printf(" end.)\n\n");
427 " There are two nearly-identical rows of buttons that load different images\n"
429 printf(" from disk. Each row contains the following buttons:\n\n");
430 printf(" node: Loads a .node file.\n");
432 " poly: Loads a .poly file (and possibly an associated .node file).\n");
433 printf(" ele: Loads an .ele file (and associated .node file).\n");
434 printf(" edge: Loads an .edge file (and associated .node file).\n");
436 " part: Loads a .part file (and associated .node and .ele files).\n");
438 " adj: Loads an .adj file (and associated .node, .ele, and .part files).\n");
439 printf(" voro: Loads a .v.node and .v.edge file for a Voronoi diagram.\n");
442 " Each row represents a different iteration number of the geometry files.\n");
444 " For a full explanation of iteration numbers, read the instructions for\n");
446 " Triangle. Briefly, iteration numbers are used to allow a user to easily\n"
449 " represent a sequence of related triangulations. Iteration numbers are\n");
451 " used in the names of geometry files; for instance, mymesh.3.ele is a\n");
453 " triangle file with iteration number three, and mymesh.ele has an implicit\n"
455 printf(" iteration number of zero.\n\n");
457 " The control buttons at the right end of each row display the two\n");
459 " iterations currently under view. These buttons can be clicked to\n");
461 " increase or decrease the iteration numbers, and thus conveniently view\n");
462 printf(" a sequence of meshes.\n\n");
464 " Show Me keeps each file in memory after loading it, but you can force\n");
466 " Show Me to reread a set of files (for one iteration number) by reclicking\n"
469 " the button that corresponds to the current image. This is convenient if\n"
471 printf(" you have changed a geometry file.\n\n");
472 printf("File Formats:\n\n");
474 " All files may contain comments prefixed by the character '#'. Points,\n");
476 " segments, holes, triangles, edges, and subdomains must be numbered\n");
478 " consecutively, starting from either 1 or 0. Whichever you choose, all\n");
480 " input files must be consistent (for any single iteration number); if the\n"
483 " nodes are numbered from 1, so must be all other objects. Show Me\n");
485 " automatically detects your choice while reading a .node (or .poly) file.\n"
487 printf(" Examples of these file formats are given below.\n\n");
488 printf(" .node files:\n");
490 " First line: <# of points> <dimension (must be 2)> <# of attributes>\n");
492 " <# of boundary markers (0 or 1)>\n"
495 " Remaining lines: <point #> <x> <y> [attributes] [boundary marker]\n");
498 " The attributes, which are typically floating-point values of physical\n");
500 " quantities (such as mass or conductivity) associated with the nodes of\n"
503 " a finite element mesh, are ignored by Show Me. Show Me also ignores\n");
505 " boundary markers. See the instructions for Triangle to find out what\n");
506 printf(" attributes and boundary markers are.\n\n");
507 printf(" .poly files:\n");
509 " First line: <# of points> <dimension (must be 2)> <# of attributes>\n");
511 " <# of boundary markers (0 or 1)>\n"
514 " Following lines: <point #> <x> <y> [attributes] [boundary marker]\n");
515 printf(" One line: <# of segments> <# of boundary markers (0 or 1)>\n");
517 " Following lines: <segment #> <endpoint> <endpoint> [boundary marker]\n");
518 printf(" One line: <# of holes>\n");
519 printf(" Following lines: <hole #> <x> <y>\n");
520 printf(" [Optional additional lines that are ignored]\n\n");
522 " A .poly file represents a Planar Straight Line Graph (PSLG), an idea\n");
524 " familiar to computational geometers. By definition, a PSLG is just a\n");
526 " list of points and edges. A .poly file also contains some additional\n");
527 printf(" information.\n\n");
529 " The first section lists all the points, and is identical to the format\n"
532 " of .node files. <# of points> may be set to zero to indicate that the\n"
535 " points are listed in a separate .node file; .poly files produced by\n");
537 " Triangle always have this format. When Show Me reads such a file, it\n");
538 printf(" also reads the corresponding .node file.\n\n");
540 " The second section lists the segments. Segments are edges whose\n");
542 " presence in a triangulation produced from the PSLG is enforced. Each\n");
544 " segment is specified by listing the indices of its two endpoints. This\n"
547 " means that its endpoints must be included in the point list. Each\n");
549 " segment, like each point, may have a boundary marker, which is ignored\n"
551 printf(" by Show Me.\n\n");
553 " The third section lists holes and concavities that are desired in any\n");
555 " triangulation generated from the PSLG. Holes are specified by\n");
556 printf(" identifying a point inside each hole.\n\n");
557 printf(" .ele files:\n");
559 " First line: <# of triangles> <points per triangle> <# of attributes>\n");
561 " Remaining lines: <triangle #> <point> <point> <point> ... [attributes]\n"
565 " Points are indices into the corresponding .node file. Show Me ignores\n"
568 " all but the first three points of each triangle; these should be the\n");
570 " corners listed in counterclockwise order around the triangle. The\n");
571 printf(" attributes are ignored by Show Me.\n\n");
572 printf(" .edge files:\n");
573 printf(" First line: <# of edges> <# of boundary markers (0 or 1)>\n");
575 " Following lines: <edge #> <endpoint> <endpoint> [boundary marker]\n");
578 " Endpoints are indices into the corresponding .node file. The boundary\n"
580 printf(" markers are ignored by Show Me.\n\n");
582 " In Voronoi diagrams, one also finds a special kind of edge that is an\n");
584 " infinite ray with only one endpoint. For these edges, a different\n");
585 printf(" format is used:\n\n");
586 printf(" <edge #> <endpoint> -1 <direction x> <direction y>\n\n");
588 " The `direction' is a floating-point vector that indicates the direction\n"
590 printf(" of the infinite ray.\n\n");
591 printf(" .part files:\n");
592 printf(" First line: <# of triangles> <# of subdomains>\n");
593 printf(" Remaining lines: <triangle #> <subdomain #>\n\n");
595 " The set of triangles is partitioned by a .part file; each triangle is\n");
596 printf(" mapped to a subdomain.\n\n");
597 printf(" .adj files:\n");
598 printf(" First line: <# of subdomains>\n");
599 printf(" Remaining lines: <adjacency matrix entry>\n\n");
601 " An .adj file represents adjacencies between subdomains (presumably\n");
602 printf(" computed by a partitioner). The first line is followed by\n");
604 " (subdomains X subdomains) lines, each containing one entry of the\n");
606 " adjacency matrix. A nonzero entry indicates that two subdomains are\n");
607 printf(" adjacent (share a point).\n\n");
608 printf("Example:\n\n");
610 " Here is a sample file `box.poly' describing a square with a square hole:\n"
614 " # A box with eight points in 2D, no attributes, no boundary marker.\n");
615 printf(" 8 2 0 0\n");
616 printf(" # Outer box has these vertices:\n");
621 printf(" # Inner square has these vertices:\n");
626 printf(" # Five segments without boundary markers.\n");
628 printf(" 1 1 2 # Left side of outer box.\n");
629 printf(" 2 5 7 # Segments 2 through 5 enclose the hole.\n");
633 printf(" # One hole in the middle of the inner square.\n");
635 printf(" 1 1.5 1.5\n\n");
637 " After this PSLG is triangulated by Triangle, the resulting triangulation\n"
640 " consists of a .node and .ele file. Here is the former, `box.1.node',\n");
641 printf(" which duplicates the points of the PSLG:\n\n");
642 printf(" 8 2 0 0\n");
651 printf(" # Generated by triangle -pcBev box\n");
653 printf(" Here is the triangulation file, `box.1.ele'.\n");
656 printf(" 1 1 5 6\n");
657 printf(" 2 5 1 3\n");
658 printf(" 3 2 6 8\n");
659 printf(" 4 6 2 1\n");
660 printf(" 5 7 3 4\n");
661 printf(" 6 3 7 5\n");
662 printf(" 7 8 4 2\n");
663 printf(" 8 4 8 7\n");
664 printf(" # Generated by triangle -pcBev box\n\n");
665 printf(" Here is the edge file for the triangulation, `box.1.edge'.\n\n");
683 printf(" # Generated by triangle -pcBev box\n");
686 " Here's a file `box.1.part' that partitions the mesh into four subdomains.\n"
698 printf(" # Generated by slice -s4 box.1\n\n");
700 " Here's a file `box.1.adj' that represents the resulting adjacencies.\n");
720 printf("Display Speed:\n");
723 " It is worthwhile to note that .edge files typically plot and print twice\n"
726 " as quickly as .ele files, because .ele files cause each internal edge to\n"
729 " be drawn twice. For the same reason, PostScript files created from edge\n"
731 printf(" sets are smaller than those created from triangulations.\n\n");
732 printf("Show Me on the Web:\n\n");
734 " To see an illustrated, updated version of these instructions, check out\n");
736 printf(" http://www.cs.cmu.edu/~quake/showme.html\n");
738 printf("A Brief Plea:\n");
741 " If you use Show Me (or Triangle), and especially if you use it to\n");
743 " accomplish real work, I would like very much to hear from you. A short\n");
745 " letter or email (to jrs@cs.cmu.edu) describing how you use Show Me (and\n");
747 " its sister programs) will mean a lot to me. The more people I know\n");
749 " are using my programs, the more easily I can justify spending time on\n");
751 " improvements, which in turn will benefit you. Also, I can put you\n");
753 " on a list to receive email whenever new versions are available.\n");
756 " If you use a PostScript file generated by Show Me in a publication,\n");
757 printf(" please include an acknowledgment as well.\n\n");
761 void set_filenames(filename, lowermeshnumber)
765 char numberstring[100];
768 for (i = 0; i < 2; i++) {
769 strcpy(nodefilename[i], filename);
770 strcpy(polyfilename[i], filename);
771 strcpy(elefilename[i], filename);
772 strcpy(edgefilename[i], filename);
773 strcpy(partfilename[i], filename);
774 strcpy(adjfilename[i], filename);
775 strcpy(vnodefilename[i], filename);
776 strcpy(vedgefilename[i], filename);
778 if (lowermeshnumber + i > 0) {
779 sprintf(numberstring, ".%d", lowermeshnumber + i);
780 strcat(nodefilename[i], numberstring);
781 strcat(polyfilename[i], numberstring);
782 strcat(elefilename[i], numberstring);
783 strcat(edgefilename[i], numberstring);
784 strcat(partfilename[i], numberstring);
785 strcat(adjfilename[i], numberstring);
786 strcat(vnodefilename[i], numberstring);
787 strcat(vedgefilename[i], numberstring);
790 strcat(nodefilename[i], ".node");
791 strcat(polyfilename[i], ".poly");
792 strcat(elefilename[i], ".ele");
793 strcat(edgefilename[i], ".edge");
794 strcat(partfilename[i], ".part");
795 strcat(adjfilename[i], ".adj");
796 strcat(vnodefilename[i], ".v.node");
797 strcat(vedgefilename[i], ".v.edge");
801 void parsecommandline(argc, argv)
815 for (i = 1; i < argc; i++) {
816 if (argv[i][0] == '-') {
817 for (j = 1; argv[i][j] != '\0'; j++) {
818 if (argv[i][j] == 'f') {
821 if (argv[i][j] == 'w') {
822 if ((argv[i][j + 1] >= '1') && (argv[i][j + 1] <= '9')) {
824 while ((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) {
826 line_width = line_width * 10 + (int) (argv[i][j] - '0');
828 if (line_width > 100) {
829 printf("Error: Line width cannot exceed 100.\n");
834 if (argv[i][j] == 'b') {
837 if (argv[i][j] == 'Q') {
840 if ((argv[i][j] == 'h') || (argv[i][j] == 'H') ||
841 (argv[i][j] == '?')) {
846 strcpy(filename, argv[i]);
849 if (filename[0] == '\0') {
852 if (!strcmp(&filename[strlen(filename) - 5], ".node")) {
853 filename[strlen(filename) - 5] = '\0';
856 if (!strcmp(&filename[strlen(filename) - 5], ".poly")) {
857 filename[strlen(filename) - 5] = '\0';
860 if (!strcmp(&filename[strlen(filename) - 4], ".ele")) {
861 filename[strlen(filename) - 4] = '\0';
864 if (!strcmp(&filename[strlen(filename) - 5], ".edge")) {
865 filename[strlen(filename) - 5] = '\0';
868 if (!strcmp(&filename[strlen(filename) - 5], ".part")) {
869 filename[strlen(filename) - 5] = '\0';
872 if (!strcmp(&filename[strlen(filename) - 4], ".adj")) {
873 filename[strlen(filename) - 4] = '\0';
879 while (filename[j] != '\0') {
880 if ((filename[j] == '.') && (filename[j + 1] != '\0')) {
889 if ((filename[j] >= '0') && (filename[j] <= '9')) {
890 meshnumber = meshnumber * 10 + (int) (filename[j] - '0');
895 } while (filename[j] != '\0');
898 filename[increment - 1] = '\0';
901 if (meshnumber == 0) {
906 loweriteration = meshnumber - 1;
908 set_filenames(filename, loweriteration);
914 if (loaded[inc][NODE]) {
917 if (loaded[inc][POLY]) {
918 if (polynodes[inc] > 0) {
919 free(polynodeptr[inc]);
921 free(polyedgeptr[inc]);
922 free(polyholeptr[inc]);
924 if (loaded[inc][ELE]) {
927 if (loaded[inc][PART]) {
929 free(partcenter[inc]);
930 free(partshift[inc]);
932 if (loaded[inc][EDGE]) {
936 if (loaded[inc][ADJ]) {
939 if (loaded[inc][VORO]) {
952 for (i = 0; i < IMAGE_TYPES; i++) {
953 loaded[1 - inc][i] = loaded[inc][i];
955 xlo[1 - inc][i] = xlo[inc][i];
956 ylo[1 - inc][i] = ylo[inc][i];
957 xhi[1 - inc][i] = xhi[inc][i];
958 yhi[1 - inc][i] = yhi[inc][i];
960 nodes[1 - inc] = nodes[inc];
961 node_dim[1 - inc] = node_dim[inc];
962 nodeptr[1 - inc] = nodeptr[inc];
963 polynodes[1 - inc] = polynodes[inc];
964 poly_dim[1 - inc] = poly_dim[inc];
965 polyedges[1 - inc] = polyedges[inc];
966 polyholes[1 - inc] = polyholes[inc];
967 polynodeptr[1 - inc] = polynodeptr[inc];
968 polyedgeptr[1 - inc] = polyedgeptr[inc];
969 polyholeptr[1 - inc] = polyholeptr[inc];
970 elems[1 - inc] = elems[inc];
971 ele_corners[1 - inc] = ele_corners[inc];
972 eleptr[1 - inc] = eleptr[inc];
973 edges[1 - inc] = edges[inc];
974 edgeptr[1 - inc] = edgeptr[inc];
975 normptr[1 - inc] = normptr[inc];
976 subdomains[1 - inc] = subdomains[inc];
977 partpart[1 - inc] = partpart[inc];
978 partcenter[1 - inc] = partcenter[inc];
979 partshift[1 - inc] = partshift[inc];
980 adjsubdomains[1 - inc] = adjsubdomains[inc];
981 adjptr[1 - inc] = adjptr[inc];
982 vnodes[1 - inc] = vnodes[inc];
983 vnode_dim[1 - inc] = vnode_dim[inc];
984 vnodeptr[1 - inc] = vnodeptr[inc];
985 vedges[1 - inc] = vedges[inc];
986 vedgeptr[1 - inc] = vedgeptr[inc];
987 vnormptr[1 - inc] = vnormptr[inc];
988 firstnumber[1 - inc] = firstnumber[inc];
989 firstnumber[inc] = -1;
997 current_image = NOTHING;
998 for (i = 0; i < IMAGE_TYPES; i++) {
1000 firstnumber[inc] = -1;
1006 current_image = NOTHING;
1008 explosion = STARTEXPLOSION;
1013 char *readline(string, infile, infilename)
1021 result = fgets(string, INPUTLINESIZE, infile);
1022 if (result == (char *) NULL) {
1023 printf(" Error: Unexpected end of file in %s.\n",
1027 while ((*result != '\0') && (*result != '#')
1028 && (*result != '.') && (*result != '+') && (*result != '-')
1029 && ((*result < '0') || (*result > '9'))) {
1032 } while ((*result == '#') || (*result == '\0'));
1036 char *findfield(string)
1042 while ((*result != '\0') && (*result != '#')
1043 && (*result != ' ') && (*result != '\t')) {
1046 while ((*result != '\0') && (*result != '#')
1047 && (*result != '.') && (*result != '+') && (*result != '-')
1048 && ((*result < '0') || (*result > '9'))) {
1051 if (*result == '#') {
1057 int load_node(fname, firstnumber, nodes, dim, ptr, xmin, ymin, xmax, ymax)
1069 char inputline[INPUTLINESIZE];
1079 *xmin = *ymin = 0.0;
1080 *xmax = *ymax = 1.0;
1082 printf("Opening %s.\n", fname);
1084 infile = fopen(fname, "r");
1085 if (infile == (FILE *) NULL) {
1086 printf(" Error: Cannot access file %s.\n", fname);
1089 stringptr = readline(inputline, infile, fname);
1090 *nodes = (int) strtol (stringptr, &stringptr, 0);
1092 printf(" Error: %s contains %d points.\n", fname, *nodes);
1095 stringptr = findfield(stringptr);
1096 if (*stringptr == '\0') {
1099 *dim = (int) strtol (stringptr, &stringptr, 0);
1102 printf(" Error: %s has dimensionality %d.\n", fname, *dim);
1106 printf(" I only understand two-dimensional meshes.\n");
1109 stringptr = findfield(stringptr);
1110 if (*stringptr == '\0') {
1113 extras = (int) strtol (stringptr, &stringptr, 0);
1116 printf(" Error: %s has negative value for number of attributes.\n",
1120 stringptr = findfield(stringptr);
1121 if (*stringptr == '\0') {
1124 nodemarks = (int) strtol (stringptr, &stringptr, 0);
1126 if (nodemarks < 0) {
1127 printf(" Warning: %s has negative value for number of point markers.\n",
1130 if (nodemarks > 1) {
1132 " Warning: %s has value greater than one for number of point markers.\n",
1135 *ptr = (REAL *) malloc((*nodes + 1) * *dim * sizeof(REAL));
1136 if (*ptr == (REAL *) NULL) {
1137 printf(" Out of memory.\n");
1142 for (i = 0; i < *nodes; i++) {
1143 stringptr = readline(inputline, infile, fname);
1144 nodenumber = (int) strtol (stringptr, &stringptr, 0);
1145 if ((i == 0) && (*firstnumber == -1)) {
1146 if (nodenumber == 0) {
1152 if ((nodenumber != *firstnumber + i) && (smallerr)) {
1153 printf(" Warning: Points in %s are not numbered correctly\n", fname);
1154 printf(" (starting with point %d).\n", *firstnumber + i);
1157 for (j = 0; j < *dim; j++) {
1158 stringptr = findfield(stringptr);
1159 if (*stringptr == '\0') {
1160 printf("Error: Point %d is missing a coordinate in %s.\n",
1161 *firstnumber + i, fname);
1165 (*ptr)[index++] = (REAL) strtod(stringptr, &stringptr);
1170 *xmin = *xmax = (*ptr)[index];
1171 *ymin = *ymax = (*ptr)[index + 1];
1172 for (i = 2; i <= *nodes; i++) {
1175 y = (*ptr)[index + 1];
1189 if (*xmin == *xmax) {
1193 if (*ymin == *ymax) {
1200 int load_poly(inc, fname, firstnumber, pnodes, dim, edges, holes, nodeptr,
1201 edgeptr, holeptr, xmin, ymin, xmax, ymax)
1218 char inputline[INPUTLINESIZE];
1224 int nodenumber, edgenumber, holenumber;
1231 printf("Opening %s.\n", fname);
1233 infile = fopen(fname, "r");
1234 if (infile == (FILE *) NULL) {
1235 printf(" Error: Cannot access file %s.\n", fname);
1238 stringptr = readline(inputline, infile, fname);
1239 *pnodes = (int) strtol (stringptr, &stringptr, 0);
1241 if (!loaded[inc][NODE]) {
1242 if (load_image(inc, NODE)) {
1246 maxnode = nodes[inc];
1247 *xmin = xlo[inc][NODE];
1248 *ymin = ylo[inc][NODE];
1249 *xmax = xhi[inc][NODE];
1250 *ymax = yhi[inc][NODE];
1253 printf(" Error: %s contains %d points.\n", fname, *pnodes);
1258 stringptr = findfield(stringptr);
1259 if (*stringptr == '\0') {
1262 *dim = (int) strtol (stringptr, &stringptr, 0);
1265 printf(" Error: %s has dimensionality %d.\n", fname, *dim);
1269 printf(" I only understand two-dimensional meshes.\n");
1272 stringptr = findfield(stringptr);
1273 if (*stringptr == '\0') {
1276 extras = (int) strtol (stringptr, &stringptr, 0);
1279 printf(" Error: %s has negative value for number of attributes.\n",
1283 stringptr = findfield(stringptr);
1284 if (*stringptr == '\0') {
1287 nodemarks = (int) strtol (stringptr, &stringptr, 0);
1289 if (nodemarks < 0) {
1290 printf(" Warning: %s has negative value for number of point markers.\n",
1293 if (nodemarks > 1) {
1295 " Warning: %s has value greater than one for number of point markers.\n",
1299 *nodeptr = (REAL *) malloc((*pnodes + 1) * *dim * sizeof(REAL));
1300 if (*nodeptr == (REAL *) NULL) {
1301 printf(" Out of memory.\n");
1306 for (i = 0; i < *pnodes; i++) {
1307 stringptr = readline(inputline, infile, fname);
1308 nodenumber = (int) strtol (stringptr, &stringptr, 0);
1309 if ((i == 0) && (*firstnumber == -1)) {
1310 if (nodenumber == 0) {
1316 if ((nodenumber != *firstnumber + i) && (smallerr)) {
1317 printf(" Warning: Points in %s are not numbered correctly.\n",
1319 printf(" (starting with point %d).\n", *firstnumber + i);
1322 for (j = 0; j < *dim; j++) {
1323 stringptr = findfield(stringptr);
1324 if (*stringptr == '\0') {
1325 printf("Error: Point %d is missing a coordinate in %s.\n",
1326 *firstnumber + i, fname);
1330 (*nodeptr)[index++] = (REAL) strtod(stringptr, &stringptr);
1334 stringptr = readline(inputline, infile, fname);
1335 *edges = (int) strtol (stringptr, &stringptr, 0);
1337 printf(" Error: %s contains %d segments.\n", fname, *edges);
1341 stringptr = findfield(stringptr);
1342 if (*stringptr == '\0') {
1345 segmentmarks = (int) strtol (stringptr, &stringptr, 0);
1347 if (segmentmarks < 0) {
1348 printf(" Error: %s has negative value for number of segment markers.\n",
1353 if (segmentmarks > 1) {
1355 " Error: %s has value greater than one for number of segment markers.\n",
1360 *edgeptr = (int *) malloc(((*edges + 1) << 1) * sizeof(int));
1361 if (*edgeptr == (int *) NULL) {
1362 printf(" Out of memory.\n");
1368 for (i = *firstnumber; i < *firstnumber + *edges; i++) {
1369 stringptr = readline(inputline, infile, fname);
1370 edgenumber = (int) strtol (stringptr, &stringptr, 0);
1371 if ((edgenumber != i) && (smallerr)) {
1372 printf(" Warning: Segments in %s are not numbered correctly.\n",
1374 printf(" (starting with segment %d).\n", i);
1377 stringptr = findfield(stringptr);
1378 if (*stringptr == '\0') {
1379 printf("Error: Segment %d is missing its endpoints in %s.\n", i, fname);
1384 (*edgeptr)[index] = (int) strtol (stringptr, &stringptr, 0) + 1 -
1386 if (((*edgeptr)[index] < 1) || ((*edgeptr)[index] > maxnode)) {
1387 printf("Error: Segment %d has invalid endpoint in %s.\n", i, fname);
1390 stringptr = findfield(stringptr);
1391 if (*stringptr == '\0') {
1392 printf("Error: Segment %d is missing an endpoint in %s.\n", i, fname);
1397 (*edgeptr)[index + 1] = (int) strtol (stringptr, &stringptr, 0) + 1 -
1399 if (((*edgeptr)[index + 1] < 1) || ((*edgeptr)[index + 1] > maxnode)) {
1400 printf("Error: Segment %d has invalid endpoint in %s.\n", i, fname);
1405 stringptr = readline(inputline, infile, fname);
1406 *holes = (int) strtol (stringptr, &stringptr, 0);
1408 printf(" Error: %s contains %d holes.\n", fname, *holes);
1413 *holeptr = (REAL *) malloc((*holes + 1) * *dim * sizeof(REAL));
1414 if (*holeptr == (REAL *) NULL) {
1415 printf(" Out of memory.\n");
1422 for (i = *firstnumber; i < *firstnumber + *holes; i++) {
1423 stringptr = readline(inputline, infile, fname);
1424 holenumber = (int) strtol (stringptr, &stringptr, 0);
1425 if ((holenumber != i) && (smallerr)) {
1426 printf(" Warning: Holes in %s are not numbered correctly.\n", fname);
1427 printf(" (starting with hole %d).\n", i);
1430 for (j = 0; j < *dim; j++) {
1431 stringptr = findfield(stringptr);
1432 if (*stringptr == '\0') {
1433 printf("Error: Hole %d is missing a coordinate in %s.\n", i,
1440 (*holeptr)[index++] = (REAL) strtod(stringptr, &stringptr);
1446 *xmin = *xmax = (*nodeptr)[index];
1447 *ymin = *ymax = (*nodeptr)[index + 1];
1448 for (i = 2; i <= *pnodes; i++) {
1450 x = (*nodeptr)[index];
1451 y = (*nodeptr)[index + 1];
1467 for (i = 1; i <= *holes; i++) {
1468 x = (*holeptr)[index];
1469 y = (*holeptr)[index + 1];
1487 int load_ele(fname, firstnumber, nodes, elems, corners, ptr)
1496 char inputline[INPUTLINESIZE];
1505 printf("Opening %s.\n", fname);
1507 infile = fopen(fname, "r");
1508 if (infile == (FILE *) NULL) {
1509 printf(" Error: Cannot access file %s.\n", fname);
1512 stringptr = readline(inputline, infile, fname);
1513 *elems = (int) strtol (stringptr, &stringptr, 0);
1515 printf(" Error: %s contains %d triangles.\n", fname, *elems);
1518 stringptr = findfield(stringptr);
1519 if (*stringptr == '\0') {
1522 *corners = (int) strtol (stringptr, &stringptr, 0);
1525 printf(" Error: Triangles in %s have only %d corners.\n", fname,
1529 stringptr = findfield(stringptr);
1530 if (*stringptr == '\0') {
1533 extras = (int) strtol (stringptr, &stringptr, 0);
1536 printf(" Error: %s has negative value for extra fields.\n", fname);
1539 *ptr = (int *) malloc((*elems + 1) * 3 * sizeof(int));
1540 if (*ptr == (int *) NULL) {
1541 printf(" Out of memory.\n");
1546 for (i = firstnumber; i < firstnumber + *elems; i++) {
1547 stringptr = readline(inputline, infile, fname);
1548 elemnumber = (int) strtol (stringptr, &stringptr, 0);
1549 if ((elemnumber != i) && (smallerr)) {
1550 printf(" Warning: Triangles in %s are not numbered correctly.\n",
1552 printf(" (starting with triangle %d).\n", i);
1555 for (j = 0; j < 3; j++) {
1556 stringptr = findfield(stringptr);
1557 if (*stringptr == '\0') {
1558 printf("Error: Triangle %d is missing a corner in %s.\n", i, fname);
1562 (*ptr)[index] = (int) strtol (stringptr, &stringptr, 0) + 1 -
1564 if (((*ptr)[index] < 1) || ((*ptr)[index] > nodes)) {
1565 printf("Error: Triangle %d has invalid corner in %s.\n", i, fname);
1575 int load_edge(fname, firstnumber, nodes, edges, edgeptr, normptr)
1584 char inputline[INPUTLINESIZE];
1593 printf("Opening %s.\n", fname);
1595 infile = fopen(fname, "r");
1596 if (infile == (FILE *) NULL) {
1597 printf(" Error: Cannot access file %s.\n", fname);
1600 stringptr = readline(inputline, infile, fname);
1601 *edges = (int) strtol (stringptr, &stringptr, 0);
1603 printf(" Error: %s contains %d edges.\n", fname, *edges);
1606 stringptr = findfield(stringptr);
1607 if (*stringptr == '\0') {
1610 edgemarks = (int) strtol (stringptr, &stringptr, 0);
1612 if (edgemarks < 0) {
1613 printf(" Error: %s has negative value for number of edge markers.\n",
1617 if (edgemarks > 1) {
1619 " Error: %s has value greater than one for number of edge markers.\n",
1623 *edgeptr = (int *) malloc(((*edges + 1) << 1) * sizeof(int));
1624 if (*edgeptr == (int *) NULL) {
1625 printf(" Out of memory.\n");
1628 *normptr = (REAL *) malloc(((*edges + 1) << 1) * sizeof(REAL));
1629 if (*normptr == (REAL *) NULL) {
1630 printf(" Out of memory.\n");
1636 for (i = firstnumber; i < firstnumber + *edges; i++) {
1637 stringptr = readline(inputline, infile, fname);
1638 edgenumber = (int) strtol (stringptr, &stringptr, 0);
1639 if ((edgenumber != i) && (smallerr)) {
1640 printf(" Warning: Edges in %s are not numbered correctly.\n", fname);
1641 printf(" (starting with edge %d).\n", i);
1644 stringptr = findfield(stringptr);
1645 if (*stringptr == '\0') {
1646 printf("Error: Edge %d is missing its endpoints in %s.\n", i, fname);
1651 (*edgeptr)[index] = (int) strtol (stringptr, &stringptr, 0) + 1 -
1653 if (((*edgeptr)[index] < 1) || ((*edgeptr)[index] > nodes)) {
1654 printf("Error: Edge %d has invalid endpoint in %s.\n", i, fname);
1657 stringptr = findfield(stringptr);
1658 if (*stringptr == '\0') {
1659 printf("Error: Edge %d is missing an endpoint in %s.\n", i, fname);
1664 (*edgeptr)[index + 1] = (int) strtol (stringptr, &stringptr, 0);
1665 if ((*edgeptr)[index + 1] == -1) {
1666 stringptr = findfield(stringptr);
1667 if (*stringptr == '\0') {
1668 printf("Error: Edge %d is missing its direction in %s.\n", i, fname);
1673 (*normptr)[index] = (REAL) strtod(stringptr, &stringptr);
1674 stringptr = findfield(stringptr);
1675 if (*stringptr == '\0') {
1676 printf("Error: Edge %d is missing a direction coordinate in %s.\n",
1682 (*normptr)[index + 1] = (REAL) strtod(stringptr, &stringptr);
1684 (*edgeptr)[index + 1] += 1 - firstnumber;
1685 if (((*edgeptr)[index + 1] < 1) || ((*edgeptr)[index + 1] > nodes)) {
1686 printf("Error: Edge %d has invalid endpoint in %s.\n", i, fname);
1696 int load_part(fname, dim, firstnumber, elems, nodeptr, eleptr, parts,
1697 partition, partcenter, partshift)
1710 char inputline[INPUTLINESIZE];
1720 printf("Opening %s.\n", fname);
1722 infile = fopen(fname, "r");
1723 if (infile == (FILE *) NULL) {
1724 printf(" Error: Cannot access file %s.\n", fname);
1727 stringptr = readline(inputline, infile, fname);
1728 partelems = (int) strtol (stringptr, &stringptr, 0);
1729 if (partelems != elems) {
1731 " Error: .ele and .part files do not agree on number of triangles.\n");
1734 stringptr = findfield(stringptr);
1735 if (*stringptr == '\0') {
1738 *parts = (int) strtol (stringptr, &stringptr, 0);
1741 printf(" Error: %s specifies %d subdomains.\n", fname, *parts);
1744 *partition = (int *) malloc((elems + 1) * sizeof(int));
1745 if (*partition == (int *) NULL) {
1746 printf(" Out of memory.\n");
1750 for (i = firstnumber; i < firstnumber + partelems; i++) {
1751 stringptr = readline(inputline, infile, fname);
1752 elemnumber = (int) strtol (stringptr, &stringptr, 0);
1753 if ((elemnumber != i) && (smallerr)) {
1754 printf(" Warning: Triangles in %s are not numbered correctly.\n",
1756 printf(" (starting with triangle %d).\n", i);
1759 stringptr = findfield(stringptr);
1760 if (*stringptr == '\0') {
1761 printf("Error: Triangle %d has no subdomain in %s.\n", i, fname);
1765 (*partition)[i] = (int) strtol (stringptr, &stringptr, 0) - firstnumber;
1766 if (((*partition)[i] >= *parts) || ((*partition)[i] < 0)) {
1767 printf(" Error: Triangle %d of %s has an invalid subdomain.\n",
1774 *partcenter = (REAL *) malloc(((*parts + 1) << 1) * sizeof(REAL));
1775 if (*partcenter == (REAL *) NULL) {
1776 printf("Error: Out of memory.\n");
1780 *partshift = (REAL *) malloc((*parts << 1) * sizeof(REAL));
1781 if (*partshift == (REAL *) NULL) {
1782 printf("Error: Out of memory.\n");
1787 partsize = (int *) malloc((*parts + 1) * sizeof(int));
1788 if (partsize == (int *) NULL) {
1789 printf("Error: Out of memory.\n");
1796 for (i = 0; i <= *parts; i++) {
1798 (*partcenter)[i << 1] = 0.0;
1799 (*partcenter)[(i << 1) + 1] = 0.0;
1801 for (i = 1; i <= elems; i++) {
1802 partsize[(*partition)[i]] += 3;
1803 for (j = 0; j < 3; j++) {
1804 (*partcenter)[(*partition)[i] << 1] +=
1805 nodeptr[eleptr[index] * dim];
1806 (*partcenter)[((*partition)[i] << 1) + 1] +=
1807 nodeptr[eleptr[index++] * dim + 1];
1810 for (i = 0; i < *parts; i++) {
1811 (*partcenter)[i << 1] /= (REAL) partsize[i];
1812 (*partcenter)[(i << 1) + 1] /= (REAL) partsize[i];
1813 (*partcenter)[*parts << 1] += (*partcenter)[i << 1];
1814 (*partcenter)[(*parts << 1) + 1] += (*partcenter)[(i << 1) + 1];
1816 (*partcenter)[*parts << 1] /= (REAL) *parts;
1817 (*partcenter)[(*parts << 1) + 1] /= (REAL) *parts;
1822 int load_adj(fname, subdomains, ptr)
1828 char inputline[INPUTLINESIZE];
1833 printf("Opening %s.\n", fname);
1835 infile = fopen(fname, "r");
1836 if (infile == (FILE *) NULL) {
1837 printf(" Error: Cannot access file %s.\n", fname);
1840 stringptr = readline(inputline, infile, fname);
1841 *subdomains = (int) strtol (stringptr, &stringptr, 0);
1842 if (*subdomains < 1) {
1843 printf(" Error: %s contains %d subdomains.\n", fname, *subdomains);
1846 *ptr = (int *) malloc(*subdomains * *subdomains * sizeof(int));
1847 if (*ptr == (int *) NULL) {
1848 printf(" Out of memory.\n");
1851 for (i = 0; i < *subdomains; i++) {
1852 for (j = 0; j < *subdomains; j++) {
1853 stringptr = readline(inputline, infile, fname);
1854 (*ptr)[i * *subdomains + j] = (int) strtol (stringptr, &stringptr, 0);
1860 void findpartshift(parts, explosion, partcenter, partshift)
1868 for (i = 0; i < parts; i++) {
1869 partshift[i << 1] = explosion *
1870 (partcenter[i << 1] - partcenter[parts << 1]);
1871 partshift[(i << 1) + 1] = explosion *
1872 (partcenter[(i << 1) + 1] - partcenter[(parts << 1) + 1]);
1876 int load_image(inc, image)
1884 error = load_node(nodefilename[inc], &firstnumber[inc], &nodes[inc],
1885 &node_dim[inc], &nodeptr[inc], &xlo[inc][NODE],
1886 &ylo[inc][NODE], &xhi[inc][NODE], &yhi[inc][NODE]);
1889 error = load_poly(inc, polyfilename[inc], &firstnumber[inc],
1890 &polynodes[inc], &poly_dim[inc], &polyedges[inc],
1891 &polyholes[inc], &polynodeptr[inc], &polyedgeptr[inc],
1893 &xlo[inc][POLY], &ylo[inc][POLY],
1894 &xhi[inc][POLY], &yhi[inc][POLY]);
1897 error = load_ele(elefilename[inc], firstnumber[inc], nodes[inc],
1898 &elems[inc], &ele_corners[inc], &eleptr[inc]);
1899 xlo[inc][ELE] = xlo[inc][NODE];
1900 ylo[inc][ELE] = ylo[inc][NODE];
1901 xhi[inc][ELE] = xhi[inc][NODE];
1902 yhi[inc][ELE] = yhi[inc][NODE];
1905 error = load_edge(edgefilename[inc], firstnumber[inc], nodes[inc],
1906 &edges[inc], &edgeptr[inc], &normptr[inc]);
1907 xlo[inc][EDGE] = xlo[inc][NODE];
1908 ylo[inc][EDGE] = ylo[inc][NODE];
1909 xhi[inc][EDGE] = xhi[inc][NODE];
1910 yhi[inc][EDGE] = yhi[inc][NODE];
1913 error = load_part(partfilename[inc], node_dim[inc], firstnumber[inc],
1914 elems[inc], nodeptr[inc], eleptr[inc],
1915 &subdomains[inc], &partpart[inc], &partcenter[inc],
1918 findpartshift(subdomains[inc], explosion, partcenter[inc],
1921 xlo[inc][PART] = xlo[inc][NODE];
1922 ylo[inc][PART] = ylo[inc][NODE];
1923 xhi[inc][PART] = xhi[inc][NODE];
1924 yhi[inc][PART] = yhi[inc][NODE];
1927 error = load_adj(adjfilename[inc], &adjsubdomains[inc], &adjptr[inc]);
1928 xlo[inc][ADJ] = xlo[inc][NODE];
1929 ylo[inc][ADJ] = ylo[inc][NODE];
1930 xhi[inc][ADJ] = xhi[inc][NODE];
1931 yhi[inc][ADJ] = yhi[inc][NODE];
1934 error = load_node(vnodefilename[inc], &firstnumber[inc], &vnodes[inc],
1935 &vnode_dim[inc], &vnodeptr[inc], &xlo[inc][VORO],
1936 &ylo[inc][VORO], &xhi[inc][VORO], &yhi[inc][VORO]);
1938 error = load_edge(vedgefilename[inc], firstnumber[inc], vnodes[inc],
1939 &vedges[inc], &vedgeptr[inc], &vnormptr[inc]);
1946 loaded[inc][image] = 1;
1951 void choose_image(inc, image)
1955 if (!loaded[inc][image]) {
1956 if ((image == ELE) || (image == EDGE) || (image == PART)
1957 || (image == ADJ)) {
1958 if (!loaded[inc][NODE]) {
1959 if (load_image(inc, NODE)) {
1964 if ((image == PART) || (image == ADJ)) {
1965 if (!loaded[inc][ELE]) {
1966 if (load_image(inc, ELE)) {
1972 if (!loaded[inc][PART]) {
1973 if (load_image(inc, PART)) {
1978 if (load_image(inc, image)) {
1983 current_image = image;
1986 Window make_button(name, x, y, width)
1992 XSetWindowAttributes attr;
1996 attr.background_pixel = black;
1997 attr.border_pixel = white;
1998 attr.backing_store = NotUseful;
1999 attr.event_mask = ExposureMask | ButtonReleaseMask | ButtonPressMask;
2000 attr.bit_gravity = SouthWestGravity;
2001 attr.win_gravity = SouthWestGravity;
2002 attr.save_under = False;
2003 button = XCreateWindow(display, mainwindow, x, y, width, BUTTONHEIGHT - 4,
2004 2, 0, InputOutput, CopyFromParent,
2005 CWBackPixel | CWBorderPixel | CWEventMask |
2006 CWBitGravity | CWWinGravity | CWBackingStore |
2007 CWSaveUnder, &attr);
2008 hints.width = width;
2009 hints.height = BUTTONHEIGHT - 4;
2010 hints.min_width = 0;
2011 hints.min_height = BUTTONHEIGHT - 4;
2012 hints.max_width = width;
2013 hints.max_height = BUTTONHEIGHT - 4;
2014 hints.width_inc = 1;
2015 hints.height_inc = 1;
2016 hints.flags = PMinSize | PMaxSize | PSize | PResizeInc;
2017 XSetStandardProperties(display, button, name, "showme", None, (char **) NULL,
2022 void make_buttons(y)
2027 for (i = 1; i >= 0; i--) {
2028 nodewin[i] = make_button("node", 0, y + (1 - i) * BUTTONHEIGHT, 42);
2029 XMapWindow(display, nodewin[i]);
2030 polywin[i] = make_button("poly", 44, y + (1 - i) * BUTTONHEIGHT, 42);
2031 XMapWindow(display, polywin[i]);
2032 elewin[i] = make_button("ele", 88, y + (1 - i) * BUTTONHEIGHT, 33);
2033 XMapWindow(display, elewin[i]);
2034 edgewin[i] = make_button("edge", 123, y + (1 - i) * BUTTONHEIGHT, 42);
2035 XMapWindow(display, edgewin[i]);
2036 partwin[i] = make_button("part", 167, y + (1 - i) * BUTTONHEIGHT, 42);
2037 XMapWindow(display, partwin[i]);
2038 adjwin[i] = make_button("adj", 211, y + (1 - i) * BUTTONHEIGHT, 33);
2039 XMapWindow(display, adjwin[i]);
2040 voronoiwin[i] = make_button("voro", 246, y + (1 - i) * BUTTONHEIGHT, 42);
2041 XMapWindow(display, voronoiwin[i]);
2043 versionpluswin = make_button(" +", 290, y, 52);
2044 XMapWindow(display, versionpluswin);
2045 versionminuswin = make_button(" -", 290, y + BUTTONHEIGHT, 52);
2046 XMapWindow(display, versionminuswin);
2048 quitwin = make_button("Quit", 0, y + 2 * BUTTONHEIGHT, 42);
2049 XMapWindow(display, quitwin);
2050 leftwin = make_button("<", 44, y + 2 * BUTTONHEIGHT, 14);
2051 XMapWindow(display, leftwin);
2052 rightwin = make_button(">", 60, y + 2 * BUTTONHEIGHT, 14);
2053 XMapWindow(display, rightwin);
2054 upwin = make_button("^", 76, y + 2 * BUTTONHEIGHT, 14);
2055 XMapWindow(display, upwin);
2056 downwin = make_button("v", 92, y + 2 * BUTTONHEIGHT, 14);
2057 XMapWindow(display, downwin);
2058 resetwin = make_button("Reset", 108, y + 2 * BUTTONHEIGHT, 52);
2059 XMapWindow(display, resetwin);
2060 widthpluswin = make_button("Width+", 162, y + 2 * BUTTONHEIGHT, 61);
2061 XMapWindow(display, widthpluswin);
2062 widthminuswin = make_button("-", 225, y + 2 * BUTTONHEIGHT, 14);
2063 XMapWindow(display, widthminuswin);
2064 expwin = make_button("Exp", 241, y + 2 * BUTTONHEIGHT, 33);
2065 XMapWindow(display, expwin);
2066 exppluswin = make_button("+", 276, y + 2 * BUTTONHEIGHT, 14);
2067 XMapWindow(display, exppluswin);
2068 expminuswin = make_button("-", 292, y + 2 * BUTTONHEIGHT, 14);
2069 XMapWindow(display, expminuswin);
2070 fillwin = make_button("Fill", 308, y + 2 * BUTTONHEIGHT, 41);
2071 XMapWindow(display, fillwin);
2072 pswin = make_button("PS", 351, y + 2 * BUTTONHEIGHT, 24);
2073 XMapWindow(display, pswin);
2074 epswin = make_button("EPS", 377, y + 2 * BUTTONHEIGHT, 33);
2075 XMapWindow(display, epswin);
2078 void fill_button(button)
2082 unsigned int w, h, d, b;
2085 XGetGeometry(display, button, &rootw, &x, &y, &w, &h, &d, &b);
2086 XFillRectangle(display, button, fontgc, 0, 0, w, h);
2091 char numberstring[32];
2092 char buttonstring[6];
2095 for (i = 1; i >= 0; i--) {
2096 if ((current_image == NODE) && (current_inc == i)) {
2097 fill_button(nodewin[i]);
2098 XDrawString(display, nodewin[i], blackfontgc, 2, 13, "node", 4);
2100 XClearWindow(display, nodewin[i]);
2101 XDrawString(display, nodewin[i], fontgc, 2, 13, "node", 4);
2103 if ((current_image == POLY) && (current_inc == i)) {
2104 fill_button(polywin[i]);
2105 XDrawString(display, polywin[i], blackfontgc, 2, 13, "poly", 4);
2107 XClearWindow(display, polywin[i]);
2108 XDrawString(display, polywin[i], fontgc, 2, 13, "poly", 4);
2110 if ((current_image == ELE) && (current_inc == i)) {
2111 fill_button(elewin[i]);
2112 XDrawString(display, elewin[i], blackfontgc, 2, 13, "ele", 3);
2114 XClearWindow(display, elewin[i]);
2115 XDrawString(display, elewin[i], fontgc, 2, 13, "ele", 3);
2117 if ((current_image == EDGE) && (current_inc == i)) {
2118 fill_button(edgewin[i]);
2119 XDrawString(display, edgewin[i], blackfontgc, 2, 13, "edge", 4);
2121 XClearWindow(display, edgewin[i]);
2122 XDrawString(display, edgewin[i], fontgc, 2, 13, "edge", 4);
2124 if ((current_image == PART) && (current_inc == i)) {
2125 fill_button(partwin[i]);
2126 XDrawString(display, partwin[i], blackfontgc, 2, 13, "part", 4);
2128 XClearWindow(display, partwin[i]);
2129 XDrawString(display, partwin[i], fontgc, 2, 13, "part", 4);
2131 if ((current_image == ADJ) && (current_inc == i)) {
2132 fill_button(adjwin[i]);
2133 XDrawString(display, adjwin[i], blackfontgc, 2, 13, "adj", 3);
2135 XClearWindow(display, adjwin[i]);
2136 XDrawString(display, adjwin[i], fontgc, 2, 13, "adj", 3);
2138 if ((current_image == VORO) && (current_inc == i)) {
2139 fill_button(voronoiwin[i]);
2140 XDrawString(display, voronoiwin[i], blackfontgc, 2, 13, "voro", 4);
2142 XClearWindow(display, voronoiwin[i]);
2143 XDrawString(display, voronoiwin[i], fontgc, 2, 13, "voro", 4);
2147 XClearWindow(display, versionpluswin);
2148 sprintf(numberstring, "%d", loweriteration + 1);
2149 sprintf(buttonstring, "%-4.4s+", numberstring);
2150 XDrawString(display, versionpluswin, fontgc, 2, 13, buttonstring, 5);
2151 XClearWindow(display, versionminuswin);
2152 sprintf(numberstring, "%d", loweriteration);
2153 if (loweriteration == 0) {
2154 sprintf(buttonstring, "%-4.4s", numberstring);
2156 sprintf(buttonstring, "%-4.4s-", numberstring);
2158 XDrawString(display, versionminuswin, fontgc, 2, 13, buttonstring, 5);
2160 XClearWindow(display, quitwin);
2161 XDrawString(display, quitwin, fontgc, 2, 13, "Quit", 4);
2162 XClearWindow(display, leftwin);
2163 XDrawString(display, leftwin, fontgc, 2, 13, "<", 1);
2164 XClearWindow(display, rightwin);
2165 XDrawString(display, rightwin, fontgc, 2, 13, ">", 1);
2166 XClearWindow(display, upwin);
2167 XDrawString(display, upwin, fontgc, 2, 13, "^", 1);
2168 XClearWindow(display, downwin);
2169 XDrawString(display, downwin, fontgc, 2, 13, "v", 1);
2170 XClearWindow(display, resetwin);
2171 XDrawString(display, resetwin, fontgc, 2, 13, "Reset", 6);
2172 XClearWindow(display, widthpluswin);
2173 if (line_width < 100) {
2174 XDrawString(display, widthpluswin, fontgc, 2, 13, "Width+", 6);
2176 XDrawString(display, widthpluswin, fontgc, 2, 13, "Width ", 6);
2178 XClearWindow(display, widthminuswin);
2179 if (line_width > 1) {
2180 XDrawString(display, widthminuswin, fontgc, 2, 13, "-", 1);
2182 XClearWindow(display, expwin);
2183 XClearWindow(display, exppluswin);
2184 XClearWindow(display, expminuswin);
2185 XClearWindow(display, fillwin);
2186 if (current_image == PART) {
2188 fill_button(expwin);
2189 XDrawString(display, expwin, blackfontgc, 2, 13, "Exp", 3);
2191 XDrawString(display, expwin, fontgc, 2, 13, "Exp", 3);
2193 XDrawString(display, exppluswin, fontgc, 2, 13, "+", 1);
2194 XDrawString(display, expminuswin, fontgc, 2, 13, "-", 1);
2196 fill_button(fillwin);
2197 XDrawString(display, fillwin, blackfontgc, 2, 13, "Fill", 4);
2199 XDrawString(display, fillwin, fontgc, 2, 13, "Fill", 4);
2202 XClearWindow(display, pswin);
2203 XDrawString(display, pswin, fontgc, 2, 13, "PS", 2);
2204 XClearWindow(display, epswin);
2205 XDrawString(display, epswin, fontgc, 2, 13, "EPS", 3);
2208 void showme_window(argc, argv)
2212 XSetWindowAttributes attr;
2214 XGCValues fontvalues, linevalues;
2215 XColor alloc_color, exact_color;
2218 display = XOpenDisplay((char *) NULL);
2220 printf("Error: Cannot open display.\n");
2223 screen = DefaultScreen(display);
2224 rootwindow = DefaultRootWindow(display);
2225 black = BlackPixel(display, screen);
2226 white = WhitePixel(display, screen);
2227 windowdepth = DefaultDepth(display, screen);
2228 rootmap = DefaultColormap(display, screen);
2230 height = STARTHEIGHT;
2231 attr.background_pixel = black;
2232 attr.border_pixel = white;
2233 attr.backing_store = NotUseful;
2234 attr.event_mask = ExposureMask | ButtonReleaseMask | ButtonPressMask |
2235 StructureNotifyMask;
2236 attr.bit_gravity = NorthWestGravity;
2237 attr.win_gravity = NorthWestGravity;
2238 attr.save_under = False;
2239 mainwindow = XCreateWindow(display, rootwindow, 0, 0, width,
2240 height + PANELHEIGHT, 3, 0,
2241 InputOutput, CopyFromParent,
2242 CWBackPixel | CWBorderPixel | CWEventMask |
2243 CWBitGravity | CWWinGravity | CWBackingStore |
2244 CWSaveUnder, &attr);
2245 hints.width = width;
2246 hints.height = height + PANELHEIGHT;
2247 hints.min_width = MINWIDTH;
2248 hints.min_height = MINHEIGHT + PANELHEIGHT;
2249 hints.width_inc = 1;
2250 hints.height_inc = 1;
2251 hints.flags = PMinSize | PSize | PResizeInc;
2252 XSetStandardProperties(display, mainwindow, "Show Me", "showme", None,
2253 argv, argc, &hints);
2254 XChangeProperty(display, mainwindow, XA_WM_CLASS, XA_STRING, 8,
2255 PropModeReplace, "showme\0Archimedes", 18);
2256 XClearWindow(display, mainwindow);
2257 XMapWindow(display, mainwindow);
2258 if ((windowdepth > 1) &&
2259 XAllocNamedColor(display, rootmap, "yellow", &alloc_color,
2263 fontvalues.foreground = alloc_color.pixel;
2264 linevalues.foreground = alloc_color.pixel;
2265 showme_foreground = alloc_color.pixel;
2266 for (i = 0; i < 64; i++) {
2267 if (XAllocNamedColor(display, rootmap, colorname[i], &alloc_color,
2269 colors[i] = alloc_color.pixel;
2272 rgb[i].red = alloc_color.red;
2273 rgb[i].green = alloc_color.green;
2274 rgb[i].blue = alloc_color.blue;
2276 printf("Warning: I could not allocate %s.\n", colorname[i]);
2284 fontvalues.foreground = white;
2285 linevalues.foreground = white;
2286 showme_foreground = white;
2288 font = XLoadQueryFont(display, "9x15");
2289 fontvalues.background = black;
2290 fontvalues.font = font->fid;
2291 fontvalues.fill_style = FillSolid;
2292 fontvalues.line_width = 2;
2293 fontgc = XCreateGC(display, rootwindow, GCForeground | GCBackground |
2294 GCFont | GCLineWidth | GCFillStyle, &fontvalues);
2295 fontvalues.foreground = black;
2296 blackfontgc = XCreateGC(display, rootwindow, GCForeground | GCBackground |
2297 GCFont | GCLineWidth | GCFillStyle, &fontvalues);
2298 linevalues.background = black;
2299 linevalues.line_width = line_width;
2300 linevalues.cap_style = CapRound;
2301 linevalues.join_style = JoinRound;
2302 linevalues.fill_style = FillSolid;
2303 linegc = XCreateGC(display, rootwindow, GCForeground | GCBackground |
2304 GCLineWidth | GCCapStyle | GCJoinStyle | GCFillStyle,
2306 trianglegc = XCreateGC(display, rootwindow, GCForeground | GCBackground |
2307 GCLineWidth | GCCapStyle | GCJoinStyle | GCFillStyle,
2309 make_buttons(height);
2313 void draw_node(nodes, dim, ptr, xscale, yscale, xoffset, yoffset)
2326 for (i = 1; i <= nodes; i++) {
2327 XFillRectangle(display, mainwindow, linegc,
2328 (int) (ptr[index] * xscale + xoffset) - (line_width >> 1),
2329 (int) (ptr[index + 1] * yscale + yoffset) -
2330 (line_width >> 1), line_width, line_width);
2335 void draw_poly(nodes, dim, edges, holes, nodeptr, edgeptr, holeptr,
2336 xscale, yscale, xoffset, yoffset)
2351 REAL *point1, *point2;
2355 for (i = 1; i <= nodes; i++) {
2356 XFillRectangle(display, mainwindow, linegc,
2357 (int) (nodeptr[index] * xscale + xoffset) -
2359 (int) (nodeptr[index + 1] * yscale + yoffset) -
2360 (line_width >> 1), line_width, line_width);
2364 for (i = 1; i <= edges; i++) {
2365 point1 = &nodeptr[edgeptr[index++] * dim];
2366 point2 = &nodeptr[edgeptr[index++] * dim];
2367 XDrawLine(display, mainwindow, linegc,
2368 (int) (point1[0] * xscale + xoffset),
2369 (int) (point1[1] * yscale + yoffset),
2370 (int) (point2[0] * xscale + xoffset),
2371 (int) (point2[1] * yscale + yoffset));
2375 XSetForeground(display, linegc, colors[0]);
2377 for (i = 1; i <= holes; i++) {
2378 x1 = (int) (holeptr[index] * xscale + xoffset) - 3;
2379 y1 = (int) (holeptr[index + 1] * yscale + yoffset) - 3;
2382 XDrawLine(display, mainwindow, linegc, x1, y1, x2, y2);
2383 XDrawLine(display, mainwindow, linegc, x1, y2, x2, y1);
2386 XSetForeground(display, linegc, showme_foreground);
2389 void draw_ele(inc, elems, corners, ptr, partition, shift,
2390 xscale, yscale, xoffset, yoffset)
2404 REAL shiftx, shifty;
2405 REAL *prevpoint, *nowpoint;
2408 if (color && fillelem && (partition != (int *) NULL)) {
2409 vertices = (XPoint *) malloc(3 * sizeof(XPoint));
2410 if (vertices == (XPoint *) NULL) {
2411 printf("Error: Out of memory.\n");
2416 for (i = 1; i <= elems; i++) {
2417 if ((partition != (int *) NULL) && explode) {
2418 shiftx = shift[partition[i] << 1];
2419 shifty = shift[(partition[i] << 1) + 1];
2421 if (color && (partition != (int *) NULL)) {
2423 XSetForeground(display, trianglegc, colors[partition[i] & 63]);
2425 XSetForeground(display, linegc, colors[partition[i] & 63]);
2428 if (color && fillelem && (partition != (int *) NULL)) {
2429 if ((partition != (int *) NULL) && explode) {
2430 for (j = 0; j < 3; j++) {
2431 nowpoint = &nodeptr[inc][ptr[index + j] * node_dim[inc]];
2432 vertices[j].x = (nowpoint[0] + shiftx) * xscale + xoffset;
2433 vertices[j].y = (nowpoint[1] + shifty) * yscale + yoffset;
2436 for (j = 0; j < 3; j++) {
2437 nowpoint = &nodeptr[inc][ptr[index + j] * node_dim[inc]];
2438 vertices[j].x = nowpoint[0] * xscale + xoffset;
2439 vertices[j].y = nowpoint[1] * yscale + yoffset;
2442 XFillPolygon(display, mainwindow, trianglegc, vertices, 3,
2443 Convex, CoordModeOrigin);
2445 prevpoint = &nodeptr[inc][ptr[index + 2] * node_dim[inc]];
2446 if ((partition != (int *) NULL) && explode) {
2447 for (j = 0; j < 3; j++) {
2448 nowpoint = &nodeptr[inc][ptr[index++] * node_dim[inc]];
2449 XDrawLine(display, mainwindow, linegc,
2450 (int) ((prevpoint[0] + shiftx) * xscale + xoffset),
2451 (int) ((prevpoint[1] + shifty) * yscale + yoffset),
2452 (int) ((nowpoint[0] + shiftx) * xscale + xoffset),
2453 (int) ((nowpoint[1] + shifty) * yscale + yoffset));
2454 prevpoint = nowpoint;
2457 for (j = 0; j < 3; j++) {
2458 nowpoint = &nodeptr[inc][ptr[index++] * node_dim[inc]];
2459 XDrawLine(display, mainwindow, linegc,
2460 (int) (prevpoint[0] * xscale + xoffset),
2461 (int) (prevpoint[1] * yscale + yoffset),
2462 (int) (nowpoint[0] * xscale + xoffset),
2463 (int) (nowpoint[1] * yscale + yoffset));
2464 prevpoint = nowpoint;
2468 if (color && fillelem && (partition != (int *) NULL)) {
2471 XSetForeground(display, linegc, showme_foreground);
2474 void draw_edge(nodes, dim, edges, nodeptr, edgeptr, normptr,
2475 xscale, yscale, xoffset, yoffset)
2489 REAL *point1, *point2;
2491 REAL normmult, normmultx, normmulty;
2492 REAL windowxmin, windowymin, windowxmax, windowymax;
2495 for (i = 1; i <= edges; i++) {
2496 point1 = &nodeptr[edgeptr[index++] * dim];
2497 if (edgeptr[index] == -1) {
2498 normx = normptr[index - 1];
2499 normy = normptr[index++];
2502 windowxmax = (width - 1 - xoffset) / xscale;
2503 normmultx = (windowxmax - point1[0]) / normx;
2504 } else if (normx < 0) {
2505 windowxmin = -xoffset / xscale;
2506 normmultx = (windowxmin - point1[0]) / normx;
2510 windowymax = -yoffset / yscale;
2511 normmulty = (windowymax - point1[1]) / normy;
2512 } else if (normy < 0) {
2513 windowymin = (height - 1 - yoffset) / yscale;
2514 normmulty = (windowymin - point1[1]) / normy;
2516 if (normmultx == 0.0) {
2517 normmult = normmulty;
2518 } else if (normmulty == 0.0) {
2519 normmult = normmultx;
2520 } else if (normmultx < normmulty) {
2521 normmult = normmultx;
2523 normmult = normmulty;
2525 if (normmult > 0.0) {
2526 XDrawLine(display, mainwindow, linegc,
2527 (int) (point1[0] * xscale + xoffset),
2528 (int) (point1[1] * yscale + yoffset),
2529 (int) ((point1[0] + normmult * normx) * xscale + xoffset),
2530 (int) ((point1[1] + normmult * normy) * yscale + yoffset));
2533 point2 = &nodeptr[edgeptr[index++] * dim];
2534 XDrawLine(display, mainwindow, linegc,
2535 (int) (point1[0] * xscale + xoffset),
2536 (int) (point1[1] * yscale + yoffset),
2537 (int) (point2[0] * xscale + xoffset),
2538 (int) (point2[1] * yscale + yoffset));
2543 void draw_adj(dim, subdomains, ptr, center, xscale, yscale,
2555 REAL *point1, *point2;
2557 for (i = 0; i < subdomains; i++) {
2558 for (j = i + 1; j < subdomains; j++) {
2559 if (ptr[i * subdomains + j]) {
2560 point1 = ¢er[i * dim];
2561 point2 = ¢er[j * dim];
2562 XDrawLine(display, mainwindow, linegc,
2563 (int) (point1[0] * xscale + xoffset),
2564 (int) (point1[1] * yscale + yoffset),
2565 (int) (point2[0] * xscale + xoffset),
2566 (int) (point2[1] * yscale + yoffset));
2570 for (i = 0; i < subdomains; i++) {
2571 point1 = ¢er[i * dim];
2573 XSetForeground(display, linegc, colors[i & 63]);
2575 XFillArc(display, mainwindow, linegc,
2576 (int) (point1[0] * xscale + xoffset) - 5 - (line_width >> 1),
2577 (int) (point1[1] * yscale + yoffset) - 5 - (line_width >> 1),
2578 line_width + 10, line_width + 10, 0, 23040);
2580 XSetForeground(display, linegc, showme_foreground);
2583 void draw(inc, image, xmin, ymin, xmax, ymax)
2592 XClearWindow(display, mainwindow);
2593 if (image == NOTHING) {
2596 if (!loaded[inc][image]) {
2599 if ((image == PART) && explode) {
2600 xmin += (xmin - partcenter[inc][subdomains[inc] << 1]) * explosion;
2601 xmax += (xmax - partcenter[inc][subdomains[inc] << 1]) * explosion;
2602 ymin += (ymin - partcenter[inc][(subdomains[inc] << 1) + 1]) * explosion;
2603 ymax += (ymax - partcenter[inc][(subdomains[inc] << 1) + 1]) * explosion;
2605 xscale = (REAL) (width - line_width - 4) / (xmax - xmin);
2606 yscale = (REAL) (height - line_width - 4) / (ymax - ymin);
2607 if (xscale > yscale) {
2612 xoffset = 0.5 * ((REAL) width - xscale * (xmax - xmin)) -
2614 yoffset = (REAL) height - 0.5 * ((REAL) height - yscale * (ymax - ymin)) +
2619 draw_node(nodes[inc], node_dim[inc], nodeptr[inc],
2620 xscale, yscale, xoffset, yoffset);
2623 if (polynodes[inc] > 0) {
2624 draw_poly(polynodes[inc], poly_dim[inc], polyedges[inc],
2625 polyholes[inc], polynodeptr[inc], polyedgeptr[inc],
2627 xscale, yscale, xoffset, yoffset);
2629 draw_poly(nodes[inc], node_dim[inc], polyedges[inc],
2630 polyholes[inc], nodeptr[inc], polyedgeptr[inc],
2632 xscale, yscale, xoffset, yoffset);
2636 draw_ele(inc, elems[inc], ele_corners[inc], eleptr[inc],
2637 (int *) NULL, (REAL *) NULL,
2638 xscale, yscale, xoffset, yoffset);
2641 draw_edge(nodes[inc], node_dim[inc], edges[inc],
2642 nodeptr[inc], edgeptr[inc], normptr[inc],
2643 xscale, yscale, xoffset, yoffset);
2646 draw_ele(inc, elems[inc], ele_corners[inc], eleptr[inc],
2647 partpart[inc], partshift[inc],
2648 xscale, yscale, xoffset, yoffset);
2651 draw_adj(node_dim[inc], adjsubdomains[inc], adjptr[inc], partcenter[inc],
2652 xscale, yscale, xoffset, yoffset);
2655 if (loaded[inc][NODE]) {
2656 draw_node(nodes[inc], node_dim[inc], nodeptr[inc],
2657 xscale, yscale, xoffset, yoffset);
2659 draw_edge(vnodes[inc], vnode_dim[inc], vedges[inc],
2660 vnodeptr[inc], vedgeptr[inc], vnormptr[inc],
2661 xscale, yscale, xoffset, yoffset);
2668 void addps(instring, outstring, eps)
2673 strcpy(outstring, instring);
2675 strcat(outstring, ".eps");
2677 strcat(outstring, ".ps");
2681 int print_head(fname, file, llcornerx, llcornery, eps)
2689 printf("Writing %s\n", fname);
2691 *file = fopen(fname, "w");
2692 if (*file == (FILE *) NULL) {
2693 printf(" Error: Could not open %s\n", fname);
2697 fprintf(*file, "%%!PS-Adobe-2.0 EPSF-2.0\n");
2699 fprintf(*file, "%%!PS-Adobe-2.0\n");
2701 fprintf(*file, "%%%%BoundingBox: %d %d %d %d\n", llcornerx, llcornery,
2702 612 - llcornerx, 792 - llcornery);
2703 fprintf(*file, "%%%%Creator: Show Me\n");
2704 fprintf(*file, "%%%%EndComments\n\n");
2705 fprintf(*file, "1 setlinecap\n");
2706 fprintf(*file, "1 setlinejoin\n");
2707 fprintf(*file, "%d setlinewidth\n", line_width);
2708 fprintf(*file, "%d %d moveto\n", llcornerx, llcornery);
2709 fprintf(*file, "%d %d lineto\n", 612 - llcornerx, llcornery);
2710 fprintf(*file, "%d %d lineto\n", 612 - llcornerx, 792 - llcornery);
2711 fprintf(*file, "%d %d lineto\n", llcornerx, 792 - llcornery);
2712 fprintf(*file, "closepath\nclip\nnewpath\n");
2716 void print_node(nodefile, nodes, dim, ptr, xscale, yscale,
2731 for (i = 1; i <= nodes; i++) {
2732 fprintf(nodefile, "%d %d %d 0 360 arc\nfill\n",
2733 (int) (ptr[index] * xscale + xoffset),
2734 (int) (ptr[index + 1] * yscale + yoffset),
2735 1 + (line_width >> 1));
2740 void print_poly(polyfile, nodes, dim, edges, holes, nodeptr, edgeptr, holeptr,
2741 xscale, yscale, xoffset, yoffset)
2757 REAL *point1, *point2;
2760 for (i = 1; i <= nodes; i++) {
2761 fprintf(polyfile, "%d %d %d 0 360 arc\nfill\n",
2762 (int) (nodeptr[index] * xscale + xoffset),
2763 (int) (nodeptr[index + 1] * yscale + yoffset),
2764 1 + (line_width >> 1));
2768 for (i = 1; i <= edges; i++) {
2769 point1 = &nodeptr[edgeptr[index++] * dim];
2770 point2 = &nodeptr[edgeptr[index++] * dim];
2771 fprintf(polyfile, "%d %d moveto\n",
2772 (int) (point1[0] * xscale + xoffset),
2773 (int) (point1[1] * yscale + yoffset));
2774 fprintf(polyfile, "%d %d lineto\nstroke\n",
2775 (int) (point2[0] * xscale + xoffset),
2776 (int) (point2[1] * yscale + yoffset));
2780 void print_ele(elefile, nodes, dim, elems, corners, nodeptr, eleptr,
2782 xscale, yscale, xoffset, yoffset, llcornerx, llcornery)
2800 int index, colorindex;
2801 REAL shiftx, shifty;
2805 if ((partition != (int *) NULL) && !bw_ps) {
2806 fprintf(elefile, "0 0 0 setrgbcolor\n");
2807 fprintf(elefile, "%d %d moveto\n", llcornerx, llcornery);
2808 fprintf(elefile, "%d %d lineto\n", 612 - llcornerx, llcornery);
2809 fprintf(elefile, "%d %d lineto\n", 612 - llcornerx, 792 - llcornery);
2810 fprintf(elefile, "%d %d lineto\n", llcornerx, 792 - llcornery);
2811 fprintf(elefile, "fill\n");
2813 for (i = 1; i <= elems; i++) {
2814 if ((partition != (int *) NULL) && !bw_ps) {
2815 colorindex = partition[i] & 63;
2816 fprintf(elefile, "%6.3f %6.3f %6.3f setrgbcolor\n",
2817 (REAL) rgb[colorindex].red / 65535.0,
2818 (REAL) rgb[colorindex].green / 65535.0,
2819 (REAL) rgb[colorindex].blue / 65535.0);
2821 nowpoint = &nodeptr[eleptr[index + 2] * dim];
2822 if ((partition != (int *) NULL) && (explode || bw_ps)) {
2823 shiftx = shift[partition[i] << 1];
2824 shifty = shift[(partition[i] << 1) + 1];
2825 fprintf(elefile, "%d %d moveto\n",
2826 (int) ((nowpoint[0] + shiftx) * xscale + xoffset),
2827 (int) ((nowpoint[1] + shifty) * yscale + yoffset));
2828 for (j = 0; j < 3; j++) {
2829 nowpoint = &nodeptr[eleptr[index++] * dim];
2830 fprintf(elefile, "%d %d lineto\n",
2831 (int) ((nowpoint[0] + shiftx) * xscale + xoffset),
2832 (int) ((nowpoint[1] + shifty) * yscale + yoffset));
2835 fprintf(elefile, "%d %d moveto\n",
2836 (int) (nowpoint[0] * xscale + xoffset),
2837 (int) (nowpoint[1] * yscale + yoffset));
2838 for (j = 0; j < 3; j++) {
2839 nowpoint = &nodeptr[eleptr[index++] * dim];
2840 fprintf(elefile, "%d %d lineto\n",
2841 (int) (nowpoint[0] * xscale + xoffset),
2842 (int) (nowpoint[1] * yscale + yoffset));
2845 if (fillelem && !bw_ps) {
2846 fprintf(elefile, "gsave\nfill\ngrestore\n1 1 0 setrgbcolor\n");
2848 fprintf(elefile, "stroke\n");
2852 void print_edge(edgefile, nodes, dim, edges, nodeptr, edgeptr, normptr,
2853 xscale, yscale, xoffset, yoffset, llcornerx, llcornery)
2870 REAL *point1, *point2;
2872 REAL normmult, normmultx, normmulty;
2873 REAL windowxmin, windowymin, windowxmax, windowymax;
2876 for (i = 1; i <= edges; i++) {
2877 point1 = &nodeptr[edgeptr[index++] * dim];
2878 if (edgeptr[index] == -1) {
2879 normx = normptr[index - 1];
2880 normy = normptr[index++];
2883 windowxmax = ((REAL) (612 - llcornerx) - xoffset) / xscale;
2884 normmultx = (windowxmax - point1[0]) / normx;
2885 } else if (normx < 0) {
2886 windowxmin = ((REAL) llcornerx - xoffset) / xscale;
2887 normmultx = (windowxmin - point1[0]) / normx;
2891 windowymax = ((REAL) (792 - llcornery) - yoffset) / yscale;
2892 normmulty = (windowymax - point1[1]) / normy;
2893 } else if (normy < 0) {
2894 windowymin = ((REAL) llcornery - yoffset) / yscale;
2895 normmulty = (windowymin - point1[1]) / normy;
2897 if (normmultx == 0.0) {
2898 normmult = normmulty;
2899 } else if (normmulty == 0.0) {
2900 normmult = normmultx;
2901 } else if (normmultx < normmulty) {
2902 normmult = normmultx;
2904 normmult = normmulty;
2906 if (normmult > 0.0) {
2907 fprintf(edgefile, "%d %d moveto\n",
2908 (int) (point1[0] * xscale + xoffset),
2909 (int) (point1[1] * yscale + yoffset));
2910 fprintf(edgefile, "%d %d lineto\nstroke\n",
2911 (int) ((point1[0] + normmult * normx) * xscale + xoffset),
2912 (int) ((point1[1] + normmult * normy) * yscale + yoffset));
2915 point2 = &nodeptr[edgeptr[index++] * dim];
2916 fprintf(edgefile, "%d %d moveto\n",
2917 (int) (point1[0] * xscale + xoffset),
2918 (int) (point1[1] * yscale + yoffset));
2919 fprintf(edgefile, "%d %d lineto\nstroke\n",
2920 (int) (point2[0] * xscale + xoffset),
2921 (int) (point2[1] * yscale + yoffset));
2926 void print_adj(adjfile, dim, subdomains, ptr, center, xscale, yscale,
2927 xoffset, yoffset, llcornerx, llcornery)
2941 REAL *point1, *point2;
2945 fprintf(adjfile, "0 0 0 setrgbcolor\n");
2946 fprintf(adjfile, "%d %d moveto\n", llcornerx, llcornery);
2947 fprintf(adjfile, "%d %d lineto\n", 612 - llcornerx, llcornery);
2948 fprintf(adjfile, "%d %d lineto\n", 612 - llcornerx, 792 - llcornery);
2949 fprintf(adjfile, "%d %d lineto\n", llcornerx, 792 - llcornery);
2950 fprintf(adjfile, "fill\n");
2951 fprintf(adjfile, "1 1 0 setrgbcolor\n");
2953 for (i = 0; i < subdomains; i++) {
2954 for (j = i + 1; j < subdomains; j++) {
2955 if (ptr[i * subdomains + j]) {
2956 point1 = ¢er[i * dim];
2957 point2 = ¢er[j * dim];
2958 fprintf(adjfile, "%d %d moveto\n",
2959 (int) (point1[0] * xscale + xoffset),
2960 (int) (point1[1] * yscale + yoffset));
2961 fprintf(adjfile, "%d %d lineto\nstroke\n",
2962 (int) (point2[0] * xscale + xoffset),
2963 (int) (point2[1] * yscale + yoffset));
2967 for (i = 0; i < subdomains; i++) {
2968 point1 = ¢er[i * dim];
2970 colorindex = i & 63;
2971 fprintf(adjfile, "%6.3f %6.3f %6.3f setrgbcolor\n",
2972 (REAL) rgb[colorindex].red / 65535.0,
2973 (REAL) rgb[colorindex].green / 65535.0,
2974 (REAL) rgb[colorindex].blue / 65535.0);
2975 fprintf(adjfile, "%d %d %d 0 360 arc\nfill\n",
2976 (int) (point1[0] * xscale + xoffset),
2977 (int) (point1[1] * yscale + yoffset),
2978 5 + (line_width >> 1));
2980 fprintf(adjfile, "%d %d %d 0 360 arc\nfill\n",
2981 (int) (point1[0] * xscale + xoffset),
2982 (int) (point1[1] * yscale + yoffset),
2983 3 + (line_width >> 1));
2988 void print(inc, image, xmin, ymin, xmax, ymax, eps)
2997 REAL xxscale, yyscale, xxoffset, yyoffset;
2998 char psfilename[FILENAMESIZE];
2999 int llcornerx, llcornery;
3002 if (image == NOTHING) {
3005 if (!loaded[inc][image]) {
3008 if ((image == PART) && (explode || bw_ps)) {
3009 xmin += (xmin - partcenter[inc][subdomains[inc] << 1]) * explosion;
3010 xmax += (xmax - partcenter[inc][subdomains[inc] << 1]) * explosion;
3011 ymin += (ymin - partcenter[inc][(subdomains[inc] << 1) + 1]) * explosion;
3012 ymax += (ymax - partcenter[inc][(subdomains[inc] << 1) + 1]) * explosion;
3014 xxscale = (460.0 - (REAL) line_width) / (xmax - xmin);
3015 yyscale = (640.0 - (REAL) line_width) / (ymax - ymin);
3016 if (xxscale > yyscale) {
3018 llcornerx = (604 - (int) (yyscale * (xmax - xmin)) - line_width) >> 1;
3023 llcornery = (784 - (int) (xxscale * (ymax - ymin)) - line_width) >> 1;
3025 xxoffset = 0.5 * (612.0 - xxscale * (xmax - xmin)) - xxscale * xmin +
3027 yyoffset = 0.5 * (792.0 - yyscale * (ymax - ymin)) - yyscale * ymin +
3031 addps(nodefilename[inc], psfilename, eps);
3034 addps(polyfilename[inc], psfilename, eps);
3037 addps(elefilename[inc], psfilename, eps);
3040 addps(edgefilename[inc], psfilename, eps);
3043 addps(partfilename[inc], psfilename, eps);
3046 addps(adjfilename[inc], psfilename, eps);
3049 addps(vedgefilename[inc], psfilename, eps);
3054 if (print_head(psfilename, &psfile, llcornerx, llcornery, eps)) {
3059 print_node(psfile, nodes[inc], node_dim[inc], nodeptr[inc],
3060 xxscale, yyscale, xxoffset, yyoffset);
3063 if (polynodes[inc] > 0) {
3064 print_poly(psfile, polynodes[inc], poly_dim[inc], polyedges[inc],
3065 polyholes[inc], polynodeptr[inc], polyedgeptr[inc],
3066 polyholeptr[inc], xxscale, yyscale, xxoffset, yyoffset);
3068 print_poly(psfile, nodes[inc], node_dim[inc], polyedges[inc],
3069 polyholes[inc], nodeptr[inc], polyedgeptr[inc],
3070 polyholeptr[inc], xxscale, yyscale, xxoffset, yyoffset);
3074 print_ele(psfile, nodes[inc], node_dim[inc], elems[inc],
3075 ele_corners[inc], nodeptr[inc], eleptr[inc],
3076 (int *) NULL, (REAL *) NULL,
3077 xxscale, yyscale, xxoffset, yyoffset, llcornerx, llcornery);
3080 print_edge(psfile, nodes[inc], node_dim[inc], edges[inc],
3081 nodeptr[inc], edgeptr[inc], normptr[inc],
3082 xxscale, yyscale, xxoffset, yyoffset, llcornerx, llcornery);
3085 print_ele(psfile, nodes[inc], node_dim[inc], elems[inc],
3086 ele_corners[inc], nodeptr[inc], eleptr[inc],
3087 partpart[inc], partshift[inc],
3088 xxscale, yyscale, xxoffset, yyoffset, llcornerx, llcornery);
3091 print_adj(psfile, node_dim[inc], adjsubdomains[inc], adjptr[inc],
3093 xxscale, yyscale, xxoffset, yyoffset, llcornerx, llcornery);
3096 print_edge(psfile, vnodes[inc], vnode_dim[inc], vedges[inc],
3097 vnodeptr[inc], vedgeptr[inc], vnormptr[inc],
3098 xxscale, yyscale, xxoffset, yyoffset, llcornerx, llcornery);
3104 fprintf(psfile, "showpage\n");
3109 int main(argc, argv)
3113 REAL xmin, ymin, xmax, ymax;
3114 REAL xptr, yptr, xspan, yspan;
3119 parsecommandline(argc, argv);
3121 choose_image(start_inc, start_image);
3122 showme_window(argc, argv);
3124 if (current_image != NOTHING) {
3125 xmin = xlo[current_inc][current_image];
3126 ymin = ylo[current_inc][current_image];
3127 xmax = xhi[current_inc][current_image];
3128 ymax = yhi[current_inc][current_image];
3132 XMaskEvent(display, ExposureMask, &event);
3134 switch (event.type) {
3136 if (event.xany.window == quitwin) {
3137 XDestroyWindow(display, mainwindow);
3138 XCloseDisplay(display);
3140 } else if (event.xany.window == leftwin) {
3141 xspan = 0.25 * (xmax - xmin);
3144 draw(current_inc, current_image, xmin, ymin, xmax, ymax);
3145 } else if (event.xany.window == rightwin) {
3146 xspan = 0.25 * (xmax - xmin);
3149 draw(current_inc, current_image, xmin, ymin, xmax, ymax);
3150 } else if (event.xany.window == upwin) {
3151 yspan = 0.25 * (ymax - ymin);
3154 draw(current_inc, current_image, xmin, ymin, xmax, ymax);
3155 } else if (event.xany.window == downwin) {
3156 yspan = 0.25 * (ymax - ymin);
3159 draw(current_inc, current_image, xmin, ymin, xmax, ymax);
3160 } else if (event.xany.window == resetwin) {
3161 xmin = xlo[current_inc][current_image];
3162 ymin = ylo[current_inc][current_image];
3163 xmax = xhi[current_inc][current_image];
3164 ymax = yhi[current_inc][current_image];
3166 draw(current_inc, current_image, xmin, ymin, xmax, ymax);
3167 } else if (event.xany.window == widthpluswin) {
3168 if (line_width < 100) {
3170 XSetLineAttributes(display, linegc, line_width, LineSolid,
3171 CapRound, JoinRound);
3172 XSetLineAttributes(display, trianglegc, line_width, LineSolid,
3173 CapRound, JoinRound);
3174 draw(current_inc, current_image, xmin, ymin, xmax, ymax);
3176 } else if (event.xany.window == widthminuswin) {
3177 if (line_width > 1) {
3179 XSetLineAttributes(display, linegc, line_width, LineSolid,
3180 CapRound, JoinRound);
3181 XSetLineAttributes(display, trianglegc, line_width, LineSolid,
3182 CapRound, JoinRound);
3183 draw(current_inc, current_image, xmin, ymin, xmax, ymax);
3185 } else if (event.xany.window == expwin) {
3186 if ((current_image == PART) && loaded[current_inc][PART]) {
3188 draw(current_inc, current_image, xmin, ymin, xmax, ymax);
3190 } else if (event.xany.window == exppluswin) {
3191 if ((current_image == PART) && loaded[PART] && explode) {
3193 findpartshift(subdomains[current_inc], explosion,
3194 partcenter[current_inc], partshift[current_inc]);
3195 draw(current_inc, current_image, xmin, ymin, xmax, ymax);
3197 } else if (event.xany.window == expminuswin) {
3198 if ((current_image == PART) && loaded[PART] && explode &&
3199 (explosion >= 0.125)) {
3201 findpartshift(subdomains[current_inc], explosion,
3202 partcenter[current_inc], partshift[current_inc]);
3203 draw(current_inc, current_image, xmin, ymin, xmax, ymax);
3205 } else if (event.xany.window == fillwin) {
3206 if ((current_image == PART) && loaded[PART]) {
3207 fillelem = !fillelem;
3208 draw(current_inc, current_image, xmin, ymin, xmax, ymax);
3210 } else if (event.xany.window == pswin) {
3213 print(current_inc, current_image, xmin, ymin, xmax, ymax, 0);
3214 XClearWindow(display, pswin);
3215 XDrawString(display, pswin, fontgc, 2, 13, "PS", 2);
3216 } else if (event.xany.window == epswin) {
3217 fill_button(epswin);
3219 print(current_inc, current_image, xmin, ymin, xmax, ymax, 1);
3220 XClearWindow(display, epswin);
3221 XDrawString(display, epswin, fontgc, 2, 13, "EPS", 3);
3222 } else if (event.xany.window == versionpluswin) {
3225 set_filenames(filename, loweriteration);
3226 if (current_inc == 1) {
3229 current_image = NOTHING;
3230 XClearWindow(display, mainwindow);
3233 } else if (event.xany.window == versionminuswin) {
3234 if (loweriteration > 0) {
3237 set_filenames(filename, loweriteration);
3238 if (current_inc == 0) {
3241 current_image = NOTHING;
3242 XClearWindow(display, mainwindow);
3246 } else if ((event.xany.window == nodewin[0]) ||
3247 (event.xany.window == polywin[0]) ||
3248 (event.xany.window == elewin[0]) ||
3249 (event.xany.window == edgewin[0]) ||
3250 (event.xany.window == partwin[0]) ||
3251 (event.xany.window == adjwin[0]) ||
3252 (event.xany.window == voronoiwin[0]) ||
3253 (event.xany.window == nodewin[1]) ||
3254 (event.xany.window == polywin[1]) ||
3255 (event.xany.window == elewin[1]) ||
3256 (event.xany.window == edgewin[1]) ||
3257 (event.xany.window == partwin[1]) ||
3258 (event.xany.window == adjwin[1]) ||
3259 (event.xany.window == voronoiwin[1])) {
3260 if (event.xany.window == nodewin[0]) {
3264 if (event.xany.window == polywin[0]) {
3268 if (event.xany.window == elewin[0]) {
3272 if (event.xany.window == edgewin[0]) {
3276 if (event.xany.window == partwin[0]) {
3280 if (event.xany.window == adjwin[0]) {
3284 if (event.xany.window == voronoiwin[0]) {
3288 if (event.xany.window == nodewin[1]) {
3292 if (event.xany.window == polywin[1]) {
3296 if (event.xany.window == elewin[1]) {
3300 if (event.xany.window == edgewin[1]) {
3304 if (event.xany.window == partwin[1]) {
3308 if (event.xany.window == adjwin[1]) {
3312 if (event.xany.window == voronoiwin[1]) {
3316 past_image = current_image;
3317 if ((current_inc == new_inc) && (current_image == new_image)) {
3319 unload_inc(new_inc);
3321 choose_image(new_inc, new_image);
3322 if ((past_image == NOTHING) && (current_image != NOTHING)) {
3323 xmin = xlo[current_inc][current_image];
3324 ymin = ylo[current_inc][current_image];
3325 xmax = xhi[current_inc][current_image];
3326 ymax = yhi[current_inc][current_image];
3329 draw(current_inc, current_image, xmin, ymin, xmax, ymax);
3331 xptr = ((REAL) event.xbutton.x - xoffset) / xscale;
3332 yptr = ((REAL) event.xbutton.y - yoffset) / yscale;
3333 if ((current_image == PART) && loaded[PART] && explode) {
3334 xptr = (xptr + partcenter[current_inc]
3335 [subdomains[current_inc] << 1]
3336 * explosion) / (1.0 + explosion);
3337 yptr = (yptr + partcenter[current_inc]
3338 [(subdomains[current_inc] << 1) + 1]
3339 * explosion) / (1.0 + explosion);
3341 if ((event.xbutton.button == Button1)
3342 || (event.xbutton.button == Button3)) {
3343 if (event.xbutton.button == Button1) {
3344 xspan = 0.25 * (xmax - xmin);
3345 yspan = 0.25 * (ymax - ymin);
3348 xspan = xmax - xmin;
3349 yspan = ymax - ymin;
3352 xmin = xptr - xspan;
3353 ymin = yptr - yspan;
3354 xmax = xptr + xspan;
3355 ymax = yptr + yspan;
3356 draw(current_inc, current_image, xmin, ymin, xmax, ymax);
3357 } else if (event.xbutton.button == Button2) {
3358 printf("x = %.4g, y = %.4g\n", xptr, yptr);
3363 XDestroyWindow(display, mainwindow);
3364 XCloseDisplay(display);
3366 case ConfigureNotify:
3367 if ((width != event.xconfigure.width) ||
3368 (height != event.xconfigure.height - PANELHEIGHT)) {
3369 width = event.xconfigure.width;
3370 height = event.xconfigure.height - PANELHEIGHT;
3371 draw(current_inc, current_image, xmin, ymin, xmax, ymax);
3372 while (XCheckMaskEvent(display, ExposureMask, &event));
3376 draw(current_inc, current_image, xmin, ymin, xmax, ymax);
3377 while (XCheckMaskEvent(display, ExposureMask, &event));
3382 XNextEvent(display, &event);