[comp.graphics] Possible Bug in Teapot Conversion Program

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