kent@sparky.IMD.Sterling.COM (Kent Landfield) (01/03/91)
Submitted-by: ingwa@isy.liu.se (Inge Wallin) Posting-number: Volume 16, Issue 9 Archive-name: sipp2.0/part05 #!/bin/sh # This is part 05 of sipp-2.0 # ============= doc/sipp.man ============== if test ! -d 'doc'; then echo 'x - creating directory doc' mkdir 'doc' fi if test -f 'doc/sipp.man' -a X"$1" != X"-c"; then echo 'x - skipping doc/sipp.man (File already exists)' else echo 'x - extracting doc/sipp.man (Text)' sed 's/^X//' << 'SHAR_EOF' > 'doc/sipp.man' && .\" Copyright 1990, Jonas Yngvesson, Inge Wallin .\" This program and documentation may be distributed freely under .\" the terms of GNU GENERAL PUBLIC LICENSE. .TH SIPP 3X "December , 1990" 3X .SH NAME sipp - simple polygon processor, a 3d-graphics library .SH SYNOPSIS \fI#include <sipp.h>\fR .sp [g]cc [\fIflags\fR] \fIfiles\fR -lsipp -lm [ \fIlibraries\fR ] .SH DESCRIPTION \fIsipp\fR is a library for creating 3-dimensional scenes and rendering them using a scan-line z-buffer algorithm. A scene is built up of objects which can be transformed with rotation, translation and scaling. The objects form hierarchies where each object can have arbitrarily many subobjects and subsurfaces. A surface is a number of connected polygons which are rendered with Phong interpolation of the surface normals. .sp The library has an internal database for the objects that is to be rendered. Objects can be installed in, and removed from, this database at any time. .sp The library also provides 3-dimensional texture mapping with automatic interpolation of texture coordinates. Simple anti-aliasing is performed through double oversampling. A scene can be illuminated by an arbitrary number of light sources. A basic shading algorithm is provided with the library, but the user can also use his own shading algorithms for each surface to produce special effects. Images are produced in the Portable Pixmap format (ppm) for which many utilities exist. X .SH USAGE Before any other function in \fIsipp\fR is used, the function \fIsipp_init()\fR must always be called. This call initiates the internal database and other global variables. The rest of this section describes the ideas behind \fIsipp\fR and outlines its usage. See the section .B FUNCTIONS for details. .sp All objects in \fIsipp\fR are built up of polygons with 3 or more vertices. The polygons can either be concave or convex, but all vertices must lie in the same plane. No test is done to assertain this, however. A number of polygons can form a, possibly non-planar, surface that is rendered using Phong interpolation of the surface normals. Surfaces are grouped together into objects which can also have other objects as subobjects. Each object or subobject can be transformed using the standard transformations: rotation, scaling and translation. All transformations are done with respect to the parent object if the object is a subobject and the world if the object is a top level object. .sp When an object is defined, copies can be made of it and it can be installed into the internal database for rendering. The installation doesn't affect the object in any way, i.e. it can still be transformed and copied. This is useful if more pictures than one is to be created, e.g. in an animation. .sp \fIsipp\fR uses a number of stacks to create a scene. First, \fIvertices\fR of a polygon are pushed onto a \fIvertex stack\fR. When all vertices in a polygon are pushed, a \fIpolygon\fR is created from them and is pushed onto a \fIpolygon stack\fR. When a number of polygons have been pushed, a call to a function in \fIsipp\fR combine them into a \fIsurface\fR and returns a pointer to the surface. This surface can then be inserted into an \fIobject\fR together with other surfaces. Objects can be transformed, used as subobjects in other objects and inserted into the scene database. .sp To create a polygon, two functions are used: \fIvertex_push()\fR and \fIpolygon_push()\fR. Variants of these functions exist, but these are the simple forms that are the easiest to use. A call to \fIvertex_push()\fR is done for each vertex in the polygons, going counter clockwise around the edge. The order in which the vertices are pushed is important, because this determines the front and the back face of the polygon. When all polygons are pushed onto the vertex stack, \fIpolygon_push()\fR is called. This call creates a polygon structure out of the pushed vertices, deletes them from the vertex stack, and pushes the newly created polygon onto the polygon stack. .sp When all polygons in a surface is on the polygon stack, \fIsurface_create()\fR (or one of it's variants) will create a surface out of them and empty the polygon stack for a new surface definition. \fIsurface_create()\fR returns a pointer to the created surface. .sp An object is created with the function \fIobject_create()\fR. This function returns a pointer to an empty object, i.e. it contains no surfaces or subobjects. Surfaces and subobjects are added to an object with the functions \fIobject_add_surface()\fR and \fIobject_add subobj()\fR. When all surfaces and subobjects are added to the object it can be installed in the rendering database, or removed from it, with the functions \fIobject_install()\fR and \fIobject_uninstall()\fR respectively. X .SH DATA TYPES The \fIsipp\fR library defines a number of data types in the file \fIsipp.h\fR. These data types are: .IP \fIbool\fR .br \fIbool\fR can be used as a boolean type, with values \fITRUE\fR of \fIFALSE\fR. These constants are also defined in \fIsipp.h\fR. X .IP \fIColor\fR \fIColor\fR is a struct with three members, \fIred\fR, \fIgrn\fR and \fIblu\fR. Each member of the struct is a double that should be in the range [0,1]. X .IP \fIVector\fR A \fIVector\fR is a struct with three members, \fIx\fR, \fIy\fR and \fIz\fR which are all doubles. X .IP \fITransf_mat\fR \fITransf_mat\fR is a standard 4 x 4 homogenous transformation matrix. Actually it is stored as a 4 x 3 matrix to save memory, since the rightmost column is only needed in the viewing calculation. .sp The members of a \fITransf_mat\fR should never be accessed directly, but rather through the abstract functions described in the \fBFUNCTIONS\fR section. X .IP \fISurface\fR\ and\ \fIObject\fR \fISurface\fR and \fIObject\fR are both opaque types used by \fIsipp\fR. The actual definition of them is not important to the user. X .IP \fISurf_desc\fR A \fISurf_desc\fR is a surface description, used by the built-in shader to determine properties about a surface. The definition of \fISurf_desc\fR is as follows: .br \fItypedef\ struct {\fR .br \fI double\ ambient;\fR\ /* Fraction of color visible in ambient light */ .br \fI double\ specular;\fR\ /* Fraction of colour specularly reflected */ .br \fI double\ c3;\fR\ /* "Shininess" 0 = shiny, 1 = dull */ .br \fI Color\ color;\fR\ /* Colour of the surface */ .br \fI}\ Surf_desc;\fR X .IP \fILightsource\fR All lightsources in the scene are kept in a linked list where the nodes are defined like this: .sp .I typedef struct lightsource { .br \fI\ double intensity;\fR .br \fI\ Vector dir;\fR .br \fI\ struct lightsource *next;\fR .br .I } Lightsource; .sp A pointer to the head of this list is sent to the shader. X .SH SHADING FUNCTIONS Each surface in a scene has a shading function associated with it. This function is called for each pixel in the surface as it is rendered. \fIsipp\fR has an internal basic shading function called \fIbasic_shader\fR that can be used in most cases. \fIbasic_shader\fR provides a somewhat modified and simplified version of Blinn's shading model, taking a \fISurf_desc\fR as a description of the surface. .sp If the user is not satisfied with the builtin shader, he can provide his own shader and surface description struct. All shaders take the same parameters and must be defined as follows: .sp \fIvoid\ myshader(nx,\ ny,\ nz,\ \ u,\ v,\ w,\ view_vec,\fR .br \fI lights,\ surface,\ color)\fR .br \fI double nx, ny, nz;\fR .br \fI double u, v, w;\fR .br \fI Vector\ view_vec;\fR .br \fI Lightsource *lights;\fR .br \fI void *surface;\fR .br \fI Color\ *color;\fR .sp \fInx, ny\fR and \fInz\fR is the \fInon-normalized\fR surface normal at the point that should be rendered. .br \fIu, v\fR and \fIw\fR are the interpolated texture coordinates at the rendered point. If no texture coordinates have been given at some vertices these values are undefined and contains garbage at best. .br \fIview_vec\fR is a normalized vector, pointing from the rendered point at the viewpoint. .br \fIlights\fR is a pointer to a linked list of lightsource descriptions. See the function \fIlightsource_push()\fR for a description of the structure of the links. .br \fIsurface\fR is the same \fIsurface\fR-pointer that was sent to the function \fIsurface_create()\fR. In the case of \fIbasic_shader\fR this is a pointer to a \fISurf_desc\fR. If the user provides his own shader, he can also provide his own surface description. .br Upon return, the shader should place the calculated rgb colour components in the areas pointed to by \fIcolor\fR. The rgb components must be values between 0 and 1. X .SH FUNCTIONS X .IP \fIvoid\ sipp_init()\fR Initializes the whole library and emptys the internal database. This function must be called before any other function in the library. X .IP \fIvoid\ vertex_push(x,\ y,\ z)\fR .br \fIdouble\ x,\ y,\ z;\fR .sp Push a vertex onto the internal vertex stack. .br Note: Vertices must be pushed on the vertex stack \fIcounterclockwize\fR when looking at the "front" face of the polygon. Otherwize the front of the surface will be defined in the wrong direction. X .IP \fIvoid\ vertex_tx_push(x,\ y,\ z,\ u,\ v,\ w)\fR .br \fIdouble\ x,\ y,\ z;\fR .br \fIdouble\ u,\ v,\ w;\fR .sp Push a vertex and it's texture coordinates onto the vertex stack. Three texture coordinates are provided to make it possible to use both 2d and solid texture. The texture coordinates are interpolated between vertices on the same object and are \fInot\fR affected by transformations of the object. The interpolated coordinates will be sent to the shader. The coordinates can of course be used to hold any attribute that one whishes to interpolate between vertices and then use in the shader. X .IP \fIvoid\ polygon_push()\fR Create a polygon from the vertices on the vertex stack and push it onto the polygon stack. The vertex stack is empty and ready for a new polygon definition after this operation. .br If a vertex in the polygon is already defined in a previous polygon that belongs to the same surface, the same vertex will be referenced, i.e. vertices shared between polygons are only stored once, but they must be repeated when defining the polygons. X .IP \fISurface\ *surface_create(surf_desc,\ shader)\fR .br \fIvoid\ *surf_desc;\fR .br \fIShader\ *shader;\fR .sp Create a surface from the polygons on the polygon stack. A pointer to the newly-created surface is returned. The polygon stack is empty afterwards. \fIshader\fR is a pointer to the shader function that will be called when a point on this surface is to be rendered. See the section \fBSHADER FUNCTIONS\fR for a declaration of the shader function. \fIsurf_desc\fR is a pointer to a static structure that contains the surface properties of the surface. The exact representation of this structure can be chosen freely by the user depending on the implementation of his shader. If the internal shader, \fIbasic_shader\fR is used, this struct is of type \fISurf_desc\fR. X .IP \fISurface\ *surface_basic_create(ambient,\ red,\ grn,\ blu,\ specular,\ c3)\fR .br \fIdouble\ ambient;\fR .br \fIdouble\ red,\ grn,\ blu;\fR .br \fIdouble\ specular;\fR .br \fIdouble\ c3;\fR .sp Create a surface from the polygons on the polygon stack. A pointer to the newly-created surface is returned. The surface will be shaded with the internal shader, \fIbasic_shader\fR, using the parameters as values in a \fISurf_desc\fR struct. X .IP \fIvoid\ surface_set_shader(surface,\ surf_desc,\ shader)\fR .br \fISurface\ *surface;\fR .br \fIvoid\ *surf_desc;\fR .br \fIShader\ *shader;\fR .sp Set the surface \fIsurface\fR to be shaded with the shading function \fIshader\fR. The shading information used by the shader is pointed at by \fIsurf_desc\fR. X .IP \fIvoid\ surface_basic_shader(surface,\ ambient,\ red,\ grn,\ blu,\ specular,\ c3)\fR .br \fISurface\ *surface;\fR .br \fIdouble\ ambient;\fR .br \fIdouble\ red,\ grn,\ blu;\fR .br \fIdouble\ specular;\fR .br \fIdouble\ c3;\fR .sp Set \fIsurface\fR to be shaded by the internal shader and let \fIambient\fR, \fIred\fR, \fIgrn\fR, \fIblu\fR, \fIspecular\fR and \fIc3\fR be the values stored in the \fISurf_desc\fR struct for this surface. X .IP \fIObject\ *object_create()\fR Create an empty object, i.e. an object with no surfaces or subobjects in it. The transformation matrix in the new object will be a identity matrix initially. X .IP \fIObject\ *object_instance(obj)\fR .br \fIObject\ *obj;\fR .sp Create a new instance of a previously defined object. The lists of surfaces and subobjects in \fIobj\fR are not copied, but a new reference with its own transformation matrix is created. The matrix is set to the identity matrix. If \fIobj\fR is changed, i.e. if one of its subobjects or surfaces are transformed, one is deleted or added, the change will also be seen in the copy. X .IP \fIObject\ *object_dup(obj)\fR .br \fIObject\ *obj;\fR .sp Copy recursively an object and its subobjects. The surfaces in the object tree are not copied, only new references to them are made. X .IP \fIObject\ *object_deep_dup(obj)\fR .br \fIObject\ *obj;\fR .sp Copy the entire tree for the object \fIobj\fR, including subobjects and all surfaces, polygons and vertices. This is a costly operation if the object is complex. X .IP \fIvoid\ object_delete(obj)\fR .br \fIObject\ *obj;\fR .sp Delete the object \fIobj\fR, i.e. the memory used by \fIobj\fR and all its subobjects and surfaces is recursively freed. \fIsipp\fR keeps track of internal references so objects and surfaces referenced from somewhere else in \fIsipp\fR will not be deleted, i.e. no dangeling references are created in the data structures. X .IP \fIvoid\ object_install(obj)\fR .br \fIObject\ *obj;\fR .sp Install the object \fIobj\fR into the rendering database. This function must be called on all objects that are to be visible in the rendered image. X .IP \fIvoid\ object_uninstall(obj)\fR .br \fIObject\ *obj;\fR .sp Remove the object \fIobj\fR from the rendering database. If \fIobj\fR is not in the database to begin with, nothing happens. X .IP \fIvoid\ object_add_surface(obj,\ surf)\fR .br \fIObject\ *obj;\fR .br \fISurface\ *surf;\fR .sp Add the surface \fIsurf\fR to the object \fIobj\fR. X .IP \fIvoid\ object_add_subobj(obj,\ subobj)\fR .br \fIObject\ *obj;\fR .br \fIObject\ *subobj;\fR .sp Add the subobject \fIsubobj\fR to the object \fIobj\fR. X .IP \fIvoid\ object_set_transf(obj,\ matrix)\fR .br \fIObject\ *obj;\fR .br \fITransf_mat\ *matrix;\fR .sp Set the transformation matrix of the object \fIobj\fR to \fImatrix\fR. .br X .IP \fIvoid\ object_clear_transf(obj)\fR .br \fIObject\ *obj;\fR .sp Set the transformation matrix of the object \fIobj\fR to the unit matrix. .br X .IP \fIvoid\ object_transform(obj,\ matrix)\fR .br \fIObject\ *obj;\fR .br \fITransf_mat\ *matrix;\fR .sp Post multiply the matrix \fImatrix\fR into the transformation matrix of the object \fIobj\fR. X .br X .IP \fIvoid\ object_rot_x(obj,\ ang)\fR .br \fIObject\ *obj;\fR .br \fIdouble\ ang;\fR .sp Rotate the object \fIobj\fR the angle \fIang\fR about the X axis. \fIang\fR is expressed in radians. X .IP \fIvoid\ object_rot_y(obj,\ ang)\fR .br \fIObject\ *obj;\fR .br \fIdouble\ ang;\fR .sp Rotate the object \fIobj\fR the angle \fIang\fR about the Y axis. \fIang\fR is expressed in radians. X .IP \fIvoid\ object_rot_z(obj,\ ang)\fR .br \fIObject\ *obj;\fR .br \fIdouble\ ang;\fR .sp Rotate the object \fIobj\fR the angle \fIang\fR about the Z axis. \fIang\fR is expressed in radians. X .IP \fIvoid\ object_rot(obj,\ point,\ vec,\ ang)\fR .br \fIObject\ *obj;\fR .br \fIVector\ *point;\fR .br \fIVector\ *vec;\fR .br \fIdouble\ ang;\fR .sp Rotate the object \fIobj\fR the angle \fIang\fR about the line given by the point \fIpoint\fR and the vector \fIvec\fR starting in that point. \fIang\fR is expressed in radians. .br X .IP \fIvoid\ object_scale(obj,\ xscale,\ yscale,\ zscale)\fR .br \fIObject\ *obj;\fR .br \fIdouble\ xscale,\ yscale,\ zscale;\fR .sp Scale the object \fIobj\fR with the scaling factors \fIxscale,\ yscale\fR and \fIzscale\fR in the main directions respectively. X .IP \fIvoid\ object_move(obj,\ dx,\ dy,\ dz)\fR .br \fIObject\ *obj;\fR .br \fIdouble\ dx,\ dy,\ dz;\fR .sp Move (translate) the object \fIobj\ dx,\ dy\fR and \fIdz\fR in the three main directions, respectively. X .IP \fIvoid\ lightsource_push(x,\ y,\ z,\ intensity)\fR .br \fIdouble\ x,\ y,\ z;\fR .br \fIdouble\ intensity;\fR .sp Create a new lightsource in the scene. All lightsources is considered to be at an infinit distance and to emit white light. \fIx,\ y,\ z\fR defines a vector pointing to the lightsource. \fIintensity\fR is a double between 0 and 1 that defines the intensity of the light coming from the lightsource. X .IP \fIvoid\ view_from(x,\ y,\ z)\fR .br .I double x, y, z; .sp Define the position of the viewpoint. X .IP \fIvoid\ view_at(x,\ y,\ z)\fR .br .I double x, y, z; .sp Define the viewing direction as going from the viewpoint to the point .I x, y, z. X .IP \fIvoid\ view_up(x,\ y,\ z)\fR .br .I double x, y, z; .sp Define the up vector. The only constraint on this vector is that it must not be parallel to the vector going from the viewpoint to the viewed point. If this function is not called, the default up vector is the world Y axis. X .IP \fIvoid\ view_focal(ratio)\fR .br .I double ratio; .sp Define the focal ratio of the "camera". This is the ratio between the distance from the viewpoint to the screen and half the screen height. .sp 5 X screen .br X | .br X | d .br .lc \ X viewpoint| .br .lc - X *| .br .lc \ X s| .br X | .br X | .sp 2 .nf X focal_ratio = d / s .fi .sp Another way of describing the value is acrtan(v/2) where v is the opening angle of the view. .br Note: The same focal ratio is used both horizontally and vertically. If the picture is rendered with different resolution in x and y, the ratio is assumed to be related to the \fIsmallest\fR of the two. X .IP \fIviewpoint(x,\ y,\ z,\ to_x,\ to_y,\ to_z,\ up_x,\ up_y,\ up_z,\ focal_ratio)\fR .br This function is used to set all viewpoint related values in one call. All arguments are doubles. .br .I x, y, z is the position of the viewpoint as in \fIview_from()\fR. .br .I to_x, to_y, to_z defines the viewing direction as in \fIview_at()\fR. .br .I up_x, up_y, up_z defines the up vector as in \fIview_up()\fR. .br .I focal_ratio defines (guess what) the focal ratio as in \fIview_focal()\fR. X .IP \fIvoid\ render_image(xsize,\ ysize,\ outfile)\fR .br \fIint\ xsize, ysize;\fR .br \fIFILE\ *outfile;\fR .sp This function does the actual rendering of the scene. The image is created with size (\fIxsize\fR X \fIysize\fR). \fIoutfile\fR is an open file pointer to which the image will be written. It can just as well be a pipe of course. X .IP \fIvoid\ basic_shader(nx,\ ny,\ nz,\ \ u,\ v,\ w,\ view_vec,fR .br \fI lights,\ surface,\ color)\fR .br \fIdouble nx, ny, nz;\fR .br \fIdouble u, v, w;\fR .br \fIVector\ view_vec;\fR .br \fILightsource *lights;\fR .br \fISurf_desc *surface;\fR .br \fI Color\ *color;\fR .sp This is the basic shader function that is provided with the library. See the section about \fBSHADING FUNCTIONS\fR for more details. X .SH SEE ALSO shaders(3X) - a number of shaders for \fIsipp\fR. .br primitives(3X) - a number of geometric primitives for \fIsipp\fR. X .SH AUTHORS Jonas Yngvesson\ \ (jonas-y@isy.liu.se) .br Inge Wallin\ (ingwa@isy.liu.se) .SH BUGS Antialiasing is rather crude. Aliasing effects is still quite obvious. It also ought to be possible to turn off antialiasing in order to get a faster "preview". .sp The viewing vector which is sent to the shader is actually only an approximation which assumes the viewpoint being at infinite distance. .sp No information is sent to the shader about how big interpolation steps are in the texture coordinate system. This makes it impossible to use any filtering techniqe for texture mapping, e.g. summed area tables. .sp There is no way to delete a subobject from an object. SHAR_EOF chmod 0644 doc/sipp.man || echo 'restore of doc/sipp.man failed' Wc_c="`wc -c < 'doc/sipp.man'`" test 20064 -eq "$Wc_c" || echo 'doc/sipp.man: original size 20064, current size' "$Wc_c" fi # ============= demo/Makefile ============== if test ! -d 'demo'; then echo 'x - creating directory demo' mkdir 'demo' fi if test -f 'demo/Makefile' -a X"$1" != X"-c"; then echo 'x - skipping demo/Makefile (File already exists)' else echo 'x - extracting demo/Makefile (Text)' sed 's/^X//' << 'SHAR_EOF' > 'demo/Makefile' && # # Makefile for the misc demos of sipp version 2.0. # X # These values are used if not overruled from the command line CC = cc CFLAGS = -O -I../libsipp X X SRCS = torustest.c cylindertest.c ellipsoid.c blocktest.c chain.c \ X teapot.c structure.c planettest.c isy90.c PROGRAMS = torustest cylindertest ellipsoid blocktest chain \ X teapot structure planettest isy90 X X all: X @echo "If you want to make only the pretty images, type 'make pretty'." X @echo "If you want to make only the test images, type 'make tests'." X @echo "If you want to make all images, type 'make images'." X @echo X @echo "If you want to make the programs, but not the images," X @echo "type 'make programs'." X @echo X X # ================================================================ X X programs: ../libsipp/libsipp.a $(PROGRAMS) X ../libsipp/libsipp.a: X cd ..; $(MAKE) library X X # ================================================================ X X teapot: teapot.o ../libsipp/libsipp.a X $(CC) -o teapot teapot.o ../libsipp/libsipp.a -lm X chain: chain.o ../libsipp/libsipp.a X $(CC) -o chain chain.o ../libsipp/libsipp.a -lm X structure: structure.o ../libsipp/libsipp.a X $(CC) -o structure structure.o ../libsipp/libsipp.a -lm X planettest: planettest.o ../libsipp/libsipp.a X $(CC) -o planettest planettest.o ../libsipp/libsipp.a -lm X isy90: isy90.o ../libsipp/libsipp.a X $(CC) -o isy90 isy90.o ../libsipp/libsipp.a -lm X ellipsoid: ellipsoid.o ../libsipp/libsipp.a X $(CC) -o ellipsoid ellipsoid.o ../libsipp/libsipp.a -lm X torustest: torustest.o ../libsipp/libsipp.a X $(CC) -o torustest torustest.o ../libsipp/libsipp.a -lm X cylindertest: cylindertest.o ../libsipp/libsipp.a X $(CC) -o cylindertest cylindertest.o ../libsipp/libsipp.a -lm X blocktest: blocktest.o ../libsipp/libsipp.a X $(CC) -o blocktest blocktest.o ../libsipp/libsipp.a -lm X X # ================================================================ X X clean: X $(RM) *~ .*~ *.o $(PROGRAMS) *.ppm X tags: X etags $(SRCS) X X # ================================================================ X PRETTY = chain.ppm teapot.ppm structure.ppm planet.ppm isy90.ppm TESTS = torus.ppm cylinder.ppm ellipsoid.ppm block.ppm IMAGES = $(PRETTY) $(TESTS) X images: $(IMAGES) pretty: $(PRETTY) tests: $(TESTS) X chain.ppm: chain X chain teapot.ppm: teapot X teapot structure.ppm: structure X structure planet.ppm: planettest X planettest isy90.ppm: isy90 X isy90 torus.ppm: torustest X torustest cylinder.ppm: cylindertest X cylindertest ellipsoid.ppm: ellipsoid X ellipsoid block.ppm: blocktest X blocktest SHAR_EOF chmod 0644 demo/Makefile || echo 'restore of demo/Makefile failed' Wc_c="`wc -c < 'demo/Makefile'`" test 2518 -eq "$Wc_c" || echo 'demo/Makefile: original size 2518, current size' "$Wc_c" fi # ============= demo/README ============== if test -f 'demo/README' -a X"$1" != X"-c"; then echo 'x - skipping demo/README (File already exists)' else echo 'x - extracting demo/README (Text)' sed 's/^X//' << 'SHAR_EOF' > 'demo/README' && This directory contains test programs and demonstration programs for the sipp library version 2.0. The images here can be divided into two categories: the mere test images (boring) and the demonstrations images (impressive). X Test image Created by Explanation --------------------------------------------------- torus.ppm torustest A plain violet torus cylinder.ppm cylindertest A violet, rather fat, cylinder ellipsoid.ppm ellipsoid A violet course ellipsoid. X Note how the surface of the X ellipsoid appears smooth in X spite of the low number of X polygons in it. block.ppm blocktest An orange square block. X X Demo image Created by Explanation --------------------------------------------------- chain.ppm chain A 3-D chain of torii. teapot.ppm teapot The standard classic Newell X teapot. structure.ppm structure A geometric structure, X demonstrating bumpy X appearance of a surface planet.ppm planettest A planet with fractal coasts X and clouds. isy90.ppm isy90 The cover of the 1990 X Activity Report at the Dept. X of EE at Linkoping University. X Demonstrates a simulated X granite texture. SHAR_EOF chmod 0644 demo/README || echo 'restore of demo/README failed' Wc_c="`wc -c < 'demo/README'`" test 1771 -eq "$Wc_c" || echo 'demo/README: original size 1771, current size' "$Wc_c" fi # ============= demo/TAGS ============== if test -f 'demo/TAGS' -a X"$1" != X"-c"; then echo 'x - skipping demo/TAGS (File already exists)' else echo 'x - extracting demo/TAGS (Text)' sed 's/^X//' << 'SHAR_EOF' > 'demo/TAGS' && X torustest.c,13 main(13,130 X cylindertest.c,13 main(12,112 X ellipsoidtest.c,13 main(12,112 X blocktest.c,11 main(9,88 X chain.c,13 main(13,130 X teapot.c,11 main(8,81 X d15.c,55 ellips_plate(47,931 main(126,3268 pixel_test(33,752 X structure.c,37 #define SIGNBIT(12,151 main(29,383 X planettest.c,13 main(12,130 SHAR_EOF chmod 0644 demo/TAGS || echo 'restore of demo/TAGS failed' Wc_c="`wc -c < 'demo/TAGS'`" test 327 -eq "$Wc_c" || echo 'demo/TAGS: original size 327, current size' "$Wc_c" fi # ============= demo/blocktest.c ============== if test -f 'demo/blocktest.c' -a X"$1" != X"-c"; then echo 'x - skipping demo/blocktest.c (File already exists)' else echo 'x - extracting demo/blocktest.c (Text)' sed 's/^X//' << 'SHAR_EOF' > 'demo/blocktest.c' && #include <stdio.h> #include <math.h> X #include <sipp.h> #include <primitives.h> X X X main(argc, argv) X int argc; X char **argv; { X FILE *fp ; X Surf_desc surf; X int side; X X X if (argc != 2) { X side = 256; X } else { X side = atoi(argv[1]); X } X X sipp_init(); X X lightsource_push(1.0, 1.0, 1.0, 0.9); X lightsource_push(-1.0, -1.0, 0.5, 0.4); X X surf.ambient = 0.5; X surf.color.red = 0.8; X surf.color.grn = 0.5; X surf.color.blu = 0.2; X surf.specular = 0.6; X surf.c3 = 0.2; X X object_install(sipp_block(1.0, 2.0, 3.0, &surf, basic_shader)); X X viewpoint(7.0, 3.0, 5.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.4); X X printf("Rendering, wait..."); X fflush(stdout); X X fp = fopen("block.ppm", "w"); X render_image(side, side, fp); X printf("Done.\n"); } X SHAR_EOF chmod 0644 demo/blocktest.c || echo 'restore of demo/blocktest.c failed' Wc_c="`wc -c < 'demo/blocktest.c'`" test 830 -eq "$Wc_c" || echo 'demo/blocktest.c: original size 830, current size' "$Wc_c" fi # ============= demo/chain.c ============== if test -f 'demo/chain.c' -a X"$1" != X"-c"; then echo 'x - skipping demo/chain.c (File already exists)' else echo 'x - extracting demo/chain.c (Text)' sed 's/^X//' << 'SHAR_EOF' > 'demo/chain.c' && #include <stdio.h> #include <math.h> X #include <sipp.h> #include <primitives.h> X X X #define SMALLRES 15 #define BIGRES 40 X X main(argc, argv) X int argc; X char **argv; { X Object *torus; X Object *torus_pair; X Object *chain; X FILE *fp ; X Surf_desc surf; X int side; X X X if (argc != 2) { X side = 256; X } else { X side = atoi(argv[1]); X } X X sipp_init(); X X lightsource_push(1.0, 1.0, 1.0, 0.9); X lightsource_push(-1.0, -1.0, 0.5, 0.4); X X surf.ambient = 0.5; X surf.color.red = 0.8; X surf.color.grn = 0.6; X surf.color.blu = 0.3; X surf.specular = 0.6; X surf.c3 = 0.2; X X torus = sipp_torus(1.0, 0.23, BIGRES, SMALLRES, &surf, basic_shader); X torus_pair = object_create(); X object_add_subobj(torus_pair, torus); X torus = object_instance(torus); X object_move(torus, 0.0, -1.375, 0.0); X object_rot_y(torus, M_PI / 2.0); X object_add_subobj(torus_pair, torus); X X chain = object_create(); X object_move(torus_pair, -1.375, 1.375, 0.0); X object_add_subobj(chain, torus_pair); X torus_pair = object_instance(torus_pair); X object_rot_z(torus_pair, M_PI / 2.0); X object_move(torus_pair, -1.375, -1.375, 0.0); X object_add_subobj(chain, torus_pair); X torus_pair = object_instance(torus_pair); X object_rot_z(torus_pair, M_PI); X object_move(torus_pair, 1.375, -1.375, 0.0); X object_add_subobj(chain, torus_pair); X torus_pair = object_instance(torus_pair); X object_rot_z(torus_pair, 3.0 * M_PI / 2.0); X object_move(torus_pair, 1.375, 1.375, 0.0); X object_add_subobj(chain, torus_pair); X X object_install(chain); X X view_from(5.0, -2.0, 15.0); X view_at(0.5, 0.0, 0.0); X view_up(0.0, 0.0, 1.0); X view_focal(0.25); X X printf("Rendering, wait..."); X fflush(stdout); X X fp = fopen("chain.ppm", "w"); X render_image(side, side, fp); X printf("Done.\n"); } SHAR_EOF chmod 0644 demo/chain.c || echo 'restore of demo/chain.c failed' Wc_c="`wc -c < 'demo/chain.c'`" test 1910 -eq "$Wc_c" || echo 'demo/chain.c: original size 1910, current size' "$Wc_c" fi # ============= demo/cylindertest.c ============== if test -f 'demo/cylindertest.c' -a X"$1" != X"-c"; then echo 'x - skipping demo/cylindertest.c (File already exists)' else echo 'x - extracting demo/cylindertest.c (Text)' sed 's/^X//' << 'SHAR_EOF' > 'demo/cylindertest.c' && #include <stdio.h> #include <math.h> X #include <sipp.h> #include <primitives.h> X X X #define RESOLUTION 40 X X main(argc, argv) X int argc; X char **argv; { X FILE *fp ; X Surf_desc surf; X int side; X X X if (argc != 2) { X side = 256; X } else { X side = atoi(argv[1]); X } X X sipp_init(); X X lightsource_push(1.0, 1.0, 1.0, 0.9); X lightsource_push(-1.0, -1.0, 0.5, 0.4); X X surf.ambient = 0.5; X surf.color.red = 0.6; X surf.color.grn = 0.3; X surf.color.blu = 0.5; X surf.specular = 0.6; X surf.c3 = 0.2; X X object_install(sipp_cylinder(1.0, 1.0, RESOLUTION, &surf, basic_shader)); X X viewpoint(3.0, 0.0, 2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.4); X X printf("Rendering, wait..."); X fflush(stdout); X X fp = fopen("cylinder.ppm", "w"); X render_image(side, side, fp); X printf("Done.\n"); } SHAR_EOF chmod 0644 demo/cylindertest.c || echo 'restore of demo/cylindertest.c failed' Wc_c="`wc -c < 'demo/cylindertest.c'`" test 866 -eq "$Wc_c" || echo 'demo/cylindertest.c: original size 866, current size' "$Wc_c" fi # ============= demo/ellipsoid.c ============== if test -f 'demo/ellipsoid.c' -a X"$1" != X"-c"; then echo 'x - skipping demo/ellipsoid.c (File already exists)' else echo 'x - extracting demo/ellipsoid.c (Text)' sed 's/^X//' << 'SHAR_EOF' > 'demo/ellipsoid.c' && #include <stdio.h> #include <math.h> X #include <sipp.h> #include <primitives.h> X X X #define RESOLUTION 15 X X main(argc, argv) X int argc; X char **argv; { X FILE *fp ; X Surf_desc surf; X int side; X X X if (argc != 2) { X side = 256; X } else { X side = atoi(argv[1]); X } X X sipp_init(); X X lightsource_push(1.0, 1.0, 1.0, 0.9); X lightsource_push(-1.0, -1.0, 0.5, 0.4); X X surf.ambient = 0.5; X surf.color.red = 0.6; X surf.color.grn = 0.3; X surf.color.blu = 0.5; X surf.specular = 0.6; X surf.c3 = 0.2; X X object_install(sipp_ellipsoid(1.0, 2.0, 3.0, RESOLUTION, X &surf, basic_shader)); X X viewpoint(10.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.4); X X printf("Rendering, wait..."); X fflush(stdout); X X fp = fopen("ellipsoid.ppm", "w"); X render_image(side, side, fp); X printf("Done.\n"); } SHAR_EOF chmod 0644 demo/ellipsoid.c || echo 'restore of demo/ellipsoid.c failed' Wc_c="`wc -c < 'demo/ellipsoid.c'`" test 908 -eq "$Wc_c" || echo 'demo/ellipsoid.c: original size 908, current size' "$Wc_c" fi # ============= demo/isy90.c ============== if test -f 'demo/isy90.c' -a X"$1" != X"-c"; then echo 'x - skipping demo/isy90.c (File already exists)' else echo 'x - extracting demo/isy90.c (Text)' sed 's/^X//' << 'SHAR_EOF' > 'demo/isy90.c' && #include <math.h> #include <stdio.h> X #include <sipp.h> #include <shaders.h> #include <primitives.h> X X #define BEZ_RES 9 #define CYL_RES 40 #define LID_ROT 1.5 #define BLOCK_SIZE 1.2 #define NCYL 10 #define CYL_LEN 5.0 #define SMALL_CYL_RAD ((BLOCK_SIZE * M_PI) / (NCYL * 2)) #define BIG_CYL_RAD (0.5 * BLOCK_SIZE - 1.1 * SMALL_CYL_RAD) X X Marble_desc teapot_surf = { X 0.4, X 0.5, X 0.05, X 8.0, X {0.90, 0.80, 0.65}, X {0.30, 0.08, 0.08} }; X Granite_desc column_surf = { X 0.4, X 0.1, X 0.4, X 20.0, X {0.647, 0.565, 0.5}, X {0.15, 0.12, 0.10} }; X X main(argc, argv) X int argc; X char **argv; { X Object *column; X Object *teapot; X Object *handle; X Object *spout; X Object *body; X Object *lid; X Object *tmp; X FILE *infile; X int siz; X FILE *image; X int i; X X if (argc > 1) { X siz = atoi(argv[1]); X } else { X siz = 256; X } X X sipp_init(); X X infile = fopen("tpt_handle.bez", "r"); X handle = sipp_bezier(infile, BEZ_RES, &teapot_surf, marble_shader); X fclose(infile); X X infile = fopen("tpt_spout.bez", "r"); X spout = sipp_bezier(infile, BEZ_RES, &teapot_surf, marble_shader); X fclose(infile); X X infile = fopen("tpt_body.bez", "r"); X body = sipp_bezier(infile, BEZ_RES, &teapot_surf, marble_shader); X fclose(infile); X X infile = fopen("tpt_lid.bez", "r"); X lid = sipp_bezier(infile, BEZ_RES, &teapot_surf, marble_shader); X fclose(infile); X X object_rot_y(lid, LID_ROT); X X teapot = object_create(); X object_add_subobj(teapot, body); X object_add_subobj(teapot, lid); X object_add_subobj(teapot, handle); X object_add_subobj(teapot, spout); X X object_install(teapot); X X column = object_create(); X tmp = sipp_block(BLOCK_SIZE, BLOCK_SIZE / 4.0, BLOCK_SIZE, X &column_surf, granite_shader); X object_move(tmp, 0.0, -BLOCK_SIZE / 8.0, 0.0); X object_add_subobj(column, tmp); X X for (i = 0; i < NCYL; i++) { X if (i == 0) { X tmp = sipp_cylinder(SMALL_CYL_RAD, CYL_LEN, CYL_RES, X &column_surf, granite_shader); X } else { X tmp = object_instance(tmp); X } X object_rot_x(tmp, M_PI / 2.0); X object_move(tmp, BIG_CYL_RAD * cos(i * 2.0 * M_PI / NCYL), X -0.5 * (CYL_LEN + BLOCK_SIZE / 4.0), X BIG_CYL_RAD * sin(i * 2.0 * M_PI / NCYL)); X object_add_subobj(column, tmp); X } X X object_install(column); X X X lightsource_push(1.0, 1.0, 0.5, 0.85); X lightsource_push(-1.0, 0.5, 0.5, 0.25); X view_from(2.0, 1.5, 4.0); X view_at(0.0, 0.1, 0.0); X view_up(0.0, 1.0, 0.0); X view_focal(0.2); X image = fopen("isy90.ppm", "w"); X render_image(siz, siz, image); } SHAR_EOF chmod 0644 demo/isy90.c || echo 'restore of demo/isy90.c failed' Wc_c="`wc -c < 'demo/isy90.c'`" test 2837 -eq "$Wc_c" || echo 'demo/isy90.c: original size 2837, current size' "$Wc_c" fi # ============= demo/planettest.c ============== if test -f 'demo/planettest.c' -a X"$1" != X"-c"; then echo 'x - skipping demo/planettest.c (File already exists)' else echo 'x - extracting demo/planettest.c (Text)' sed 's/^X//' << 'SHAR_EOF' > 'demo/planettest.c' && #include <stdio.h> #include <math.h> X #include <sipp.h> #include <primitives.h> #include <shaders.h> X X X #define SUBDIVS 20 X main(argc, argv) X int argc; X char **argv; { X Surf_desc planet_surface; X Object *planet; X FILE *outfile; X int size; X X if (argc == 2) { X size = atoi(argv[1]); X } else { X size = 256; X } X X planet_surface.ambient = 0.4; X planet_surface.specular = 0.0; X planet_surface.c3 = 0.5; X planet_surface.color.red = 1.0; X planet_surface.color.grn = 0.0; X planet_surface.color.blu = 0.0; X X sipp_init(); X X lightsource_push(1.0, 1.0, 1.0, 1.0); X X object_install(sipp_sphere(1.0, SUBDIVS, &planet_surface, planet_shader)); X X viewpoint(0.0, 2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.75); X X outfile = fopen("planet.ppm", "w"); X render_image(size, size, outfile); } X SHAR_EOF chmod 0644 demo/planettest.c || echo 'restore of demo/planettest.c failed' Wc_c="`wc -c < 'demo/planettest.c'`" test 878 -eq "$Wc_c" || echo 'demo/planettest.c: original size 878, current size' "$Wc_c" fi # ============= demo/structure.c ============== if test -f 'demo/structure.c' -a X"$1" != X"-c"; then echo 'x - skipping demo/structure.c (File already exists)' else echo 'x - extracting demo/structure.c (Text)' sed 's/^X//' << 'SHAR_EOF' > 'demo/structure.c' && #include <stdio.h> #include <math.h> X #include <sipp.h> #include <primitives.h> #include <shaders.h> X X #define SPHERERES 40 #define CYLRES 40 X #define SIGNBIT(bit, i) (((i >> bit) & 1) ? -1.0 : 1.0) X Surf_desc surf = { X 0.4, X 0.7, X 0.1, X {0.8, 0.6, 0.3} X }; X Bumpy_desc bumpy_surf = { X basic_shader, X &surf, X 14.0, X FALSE, X TRUE }; X main(argc, argv) X int argc; X char **argv; { X Object *sphere; X Object *cyl; X Object *structure; X FILE *fp ; X Surf_desc cyl_surf; X int size; X int i; X X X if (argc != 2) { X size = 256; X } else { X size = atoi(argv[1]); X } X X sipp_init(); X X lightsource_push(1.0, 1.0, 1.0, 0.9); X lightsource_push(-1.0, -1.0, 0.5, 0.4); X X cyl_surf.ambient = 0.5; X cyl_surf.color.red = 0.5; X cyl_surf.color.grn = 0.6; X cyl_surf.color.blu = 0.8; X cyl_surf.specular = 0.4; X cyl_surf.c3 = 0.3; X X structure = object_create(); X X sphere = sipp_sphere(1.0, SPHERERES, &bumpy_surf, bumpy_shader); X for (i = 0; i < 8; i++) { X if (i) { X sphere = object_instance(sphere); X } X object_move(sphere, 2.0 * SIGNBIT(2, i), 2.0 * SIGNBIT(1, i), X 2.0 * SIGNBIT(0, i)); X object_add_subobj(structure, sphere); X } X X cyl = sipp_cylinder(0.25, 4.0, CYLRES, &cyl_surf, basic_shader); X for (i = 0; i < 4; i++) { X if (i) { X cyl = object_instance(cyl); X } X object_move(cyl, 2.0 * SIGNBIT(1, i), 2.0 * SIGNBIT(0, i), 0.0); X object_add_subobj(structure, cyl); X } X for (i = 0; i < 4; i++) { X cyl = object_instance(cyl); X object_rot_x(cyl, M_PI / 2.0); X object_move(cyl, 2.0 * SIGNBIT(1, i), 0.0, 2.0 * SIGNBIT(0, i)); X object_add_subobj(structure, cyl); X } X for (i = 0; i < 4; i++) { X cyl = object_instance(cyl); X object_rot_y(cyl, M_PI / 2.0); X object_move(cyl, 0.0, 2.0 * SIGNBIT(1, i), 2.0 * SIGNBIT(0, i)); X object_add_subobj(structure, cyl); X } X X object_install(structure); X X view_from(10.0, -5.0, 15.0); X view_at(0.0, 0.0, 0.0); X view_up(0.0, 0.0, 1.0); X view_focal(0.25); X X printf("Rendering, wait..."); X fflush(stdout); X X fp = fopen("structure.ppm", "w"); X render_image(size, size, fp); X printf("Done.\n"); } X SHAR_EOF chmod 0644 demo/structure.c || echo 'restore of demo/structure.c failed' Wc_c="`wc -c < 'demo/structure.c'`" test 2360 -eq "$Wc_c" || echo 'demo/structure.c: original size 2360, current size' "$Wc_c" fi # ============= demo/teapot.c ============== if test -f 'demo/teapot.c' -a X"$1" != X"-c"; then echo 'x - skipping demo/teapot.c (File already exists)' else echo 'x - extracting demo/teapot.c (Text)' sed 's/^X//' << 'SHAR_EOF' > 'demo/teapot.c' && #include <stdio.h> X #include <sipp.h> #include <primitives.h> X X #define RESOLUTION 9 X Surf_desc teapot_surf = { X 0.4, X 0.5, X 0.1, X {0.9, 0.6, 0.6} }; X X main(argc, argv) X int argc; X char **argv; { X Object *teapot; X Object *handle; X Object *spout; X Object *body; X Object *lid; X FILE *infile; X int siz; X FILE *image; X X if (argc > 1) { X siz = atoi(argv[1]); X } else { X siz = 256; X } X X sipp_init(); X X infile = fopen("tpt_handle.bez", "r"); X handle = sipp_bezier(infile, RESOLUTION, &teapot_surf, basic_shader); X fclose(infile); X X infile = fopen("tpt_spout.bez", "r"); X spout = sipp_bezier(infile, RESOLUTION, &teapot_surf, basic_shader); X fclose(infile); X X infile = fopen("tpt_body.bez", "r"); X body = sipp_bezier(infile, RESOLUTION, &teapot_surf, basic_shader); X fclose(infile); X X infile = fopen("tpt_lid.bez", "r"); X lid = sipp_bezier(infile, RESOLUTION, &teapot_surf, basic_shader); X fclose(infile); X X teapot = object_create(); X object_add_subobj(teapot, body); X object_add_subobj(teapot, lid); X object_add_subobj(teapot, handle); X object_add_subobj(teapot, spout); X X object_install(teapot); X X lightsource_push(1.0, 1.0, 1.0, 1.0); /* lightsource_push(-1.0, 1.0, -1.0, 1.0);*/ X view_from(0.75, 1.5, 3.5); X view_at(0.0, 0.4, 0.0); X view_up(0.0, 1.0, 0.0); X view_focal(0.25); X image = fopen("teapot.ppm", "w"); X render_image(siz, siz, image); } SHAR_EOF chmod 0644 demo/teapot.c || echo 'restore of demo/teapot.c failed' Wc_c="`wc -c < 'demo/teapot.c'`" test 1505 -eq "$Wc_c" || echo 'demo/teapot.c: original size 1505, current size' "$Wc_c" fi # ============= demo/torustest.c ============== if test -f 'demo/torustest.c' -a X"$1" != X"-c"; then echo 'x - skipping demo/torustest.c (File already exists)' else echo 'x - extracting demo/torustest.c (Text)' sed 's/^X//' << 'SHAR_EOF' > 'demo/torustest.c' && #include <stdio.h> #include <math.h> X #include <sipp.h> #include <primitives.h> X X X #define SMALLRES 15 #define BIGRES 40 X X main(argc, argv) X int argc; X char **argv; { X FILE *fp ; X Surf_desc surf; X int side; X X X if (argc != 2) { X side = 256; X } else { X side = atoi(argv[1]); X } X X sipp_init(); X X lightsource_push(1.0, 1.0, 1.0, 0.9); X lightsource_push(-1.0, -1.0, 0.5, 0.4); X X surf.ambient = 0.5; X surf.color.red = 0.6; X surf.color.grn = 0.3; X surf.color.blu = 0.5; X surf.specular = 0.6; X surf.c3 = 0.2; X X object_install(sipp_torus(1.0, 0.4, BIGRES, SMALLRES, &surf, X basic_shader)); X X viewpoint(2.0, 0.0, 7.0, 0.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.4); X X printf("Rendering, wait..."); X fflush(stdout); X X fp = fopen("torus.ppm", "w"); X render_image(side, side, fp); X printf("Done.\n"); } SHAR_EOF chmod 0644 demo/torustest.c || echo 'restore of demo/torustest.c failed' Wc_c="`wc -c < 'demo/torustest.c'`" test 914 -eq "$Wc_c" || echo 'demo/torustest.c: original size 914, current size' "$Wc_c" fi # ============= demo/tpt_body.bez ============== if test -f 'demo/tpt_body.bez' -a X"$1" != X"-c"; then echo 'x - skipping demo/tpt_body.bez (File already exists)' else echo 'x - extracting demo/tpt_body.bez (Text)' sed 's/^X//' << 'SHAR_EOF' > 'demo/tpt_body.bez' && # Bezier curves (rotational body) for teapot body. X bezier_curves: X vertices: 10 vertex_list: X 3.500000E-01 5.625000E-01 0.000000E+00 X 3.343750E-01 5.953125E-01 0.000000E+00 X 3.593750E-01 5.953125E-01 0.000000E+00 X 3.750000E-01 5.625000E-01 0.000000E+00 X 4.375000E-01 4.312500E-01 0.000000E+00 X 5.000000E-01 3.000000E-01 0.000000E+00 X 5.000000E-01 1.875000E-01 0.000000E+00 X 5.000000E-01 7.500000E-02 0.000000E+00 X 3.750000E-01 1.875000E-02 0.000000E+00 X 3.750000E-01 0.000000E+00 0.000000E+00 X curves: 3 curve_list: X X 1 2 3 4 X X 4 5 6 7 X X 7 8 9 10 SHAR_EOF chmod 0644 demo/tpt_body.bez || echo 'restore of demo/tpt_body.bez failed' Wc_c="`wc -c < 'demo/tpt_body.bez'`" test 644 -eq "$Wc_c" || echo 'demo/tpt_body.bez: original size 644, current size' "$Wc_c" fi # ============= demo/tpt_handle.bez ============== if test -f 'demo/tpt_handle.bez' -a X"$1" != X"-c"; then echo 'x - skipping demo/tpt_handle.bez (File already exists)' else echo 'x - extracting demo/tpt_handle.bez (Text)' sed 's/^X//' << 'SHAR_EOF' > 'demo/tpt_handle.bez' && # Bezier patches defining the teapot handle. X bezier_patches: X X vertices: 42 vertex_list: X X -3.750000E-01 5.250000E-01 0.000000E+00 X -6.250000E-01 5.250000E-01 0.000000E+00 X -7.500000E-01 5.250000E-01 0.000000E+00 X -7.500000E-01 4.125000E-01 0.000000E+00 X -7.500000E-01 3.000000E-01 0.000000E+00 X -6.625000E-01 1.968750E-01 0.000000E+00 X -4.750000E-01 1.125000E-01 0.000000E+00 X -3.750000E-01 5.250000E-01 -7.500000E-02 X -6.250000E-01 5.250000E-01 -7.500000E-02 X -7.500000E-01 5.250000E-01 -7.500000E-02 X -7.500000E-01 4.125000E-01 -7.500000E-02 X -7.500000E-01 3.000000E-01 -7.500000E-02 X -6.625000E-01 1.968750E-01 -7.500000E-02 X -4.750000E-01 1.125000E-01 -7.500000E-02 X -4.000000E-01 4.687500E-01 -7.500000E-02 X -5.750000E-01 4.687500E-01 -7.500000E-02 X -6.750000E-01 4.687500E-01 -7.500000E-02 X -6.750000E-01 4.125000E-01 -7.500000E-02 X -6.750000E-01 3.562500E-01 -7.500000E-02 X -6.250000E-01 2.437500E-01 -7.500000E-02 X -5.000000E-01 1.875000E-01 -7.500000E-02 X -4.000000E-01 4.687500E-01 0.000000E+00 X -5.750000E-01 4.687500E-01 0.000000E+00 X -6.750000E-01 4.687500E-01 0.000000E+00 X -6.750000E-01 4.125000E-01 0.000000E+00 X -6.750000E-01 3.562500E-01 0.000000E+00 X -6.250000E-01 2.437500E-01 0.000000E+00 X -5.000000E-01 1.875000E-01 0.000000E+00 X -4.000000E-01 4.687500E-01 7.500000E-02 X -5.750000E-01 4.687500E-01 7.500000E-02 X -6.750000E-01 4.687500E-01 7.500000E-02 X -6.750000E-01 4.125000E-01 7.500000E-02 X -6.750000E-01 3.562500E-01 7.500000E-02 X -6.250000E-01 2.437500E-01 7.500000E-02 X -5.000000E-01 1.875000E-01 7.500000E-02 X -3.750000E-01 5.250000E-01 7.500000E-02 X -6.250000E-01 5.250000E-01 7.500000E-02 X -7.500000E-01 5.250000E-01 7.500000E-02 X -7.500000E-01 4.125000E-01 7.500000E-02 X -7.500000E-01 3.000000E-01 7.500000E-02 X -6.625000E-01 1.968750E-01 7.500000E-02 X -4.750000E-01 1.125000E-01 7.500000E-02 X patches: 4 patch_list: X X 1 2 3 4 36 37 38 39 29 30 31 32 22 23 24 25 X 22 23 24 25 15 16 17 18 X 8 9 10 11 X 1 2 3 4 X X 4 5 6 7 39 40 41 42 32 33 34 35 25 26 27 28 X X 7 6 5 4 14 13 12 11 21 20 19 18 28 27 26 25 SHAR_EOF chmod 0644 demo/tpt_handle.bez || echo 'restore of demo/tpt_handle.bez failed' Wc_c="`wc -c < 'demo/tpt_handle.bez'`" test 2371 -eq "$Wc_c" || echo 'demo/tpt_handle.bez: original size 2371, current size' "$Wc_c" fi # ============= demo/tpt_lid.bez ============== if test -f 'demo/tpt_lid.bez' -a X"$1" != X"-c"; then echo 'x - skipping demo/tpt_lid.bez (File already exists)' else echo 'x - extracting demo/tpt_lid.bez (Text)' sed 's/^X//' << 'SHAR_EOF' > 'demo/tpt_lid.bez' && # Bezier curves (rotational body) for teapot lid. X bezier_curves: X vertices: 7 vertex_list: X X 0.000000e+00 7.500000e-01 0.000000e+00 X 2.000000E-01 7.500000E-01 0.000000E+00 X 0.000000E+00 6.750000E-01 0.000000E+00 X 5.000000E-02 6.375000E-01 0.000000E+00 X 1.000000E-01 6.000000E-01 0.000000E+00 X 3.250000E-01 6.000000E-01 0.000000E+00 X 3.375000E-01 5.625000E-01 0.000000E+00 X curves: 2 curve_list: X X 1 2 3 4 X X 4 5 6 7 SHAR_EOF chmod 0644 demo/tpt_lid.bez || echo 'restore of demo/tpt_lid.bez failed' Wc_c="`wc -c < 'demo/tpt_lid.bez'`" test 481 -eq "$Wc_c" || echo 'demo/tpt_lid.bez: original size 481, current size' "$Wc_c" fi true || echo 'restore of demo/tpt_spout.bez failed' echo End of part 5, continue with part 6 exit 0 -- Inge Wallin | Thus spake the master programmer: | | "After three days without programming, | ingwa@isy.liu.se | life becomes meaningless." | | Geoffrey James: The Tao of Programming. | exit 0 # Just in case... -- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM Sterling Software, IMD UUCP: uunet!sparky!kent Phone: (402) 291-8300 FAX: (402) 291-4362 Please send comp.sources.misc-related mail to kent@uunet.uu.net.