ronbo@vixen.uucp (Ron Hitchens) (12/17/88)
In article <2401@ssc-vax.UUCP> coy@ssc-vax.UUCP (Stephen B Coy) writes: >In article <108@avatar.UUCP>, kory@avatar.UUCP (Kory Hamzeh) writes: >> >> I found a possible bug in the Teapot conversion program that was ... >> >> Kory Hamzeh UUCP: ..!uunet!psivax!quad1!avatar!kory >> INTERNET: avatar!kory@quad.com > > [info on bug deleted] > > Yes, this is a problem. The original poster of the conversion > program(I think) also mentioned that MTV produced "glitches" on the > spout and handle of the teapot. These appear because in these > regions the 4-gons are not planar. A quick n dirty solution is to > modify the conversion program to split each 4-gon into 2 triangles. > Then for each triangle compare the vertices against each other and > only keep those triangles with three unique vertices. You would > also be wise to ensure that the vertices are not colinear. > > Stephen Coy > uw-beaver!ssc-vax!coy Yo, that's me, I'm the original poster. I posted the program which generates an NFF file that produces the Utah teapot, which was a modification of a program posted by Dean Jones at AT&T which drew it with SunCore (which I think he probably modified from something else...). I apologize if anyone has been trying to reach me about it and couldn't, my machine was down for nearly two months and I'm just now getting caught up on news and mail again. Anyway, Stephen is exactly right. The original program I posted was buggy, it suffered from precisely the problems he describes. The code I posted was the product of one long night's hacking, I finally got it to produce something that looked like a teapot (some of the early atempts were pretty psychadelic) and I quit at that point. I have a little time on my hands at the moment, so I played around with this thing a bit and made the changes Stephen recommends, it now works a lot better. I'm reposting the whole thing below since it's fairly small. Somebody let me know if there's still something I've missed. If someone comes up with a more aestheticly pleasing combination of color/ lighting/viewing angle let me know. I just sort of arbitrarily placed lights and picked a color. I decided not to make the teapot shiny because the reflections get all broken up by the "facets" of the teapot and look ugly. So, I decided my teapot is made of glazed ceramic rather than shiny gold :-) Somebody really ought to generate the data for a teacup to match this teapot. Any volunteers? Ron Hitchens ronbo@vixen.uucp hitchens@cs.utexas.edu ----- # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Wrapped by vixen!ronbo on Fri Dec 16 12:04:52 CST 1988 # Contents: Makefile tea.h raypot.c ducks.c patches.c echo x - Makefile sed 's/^@//' > "Makefile" <<'@//E*O*F Makefile//' OFILES= tea.o patches.o ducks.o RAYOFILES= raypot.o patches.o ducks.o LIBS= -lcore -lsunwindow -lpixrect -lm CFLAGS= -O -f68881 raypot: $(RAYOFILES) $(CC) $(CFLAGS) -o $@ $(RAYOFILES) tea: $(OFILES) $(CC) $(CFLAGS) -o $@ $(OFILES) $(LIBS) @//E*O*F Makefile// chmod u=rw,g=r,o=r Makefile echo x - tea.h sed 's/^@//' > "tea.h" <<'@//E*O*F tea.h//' #define DEGREE 4 #define DUCK_COUNT 306 #define PATCH_COUNT 32 typedef struct { float x, y, z; } dt; typedef int pt[DEGREE][DEGREE]; @//E*O*F tea.h// chmod u=rw,g=r,o=r tea.h echo x - raypot.c sed 's/^@//' > "raypot.c" <<'@//E*O*F raypot.c//' /* * Ray-trace the University of Utah Teapot * * This code generates an NFF file of a teapot sitting on a polished * table. It uses the patch data to generate triangular polygons. * A step count may be given as an argument. If so, the patches will * be divided down into smaller subpatches. * The default granularity of 6 looks adequate and generates about 2200 * 3-gons. I prefer a granularity of 12, the resulting curves are * nice and smooth, the teapot's lid looks especially nice. A little * over 10,000 3-gons will be generated by a step rate of 12, if * you want to go higher than that, be careful you don't blow the limits * of your raytracer. * The output NFF file, written to stdout, is intended for input to * Mark VandeWettering's (MTV) ray tracer, but could easily be adapted * for other software that takes lists of polygons. * * Posted SunCore version by Dean S. Jones (dean@homxb.uucp) * Ray trace/polygon mods by Ron Hitchens (ronbo@vixen.uucp) * * This is version 2, the patches are now rendered using pairs of * triangles rather than 4-gons for each patch. The data describing * the teapot patches does not guarantee that all four corners of a * given patch will lie in the same plane, which is an assumption I * made in the first version. This is in fact the case in some of the * patches describing the spout and handle. This version also clips * any triangle which does not have three unique points. The patches * describing the top of the knob on the lid and the very bottom of the * pot converge on the Z axis and hence there are several triangles * with two corners at the same point. A fully general solution would * also check that all three points don't lie on the same line, but I * don't know how to do that offhand, and this little hack isn't worth * the effort of looking it up. * Ron Hitchens, Dec 1988 * */ #include <stdio.h> #include "tea.h" #define MAX_STEPS 50 #define SAME_POINT(a,b) ((a.x == b.x) && (a.y == b.y) && (a.z == b.z)) #define UNIQUE3(a,b,c) ((!SAME_POINT(a,b)) && (!SAME_POINT(b,c)) && \ (!SAME_POINT(a,c))) extern dt ducks [DUCK_COUNT]; extern pt patches [PATCH_COUNT]; char *nff_hdr [] = { "v", /* viewport parms */ "from 1.5 -7.9 5.1", "at 0 0 1", "up 0 0 1", "angle 45", "hither 1", "resolution 512 512", /* image size */ "b 0.078 0.361 0.753", /* background color */ "l 8 -4 6", /* lights */ "l -1 -3 5", "l -1 -4 9", "l -2 -4 .4", "f 1 0.85 0.7 0.75 0.5 25 0 0", /* surface properties */ "p 4", /* table top square */ "6 6 0", "-6 6 0", "-6 -6 0", "6 -6 0", "f 1 .47 0 1 0 30 0 0", /* surf props for teapot */ "#" }; main (argc, argv) int argc; char *argv[]; { int i, s = 6; if (argc > 1) { s = atoi (argv [1]); s = (s > 0) ? s : 6; if (s > MAX_STEPS) { fprintf (stderr, "max step size is %d\n", MAX_STEPS); exit (1); } } printf ("#\n# The University of Utah Teapot, granularity=%d\n#\n", s); for (i = 0; i < sizeof (nff_hdr) / sizeof (char *); i++) { printf ("%s\n", nff_hdr [i]); } display_patches (s); exit (0); } void blend_vector (d0, d1, d2, d3, t, r) dt d0, d1, d2, d3; float t; dt *r; { r->x = d0.x*(1-t)*(1-t)*(1-t) + d1.x*3*t*(1-t)*(1-t) + d2.x*3*t*t*(1-t) + d3.x*t*t*t; r->y = d0.y*(1-t)*(1-t)*(1-t) + d1.y*3*t*(1-t)*(1-t) + d2.y*3*t*t*(1-t) + d3.y*t*t*t; r->z = d0.z*(1-t)*(1-t)*(1-t) + d1.z*3*t*(1-t)*(1-t) + d2.z*3*t*t*(1-t) + d3.z*t*t*t; } /* * The name "display_curve" is a bit of a misnomer. It's function in * the original program was to draw the curved line described by the * given four points, in the number of increments indicated by steps. * Since this guy now generates polygons that fill in the space between * the lines, it needs the points from adjacent pairs of these curves. * Rather than reorganizing the whole structure of the program, this * function generates the points on the curve as it did before, saves * them in a static array and returns. When all the curves for a given * patch have been generated (deducible from the number of steps) it * passes the array and dumps out all the polygons, then resets for the * next patch. A bit of hack, but it works. */ void display_curve (d0, d1, d2, d3, steps) dt d0, d1, d2, d3; int steps; { dt tmp; float t, step; int i = 0, j; static int count = 0; static dt p [MAX_STEPS+1][MAX_STEPS+1]; t = step = (1.0 / (float)steps); p [count][0] = d0; while (t < (1.0 + step / 2.0)) { blend_vector (d0, d1, d2, d3, t, &tmp); p [count][++i] = tmp; t += step; } count++; if (count <= steps) { return; } for (i = 0; i < steps; i++) { for (j = 0; j < steps; j++) { if (UNIQUE3 (p [i][j+1], p [i][j], p [i+1][j])) { printf ("p 3\n"); printf ("%f %f %f\n", p [i][j+1].x, p [i][j+1].y, p [i][j+1].z); printf ("%f %f %f\n", p [i][j].x, p [i][j].y, p [i][j].z); printf ("%f %f %f\n", p [i+1][j].x, p [i+1][j].y, p [i+1][j].z); } else { printf ("# triangle 1 clipped\n"); } if (UNIQUE3 (p [i+1][j], p [i+1][j+1], p [i][j+1])) { printf ("p 3\n"); printf ("%f %f %f\n", p [i+1][j].x, p [i+1][j].y, p [i+1][j].z); printf ("%f %f %f\n", p [i+1][j+1].x, p [i+1][j+1].y, p [i+1][j+1].z); printf ("%f %f %f\n", p [i][j+1].x, p [i][j+1].y, p [i][j+1].z); } else { printf ("# triangle 2 clipped\n"); } } } count = 0; } void display_patch (patch, steps) pt patch; int steps; { float t, step; dt d0, d1, d2, d3; int i; t = 0; step = (1.0 / (float)steps); while(t < (1.0 + step / 2.0)) { blend_vector(ducks[patch[0][0]-1],ducks[patch[0][1]-1], ducks[patch[0][2]-1],ducks[patch[0][3]-1], t, &d0); blend_vector(ducks[patch[1][0]-1],ducks[patch[1][1]-1], ducks[patch[1][2]-1],ducks[patch[1][3]-1], t, &d1); blend_vector(ducks[patch[2][0]-1],ducks[patch[2][1]-1], ducks[patch[2][2]-1],ducks[patch[2][3]-1], t, &d2); blend_vector(ducks[patch[3][0]-1],ducks[patch[3][1]-1], ducks[patch[3][2]-1],ducks[patch[3][3]-1], t, &d3); display_curve (d0, d1, d2, d3, steps); t += step; } } display_patches (s) int s; { int i; for (i = 0; i < PATCH_COUNT; i++) { printf ("# patch #%d\n", i); display_patch (patches [i], s); } } @//E*O*F raypot.c// chmod u=rw,g=r,o=r raypot.c echo x - ducks.c sed 's/^@//' > "ducks.c" <<'@//E*O*F ducks.c//' #include "tea.h" dt ducks[DUCK_COUNT] = { {1.4,0.0,2.4}, {1.4,-0.784,2.4}, {0.784,-1.4,2.4}, {0.0,-1.4,2.4}, {1.3375,0.0,2.53125}, {1.3375,-0.749,2.53125}, {0.749,-1.3375,2.53125}, {0.0,-1.3375,2.53125}, {1.4375,0.0,2.53125}, {1.4375,-0.805,2.53125}, {0.805,-1.4375,2.53125}, {0.0,-1.4375,2.53125}, {1.5,0.0,2.4}, {1.5,-0.84,2.4}, {0.84,-1.5,2.4}, {0.0,-1.5,2.4}, {-0.784,-1.4,2.4}, {-1.4,-0.784,2.4}, {-1.4,0.0,2.4}, {-0.749,-1.3375,2.53125}, {-1.3375,-0.749,2.53125}, {-1.3375,0.0,2.53125}, {-0.805,-1.4375,2.53125}, {-1.4375,-0.805,2.53125}, {-1.4375,0.0,2.53125}, {-0.84,-1.5,2.4}, {-1.5,-0.84,2.4}, {-1.5,0.0,2.4}, {-1.4,0.784,2.4}, {-0.784,1.4,2.4}, {0.0,1.4,2.4}, {-1.3375,0.749,2.53125}, {-0.749,1.3375,2.53125}, {0.0,1.3375,2.53125}, {-1.4375,0.805,2.53125}, {-0.805,1.4375,2.53125}, {0.0,1.4375,2.53125}, {-1.5,0.84,2.4}, {-0.84,1.5,2.4}, {0.0,1.5,2.4}, {0.784,1.4,2.4}, {1.4,0.784,2.4}, {0.749,1.3375,2.53125}, {1.3375,0.749,2.53125}, {0.805,1.4375,2.53125}, {1.4375,0.805,2.53125}, {0.84,1.5,2.4}, {1.5,0.84,2.4}, {1.75,0.0,1.875}, {1.75,-0.98,1.875}, {0.98,-1.75,1.875}, {0.0,-1.75,1.875}, {2.0,0.0,1.35}, {2.0,-1.12,1.35}, {1.12,-2.0,1.35}, {0.0,-2.0,1.35}, {2.0,0.0,0.9}, {2.0,-1.12,0.9}, {1.12,-2.0,0.9}, {0.0,-2.0,0.9}, {-0.98,-1.75,1.875}, {-1.75,-0.98,1.875}, {-1.75,0.0,1.875}, {-1.12,-2.0,1.35}, {-2.0,-1.12,1.35}, {-2.0,0.0,1.35}, {-1.12,-2.0,0.9}, {-2.0,-1.12,0.9}, {-2.0,0.0,0.9}, {-1.75,0.98,1.875}, {-0.98,1.75,1.875}, {0.0,1.75,1.875}, {-2.0,1.12,1.35}, {-1.12,2.0,1.35}, {0.0,2.0,1.35}, {-2.0,1.12,0.9}, {-1.12,2.0,0.9}, {0.0,2.0,0.9}, {0.98,1.75,1.875}, {1.75,0.98,1.875}, {1.12,2.0,1.35}, {2.0,1.12,1.35}, {1.12,2.0,0.9}, {2.0,1.12,0.9}, {2.0,0.0,0.45}, {2.0,-1.12,0.45}, {1.12,-2.0,0.45}, {0.0,-2.0,0.45}, {1.5,0.0,0.225}, {1.5,-0.84,0.225}, {0.84,-1.5,0.225}, {0.0,-1.5,0.225}, {1.5,0.0,0.15}, {1.5,-0.84,0.15}, {0.84,-1.5,0.15}, {0.0,-1.5,0.15}, {-1.12,-2.0,0.45}, {-2.0,-1.12,0.45}, {-2.0,0.0,0.45}, {-0.84,-1.5,0.225}, {-1.5,-0.84,0.225}, {-1.5,0.0,0.225}, {-0.84,-1.5,0.15}, {-1.5,-0.84,0.15}, {-1.5,0.0,0.15}, {-2.0,1.12,0.45}, {-1.12,2.0,0.45}, {0.0,2.0,0.45}, {-1.5,0.84,0.225}, {-0.84,1.5,0.225}, {0.0,1.5,0.225}, {-1.5,0.84,0.15}, {-0.84,1.5,0.15}, {0.0,1.5,0.15}, {1.12,2.0,0.45}, {2.0,1.12,0.45}, {0.84,1.5,0.225}, {1.5,0.84,0.225}, {0.84,1.5,0.15}, {1.5,0.84,0.15}, {-1.6,0.0,2.025}, {-1.6,-0.3,2.025}, {-1.5,-0.3,2.25}, {-1.5,0.0,2.25}, {-2.3,0.0,2.025}, {-2.3,-0.3,2.025}, {-2.5,-0.3,2.25}, {-2.5,0.0,2.25}, {-2.7,0.0,2.025}, {-2.7,-0.3,2.025}, {-3.0,-0.3,2.25}, {-3.0,0.0,2.25}, {-2.7,0.0,1.8}, {-2.7,-0.3,1.8}, {-3.0,-0.3,1.8}, {-3.0,0.0,1.8}, {-1.5,0.3,2.25}, {-1.6,0.3,2.025}, {-2.5,0.3,2.25}, {-2.3,0.3,2.025}, {-3.0,0.3,2.25}, {-2.7,0.3,2.025}, {-3.0,0.3,1.8}, {-2.7,0.3,1.8}, {-2.7,0.0,1.575}, {-2.7,-0.3,1.575}, {-3.0,-0.3,1.35}, {-3.0,0.0,1.35}, {-2.5,0.0,1.125}, {-2.5,-0.3,1.125}, {-2.65,-0.3,0.9375}, {-2.65,0.0,0.9375}, {-2.0,-0.3,0.9}, {-1.9,-0.3,0.6}, {-1.9,0.0,0.6}, {-3.0,0.3,1.35}, {-2.7,0.3,1.575}, {-2.65,0.3,0.9375}, {-2.5,0.3,1.125}, {-1.9,0.3,0.6}, {-2.0,0.3,0.9}, {1.7,0.0,1.425}, {1.7,-0.66,1.425}, {1.7,-0.66,0.6}, {1.7,0.0,0.6}, {2.6,0.0,1.425}, {2.6,-0.66,1.425}, {3.1,-0.66,0.825}, {3.1,0.0,0.825}, {2.3,0.0,2.1}, {2.3,-0.25,2.1}, {2.4,-0.25,2.025}, {2.4,0.0,2.025}, {2.7,0.0,2.4}, {2.7,-0.25,2.4}, {3.3,-0.25,2.4}, {3.3,0.0,2.4}, {1.7,0.66,0.6}, {1.7,0.66,1.425}, {3.1,0.66,0.825}, {2.6,0.66,1.425}, {2.4,0.25,2.025}, {2.3,0.25,2.1}, {3.3,0.25,2.4}, {2.7,0.25,2.4}, {2.8,0.0,2.475}, {2.8,-0.25,2.475}, {3.525,-0.25,2.49375}, {3.525,0.0,2.49375}, {2.9,0.0,2.475}, {2.9,-0.15,2.475}, {3.45,-0.15,2.5125}, {3.45,0.0,2.5125}, {2.8,0.0,2.4}, {2.8,-0.15,2.4}, {3.2,-0.15,2.4}, {3.2,0.0,2.4}, {3.525,0.25,2.49375}, {2.8,0.25,2.475}, {3.45,0.15,2.5125}, {2.9,0.15,2.475}, {3.2,0.15,2.4}, {2.8,0.15,2.4}, {0.0,0.0,3.15}, {0.0,-0.002,3.15}, {0.002,0.0,3.15}, {0.8,0.0,3.15}, {0.8,-0.45,3.15}, {0.45,-0.8,3.15}, {0.0,-0.8,3.15}, {0.0,0.0,2.85}, {0.2,0.0,2.7}, {0.2,-0.112,2.7}, {0.112,-0.2,2.7}, {0.0,-0.2,2.7}, {-0.002,0.0,3.15}, {-0.45,-0.8,3.15}, {-0.8,-0.45,3.15}, {-0.8,0.0,3.15}, {-0.112,-0.2,2.7}, {-0.2,-0.112,2.7}, {-0.2,0.0,2.7}, {0.0,0.002,3.15}, {-0.8,0.45,3.15}, {-0.45,0.8,3.15}, {0.0,0.8,3.15}, {-0.2,0.112,2.7}, {-0.112,0.2,2.7}, {0.0,0.2,2.7}, {0.45,0.8,3.15}, {0.8,0.45,3.15}, {0.112,0.2,2.7}, {0.2,0.112,2.7}, {0.4,0.0,2.55}, {0.4,-0.224,2.55}, {0.224,-0.4,2.55}, {0.0,-0.4,2.55}, {1.3,0.0,2.55}, {1.3,-0.728,2.55}, {0.728,-1.3,2.55}, {0.0,-1.3,2.55}, {1.3,0.0,2.4}, {1.3,-0.728,2.4}, {0.728,-1.3,2.4}, {0.0,-1.3,2.4}, {-0.224,-0.4,2.55}, {-0.4,-0.224,2.55}, {-0.4,0.0,2.55}, {-0.728,-1.3,2.55}, {-1.3,-0.728,2.55}, {-1.3,0.0,2.55}, {-0.728,-1.3,2.4}, {-1.3,-0.728,2.4}, {-1.3,0.0,2.4}, {-0.4,0.224,2.55}, {-0.224,0.4,2.55}, {0.0,0.4,2.55}, {-1.3,0.728,2.55}, {-0.728,1.3,2.55}, {0.0,1.3,2.55}, {-1.3,0.728,2.4}, {-0.728,1.3,2.4}, {0.0,1.3,2.4}, {0.224,0.4,2.55}, {0.4,0.224,2.55}, {0.728,1.3,2.55}, {1.3,0.728,2.55}, {0.728,1.3,2.4}, {1.3,0.728,2.4}, {0.0,0.0,0.0}, {1.5,0.0,0.15}, {1.5,0.84,0.15}, {0.84,1.5,0.15}, {0.0,1.5,0.15}, {1.5,0.0,0.075}, {1.5,0.84,0.075}, {0.84,1.5,0.075}, {0.0,1.5,0.075}, {1.425,0.0,0.0}, {1.425,0.798,0.0}, {0.798,1.425,0.0}, {0.0,1.425,0.0}, {-0.84,1.5,0.15}, {-1.5,0.84,0.15}, {-1.5,0.0,0.15}, {-0.84,1.5,0.075}, {-1.5,0.84,0.075}, {-1.5,0.0,0.075}, {-0.798,1.425,0.0}, {-1.425,0.798,0.0}, {-1.425,0.0,0.0}, {-1.5,-0.84,0.15}, {-0.84,-1.5,0.15}, {0.0,-1.5,0.15}, {-1.5,-0.84,0.075}, {-0.84,-1.5,0.075}, {0.0,-1.5,0.075}, {-1.425,-0.798,0.0}, {-0.798,-1.425,0.0}, {0.0,-1.425,0.0}, {0.84,-1.5,0.15}, {1.5,-0.84,0.15}, {0.84,-1.5,0.075}, {1.5,-0.84,0.075}, {0.798,-1.425,0.0}, {1.425,-0.798,0.0}, }; @//E*O*F ducks.c// chmod u=rw,g=r,o=r ducks.c echo x - patches.c sed 's/^@//' > "patches.c" <<'@//E*O*F patches.c//' #include "tea.h" pt patches[PATCH_COUNT] = { {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}}, {{4,17,18,19},{8,20,21,22},{12,23,24,25},{16,26,27,28}}, {{19,29,30,31},{22,32,33,34},{25,35,36,37},{28,38,39,40}}, {{31,41,42,1},{34,43,44,5},{37,45,46,9},{40,47,48,13}}, {{13,14,15,16},{49,50,51,52},{53,54,55,56},{57,58,59,60}}, {{16,26,27,28},{52,61,62,63},{56,64,65,66},{60,67,68,69}}, {{28,38,39,40},{63,70,71,72},{66,73,74,75},{69,76,77,78}}, {{40,47,48,13},{72,79,80,49},{75,81,82,53},{78,83,84,57}}, {{57,58,59,60},{85,86,87,88},{89,90,91,92},{93,94,95,96}}, {{60,67,68,69},{88,97,98,99},{92,100,101,102},{96,103,104,105}}, {{69,76,77,78},{99,106,107,108},{102,109,110,111},{105,112,113,114}}, {{78,83,84,57},{108,115,116,85},{111,117,118,89},{114,119,120,93}}, {{121,122,123,124},{125,126,127,128},{129,130,131,132},{133,134,135,136}}, {{124,137,138,121},{128,139,140,125},{132,141,142,129},{136,143,144,133}}, {{133,134,135,136},{145,146,147,148},{149,150,151,152},{69,153,154,155}}, {{136,143,144,133},{148,156,157,145},{152,158,159,149},{155,160,161,69}}, {{162,163,164,165},{166,167,168,169},{170,171,172,173},{174,175,176,177}}, {{165,178,179,162},{169,180,181,166},{173,182,183,170},{177,184,185,174}}, {{174,175,176,177},{186,187,188,189},{190,191,192,193},{194,195,196,197}}, {{177,184,185,174},{189,198,199,186},{193,200,201,190},{197,202,203,194}}, {{204,204,204,204},{207,208,209,210},{211,211,211,211},{212,213,214,215}}, {{204,204,204,204},{210,217,218,219},{211,211,211,211},{215,220,221,222}}, {{204,204,204,204},{219,224,225,226},{211,211,211,211},{222,227,228,229}}, {{204,204,204,204},{226,230,231,207},{211,211,211,211},{229,232,233,212}}, {{212,213,214,215},{234,235,236,237},{238,239,240,241},{242,243,244,245}}, {{215,220,221,222},{237,246,247,248},{241,249,250,251},{245,252,253,254}}, {{222,227,228,229},{248,255,256,257},{251,258,259,260},{254,261,262,263}}, {{229,232,233,212},{257,264,265,234},{260,266,267,238},{263,268,269,242}}, {{270,270,270,270},{279,280,281,282},{275,276,277,278},{271,272,273,274}}, {{270,270,270,270},{282,289,290,291},{278,286,287,288},{274,283,284,285}}, {{270,270,270,270},{291,298,299,300},{288,295,296,297},{285,292,293,294}}, {{270,270,270,270},{300,305,306,279},{297,303,304,275},{294,301,302,271}} }; @//E*O*F patches.c// chmod u=rw,g=r,o=r patches.c echo Inspecting for damage in transit... temp=/tmp/shar$$; dtemp=/tmp/.shar$$ trap "rm -f $temp $dtemp; exit" 0 1 2 3 15 cat > $temp <<\!!! 13 31 246 Makefile 9 21 137 tea.h 237 1058 6416 raypot.c 310 313 5617 ducks.c 36 39 2266 patches.c 605 1462 14682 total !!! wc Makefile tea.h raypot.c ducks.c patches.c | sed 's=[^ ]*/==' | diff -b $temp - >$dtemp if [ -s $dtemp ] then echo "Ouch [diff of wc output]:" ; cat $dtemp else echo "No problems found." fi exit 0