home *** CD-ROM | disk | FTP | other *** search
- /* :ts=8 */ /* Yes some of us still use vi ! */
- /************************************************************************/
- /* */
- /* Program to generate a TTDDD description of a functional surface. */
- /* */
- /* Usage: */
- /* */
- /* igensurf [-n name] [-s step_s] [-t step_t] */
- /* [-C] [-R] [-T] [-S scale_factor] [-p] [-v] */
- /* [-e expression] [-o output_file] input_file ... */
- /* */
- /************************************************************************/
- /* */
- /* This program is based on the 'gensurf' program found in the Radiance */
- /* Synthetic Imaging System. Radiance (and gensurf) is written by */
- /* Greg Ward. */
- /* */
- /* Igensurf produces a TTDDD object description of a functional surface */
- /* defined by the parametric equations x(s,t), y(s,t) and z(s,t). */
- /* The object is scaled by the factor given with the -S option. */
- /* */
- /* The surface normal is defined ny the right and rule as applied to */
- /* (s,t). S will vary from 0 to 1 in steps of 1/step_s, and t will vary */
- /* from 0 to 1 in steps of 1/step_t. The surface will be composed of */
- /* 2 * step_s * step_t or fewer triangles. */
- /* */
- /* -n defines name of the generated object. */
- /* -C enables generation of face color info. */
- /* -R enables generation of face reflectance info. */
- /* -T enables generation of face transmittance info. */
- /* -S defines a scale factor. */
- /* -p enables phong smothing of the surface. */
- /* -v enables writing of some messages to stderr. */
- /* -e defines extra expressions (can be repeated). */
- /* -o defines name of the TTDDD output file (default is stdout). */
- /* */
- /* See the 'igensurf.doc' file for further information. */
- /* */
- /************************************************************************/
- /* */
- /* EXAMPLE: */
- /* */
- /* To generate a sphere: */
- /* */
- /* igensurf -n ball -e "x(s,t)=sin(PI*s)*cos(2*PI*t)" */
- /* -e "y(x,t)=cos(PI*s)" -e "z(x,t)=sin(PI*s)*sin(2*PI*t)" */
- /* -s 7 -t 10 -S 100 -o ball.ttddd */
- /* */
- /* writetddd ball.ttddd ball.obj */
- /* */
- /* You can of course use a pipe instead of using a temporary file. */
- /* */
- /************************************************************************/
- /* */
- /* BUGS: */
- /* */
- /* Has limits on object sizes. These may be changed by recompiling after*/
- /* changing some defines below. */
- /* It might also be necessary to change the sizes if you are using a */
- /* 512 K machine. */
- /* */
- /* All points, edges and faces are saved in arrays. The program does a */
- /* linear search for points before adding new points. This method can */
- /* be very time consuming for big objects. */
- /* */
- /* igensurf doesn't free allocated space itself. Hopefully the OS, or */
- /* the compiler will do it. It only uses standard malloc calls. */
- /* */
- /************************************************************************/
- /* */
- /* Author: Helge E. Rasmussen (her@compel.dk) */
- /* */
- /* Original Radiance code by Greg Ward. */
- /* */
- /* You may use the program and the source code in any way you want as */
- /* long as you do not resell the software as your own, or use it in a */
- /* commercial product. */
- /* */
- /* Please let me know if you find any bugs, or have ideas for enhance- */
- /* ments. */
- /* */
- /************************************************************************/
-
- #define Version "v. 1.0" /* Current version of program. */
-
-
- /* Increase these for very big objects */
- /* Decrease them if you are using a 512 K machine */
-
- #define Max_Nbr_Points 10000
- #define Max_Nbr_Edges 10000
- #define Max_Nbr_Faces 10000
-
-
- #include <math.h>
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
- #include <errno.h>
- #ifdef AMIGA
- #include <stdlib.h>
- #else
- #include <unistd.h>
- #endif
-
- #include "calc.h"
-
- #ifndef PI
- #define PI M_PI
- #endif
-
- #ifndef TRUE
- #define TRUE 1
- #define FALSE 0
- #endif
-
- #define FTINY (double) 1e-6
- #define Buffer_Length 256
- #define ABS(x) ((x)>=0 ? (x) : -(x))
-
- typedef int Boolean_T;
-
- typedef struct {
- unsigned char R;
- unsigned char G;
- unsigned char B;
- } Color_T;
-
- typedef struct {
- double X;
- double Y;
- double Z;
- } Vector_T;
-
- typedef struct {
- int P1;
- int P2;
- } Edge_T;
-
- typedef struct {
- int E1;
- int E2;
- int E3;
- Color_T Color;
- Color_T Refl;
- Color_T Trans;
- } Face_T;
-
- #define X_FUNC "x" /* x function name */
- #define Y_FUNC "y" /* y function name */
- #define Z_FUNC "z" /* z function name */
- #define CR_FUNC "cr" /* color R function name */
- #define CG_FUNC "cg" /* color G function name */
- #define CB_FUNC "cb" /* color B function name */
- #define RR_FUNC "rr" /* refl. R function name */
- #define RG_FUNC "rg" /* refl. G function name */
- #define RB_FUNC "rb" /* refl. B function name */
- #define TR_FUNC "tr" /* trans R function name */
- #define TG_FUNC "rg" /* trans G function name */
- #define TB_FUNC "tb" /* trans B function name */
-
- char Object_Name[Buffer_Length+1];/* Name of object. */
-
- Boolean_T Verbose = FALSE; /* Be verbose */
- Boolean_T Phong = FALSE; /* Phong smoothing? */
- Boolean_T Compute_Color = FALSE; /* Compute color */
- Boolean_T Compute_Refl = FALSE; /* Compute reflectance */
- Boolean_T Compute_Trans = FALSE; /* Compute transmittance */
- int Step_S = 10; /* Number of steps (s). */
- int Step_T = 10; /* Number of steps (t). */
- double Scale_Factor = 1.0; /* Scale factor */
- double Precision = 1e-7; /* Precision in coordinates */
- Vector_T *Row0 = NULL;
- Vector_T *Row1 = NULL;
- Vector_T *Row2 = NULL;
- FILE *O_Stream = NULL;
- Boolean_T Generate_Done = FALSE;
-
- Vector_T Points[Max_Nbr_Points]; /* Table of points */
- int Nbr_Points = 0;
-
- Edge_T Edges[Max_Nbr_Edges]; /* Table of edges */
- int Nbr_Edges = 0;
-
- Face_T Faces[Max_Nbr_Faces]; /* Table of faces */
- int Nbr_Faces = 0;
-
-
- void Error(Txt)
- char *Txt;
- /************************************************************************/
- /* */
- /* Write error messages and stop the program. */
- /* */
- /************************************************************************/
- {
-
- fprintf(stderr, "Error: %s\n", Txt);
- exit(9);
-
- } /* Error */
-
-
- void Usage()
- /************************************************************************/
- /* */
- /* Write a usage message to stderr, and stop the program. */
- /* */
- /************************************************************************/
- {
-
- fprintf(stderr, "Usage: igensurf [-n name] [-s step_s] [-t step_t]\n");
- fprintf(stderr, " [-C] [-R] [-T] [-S scale_factor] [-p] [-v]\n");
- fprintf(stderr, " [-e expression] [-o output_file] input_file ...\n");
- exit(1);
-
- } /* Usage */
-
-
- int Get_Point(Point)
- Vector_T *Point;
- /************************************************************************/
- /* */
- /* Get id for the point 'Point'. */
- /* If no such point exist, then create it and return the newly created */
- /* id. */
- /* */
- /************************************************************************/
- {
- int i;
-
- for (i = Nbr_Points-1; i >= 0; i--) {
-
- if (ABS(Point->X - Points[i].X) < Precision &&
- ABS(Point->Y - Points[i].Y) < Precision &&
- ABS(Point->Z - Points[i].Z) < Precision) return(i);
-
- } /* for */
-
- if (Nbr_Points >= Max_Nbr_Points) Error("Too many points");
-
- Points[Nbr_Points].X = Point->X;
- Points[Nbr_Points].Y = Point->Y;
- Points[Nbr_Points].Z = Point->Z;
-
- return(Nbr_Points++);
-
- } /* Get_Point */
-
- int Get_Edge(P1, P2)
- int P1;
- int P2;
- /************************************************************************/
- /* */
- /* Get id for the edge that connects the points P1 and P2. */
- /* If no such edge exists, then create it and return the newly created */
- /* id. */
- /* */
- /************************************************************************/
- {
- int i;
-
- for (i = Nbr_Edges-1; i >= 0; i--) {
-
- if ( (Edges[i].P1 == P1 && Edges[i].P2 == P2) ||
- (Edges[i].P1 == P2 && Edges[i].P2 == P1) ) return(i);
-
- } /* for */
-
- if (Nbr_Edges >= Max_Nbr_Edges) Error("Too many edges");
-
- Edges[Nbr_Edges].P1 = P1;
- Edges[Nbr_Edges].P2 = P2;
-
- return(Nbr_Edges++);
-
- } /* Get_Edge */
-
- void Add_Face(P1, P2, P3, Color, Refl, Trans)
- int P1;
- int P2;
- int P3;
- Color_T *Color;
- Color_T *Refl;
- Color_T *Trans;
- /************************************************************************/
- /* */
- /* Add a new face connecting P1, P2 and P3 to the face table. */
- /* The corresponding edges will be created if they don't exist. */
- /* */
- /************************************************************************/
- {
- int i;
- int E1, E2, E3;
-
- E1 = Get_Edge(P1, P2);
- E2 = Get_Edge(P2, P3);
- E3 = Get_Edge(P3, P1);
-
- for (i = Nbr_Faces-1; i >= 0; i--) {
-
- if (Faces[i].E1 == E1 && Faces[i].E2 == E2 &&
- Faces[i].E3 == E3) return;
-
- } /* for */
-
-
- if (Nbr_Faces >= Max_Nbr_Faces) Error("Too many Faces");
-
- Faces[Nbr_Faces].E1 = Get_Edge(P1, P2);
- Faces[Nbr_Faces].E2 = Get_Edge(P2, P3);
- Faces[Nbr_Faces].E3 = Get_Edge(P3, P1);
-
- Faces[Nbr_Faces].Color.R = Color->R;
- Faces[Nbr_Faces].Color.G = Color->G;
- Faces[Nbr_Faces].Color.B = Color->B;
-
- Faces[Nbr_Faces].Refl.R = Refl->R;
- Faces[Nbr_Faces].Refl.G = Refl->G;
- Faces[Nbr_Faces].Refl.B = Refl->B;
-
- Faces[Nbr_Faces].Trans.R = Trans->R;
- Faces[Nbr_Faces].Trans.G = Trans->G;
- Faces[Nbr_Faces].Trans.B = Trans->B;
-
- Nbr_Faces++;
-
- } /* Add_Face */
-
- void Write_TTDDD_Object()
- /************************************************************************/
- /* */
- /* Write the object saved in the global variables to O_Stream in TTDDD */
- /* format. */
- /* Set the name of the object to 'Object_Name'. */
- /* If 'Phong' is TRUE, the object should be phong smoothed. */
- /* */
- /************************************************************************/
- {
- int i;
-
- if (Nbr_Points == 0) return;
-
- if (Verbose)
- fprintf(stderr,
- "Generating TTDDD description for %s...\n", Object_Name);
-
- fprintf(O_Stream, "OBJ Begin %% Begin Object chunk\n");
- fprintf(O_Stream, "\n");
-
- fprintf(O_Stream, "DESC Begin %% Begin DESC sub-chunk\n");
- fprintf(O_Stream, "\n");
-
- fprintf(O_Stream, "\tNAME \"%s\"\n", Object_Name);
- fprintf(O_Stream, "\n");
- fprintf(O_Stream, "\tSHAP Shape 2 %% Axis object\n");
- fprintf(O_Stream, "\tSHAP Lamp 0 %% Not a lamp\n");
- fprintf(O_Stream, "\n");
- fprintf(O_Stream, "\tPOSI X=0.0 Y=0.0 Z=0.0 %% Position.\n");
- fprintf(O_Stream, "\n");
-
- fprintf(O_Stream, "\tAXIS XAxis X=1 %% Defaults to 1 0 0\n");
- fprintf(O_Stream, "\tAXIS YAxis Y=1 %% Defaults to 0 1 0\n");
- fprintf(O_Stream, "\tAXIS ZAxis Z=1 %% Defaults to 0 0 1\n");
- fprintf(O_Stream, "\n");
-
- fprintf(O_Stream, "\tSIZE X=32 Y=32 Z=32 %% Defaults to 32.0\n");
- fprintf(O_Stream, "\n");
-
- /* POINTS */
-
- if (Verbose) fprintf(stderr, "Points (%d)...\n", Nbr_Points);
-
- fprintf(O_Stream, "\tPNTS PCount %d %% Number of points\n", Nbr_Points);
- fprintf(O_Stream, "\n");
- for (i = 0; i < Nbr_Points; i++) {
- fprintf(O_Stream, "\tPNTS Point[%d] %lf %lf %lf\n",
- i,
- Scale_Factor * Points[i].X,
- Scale_Factor * Points[i].Y,
- Scale_Factor * Points[i].Z);
- } /* for */
- fprintf(O_Stream, "\n");
-
-
- /* EDGES */
- if (Verbose) fprintf(stderr, "Edges (%d)...\n", Nbr_Edges);
-
- fprintf(O_Stream, "\tEDGE ECount %d %% Number of edges\n", Nbr_Edges);
- fprintf(O_Stream, "\n");
- for (i = 0; i < Nbr_Edges; i++) {
- fprintf(O_Stream, "\tEDGE Edge[%d] %d %d\n",
- i, Edges[i].P1, Edges[i].P2);
- } /* for */
- fprintf(O_Stream, "\n");
-
-
- /* FACES */
- if (Verbose) fprintf(stderr, "Faces (%d)...\n", Nbr_Faces);
-
- fprintf(O_Stream, "\tFACE TCount %d %% Number of faces\n", Nbr_Faces);
- fprintf(O_Stream, "\n");
- for (i = 0; i < Nbr_Faces; i++) {
- fprintf(O_Stream, "\tFACE Connect[%d] %d %d %d\n",
- i, Faces[i].E1, Faces[i].E2, Faces[i].E3);
- } /* for */
- fprintf(O_Stream, "\n");
-
-
- if (Compute_Color) {
-
- /* COLORS */
- if (Verbose) fprintf(stderr, "Colors (%d)...\n", Nbr_Faces);
-
- fprintf(O_Stream, "\tCLST Count %d %% Number of colors\n",Nbr_Faces);
- fprintf(O_Stream, "\n");
- for (i = 0; i < Nbr_Faces; i++) {
- fprintf(O_Stream, "\tCLST Color[%d] %d %d %d\n", i,
- Faces[i].Color.R,
- Faces[i].Color.G,
- Faces[i].Color.B);
- } /* for */
- fprintf(O_Stream, "\n");
-
- } /* if */
-
- if (Compute_Refl) {
-
- /* COLORS */
- if (Verbose) fprintf(stderr, "Reflectance (%d)...\n", Nbr_Faces);
-
- fprintf(O_Stream, "\tRLST Count %d %% Number of colors\n",Nbr_Faces);
- fprintf(O_Stream, "\n");
- for (i = 0; i < Nbr_Faces; i++) {
- fprintf(O_Stream, "\tRLST Color[%d] %d %d %d\n", i,
- Faces[i].Refl.R,
- Faces[i].Refl.G,
- Faces[i].Refl.B);
- } /* for */
- fprintf(O_Stream, "\n");
-
- } /* if */
-
- if (Compute_Trans) {
-
- /* COLORS */
- if (Verbose) fprintf(stderr, "Transmittance (%d)...\n", Nbr_Faces);
-
- fprintf(O_Stream, "\tTLST Count %d %% Number of colors\n",Nbr_Faces);
- fprintf(O_Stream, "\n");
- for (i = 0; i < Nbr_Faces; i++) {
- fprintf(O_Stream, "\tTLST Color[%d] %d %d %d\n", i,
- Faces[i].Trans.R,
- Faces[i].Trans.G,
- Faces[i].Trans.B);
- } /* for */
- fprintf(O_Stream, "\n");
-
- } /* if */
-
- fprintf(O_Stream, "\tMTTR Type 4 %%\n");
- fprintf(O_Stream, "\tMTTR Index 1.0 %%\n");
- fprintf(O_Stream, "\n");
-
- fprintf(O_Stream, "\tSPEC Specularity 0\n");
- fprintf(O_Stream, "\tSPEC Hardness 0\n");
- fprintf(O_Stream, "\n");
-
- fprintf(O_Stream, "\tPRP0[0] 0 %% Blending (dither) factor.\n");
- fprintf(O_Stream, "\tPRP0[1] 0 %% Roughness factor.\n");
- fprintf(O_Stream, "\tPRP0[2] 0 %% Shading on/off.\n");
- fprintf(O_Stream, "\tPRP0[3] %d %% Phong shading flag.\n", !Phong);
- fprintf(O_Stream, "\tPRP0[4] 0 %% Glossy flag. \n");
- fprintf(O_Stream, "\tPRP0[5] 0 %% Quickdraw flag.\n");
- fprintf(O_Stream, "\n");
-
- fprintf(O_Stream, "End DESC %% End of DESC sub-chunk\n");
- fprintf(O_Stream, "\n");
-
- fprintf(O_Stream, "TOBJ %% End of object hierachy.\n");
- fprintf(O_Stream, "\n");
-
- fprintf(O_Stream, "End OBJ %% End of object chunk\n");
- fprintf(O_Stream, "\n");
-
- Nbr_Points = 0;
- Nbr_Edges = 0;
- Nbr_Faces = 0;
-
- } /* Write_TTDDD_Object */
-
-
- Boolean_T Face_Is_Ok(Point0, Point1, Point2)
- Vector_T *Point0;
- Vector_T *Point1;
- Vector_T *Point2;
- /************************************************************************/
- /* */
- /* Check if the three points defines a triangle. */
- /* Return TRUE if they do. */
- /* */
- /************************************************************************/
- {
- Vector_T V1;
- Vector_T V2;
- double Vx, Vy, Vz;
-
- V1.X = Point1->X - Point0->X;
- V1.Y = Point1->Y - Point0->Y;
- V1.Z = Point1->Z - Point0->Z;
-
- V2.X = Point2->X - Point0->X;
- V2.Y = Point2->Y - Point0->Y;
- V2.Z = Point2->Z - Point0->Z;
-
- /* Cross product: */
- Vx = V1.Y * V2.Z - V1.Z * V2.Y;
- Vy = V1.Z * V2.X - V1.X * V2.Z;
- Vz = V1.X * V2.Y - V1.Y * V2.X;
-
- if (ABS(Vx) < FTINY &&
- ABS(Vy) < FTINY &&
- ABS(Vz) < FTINY) return(FALSE);
-
- return(TRUE);
-
- } /* Face_Is_Ok */
-
-
- void Compute_Face_Info(s, t, Point0, Point1, Point2, Color, Refl, Trans)
- double s, t;
- Vector_T *Point0, *Point1, *Point2;
- Color_T *Color;
- Color_T *Refl;
- Color_T *Trans;
- /************************************************************************/
- /* */
- /* Compute Color, Reflectance and Transmittance for the face defined by */
- /* Point0, Point1 and Point2 (plus s and t). */
- /* */
- /************************************************************************/
- {
- double Arguments[5];
-
- if (!Compute_Color && !Compute_Refl && !Compute_Trans) return;
- Arguments[0] = s;
- Arguments[1] = t;
- Arguments[2] = (Point0->X + Point1->X + Point2->X) / 3.0;
- Arguments[3] = (Point0->Y + Point1->Y + Point2->Y) / 3.0;
- Arguments[4] = (Point0->Z + Point1->Z + Point2->Z) / 3.0;
-
- if (Compute_Color) {
- Color->R = 255.0 * Func_Value(CR_FUNC, 5, Arguments);
- Color->G = 255.0 * Func_Value(CG_FUNC, 5, Arguments);
- Color->B = 255.0 * Func_Value(CB_FUNC, 5, Arguments);
- }
-
- if (Compute_Refl) {
- Refl->R = 255.0 * Func_Value(RR_FUNC, 5, Arguments);
- Refl->G = 255.0 * Func_Value(RG_FUNC, 5, Arguments);
- Refl->B = 255.0 * Func_Value(RB_FUNC, 5, Arguments);
- }
-
- if (Compute_Trans) {
- Trans->R = 255.0 * Func_Value(TR_FUNC, 5, Arguments);
- Trans->G = 255.0 * Func_Value(TG_FUNC, 5, Arguments);
- Trans->B = 255.0 * Func_Value(TB_FUNC, 5, Arguments);
- }
-
-
- } /* Compute_Face_Info */
-
- void Generate_Face(s, t, Point0, Point1, Point2, Point3)
- double s, t;
- Vector_T *Point0, *Point1, *Point2, *Point3;
- /************************************************************************/
- /* */
- /* Add the square given by the four points to the face/edge/point lists.*/
- /* */
- /************************************************************************/
- {
- int Face1_Ok, Face2_Ok;
- int Point0_Id, Point1_Id, Point2_Id, Point3_Id;
- Color_T Color, Refl, Trans;
-
- Face1_Ok = Face_Is_Ok(Point0, Point1, Point2);
- Face2_Ok = Face_Is_Ok(Point1, Point2, Point3);
-
- if (Face1_Ok || Face2_Ok) {
-
- if (Face1_Ok) Point0_Id = Get_Point(Point0);
-
- Point1_Id = Get_Point(Point1);
- Point2_Id = Get_Point(Point2);
-
- if (Face2_Ok) Point3_Id = Get_Point(Point3);
-
- if (Face1_Ok) {
- Compute_Face_Info(s, t, Point0, Point1, Point2,
- &Color, &Refl, &Trans);
- Add_Face(Point0_Id, Point1_Id, Point2_Id,
- &Color, &Refl, &Trans);
- }
-
- if (Face2_Ok) {
- Compute_Face_Info(s, t, Point2, Point1, Point3,
- &Color, &Refl, &Trans);
- Add_Face(Point2_Id, Point1_Id, Point3_Id,
- &Color, &Refl, &Trans);
- }
-
- } /* if */
-
- } /* Generate_Face */
-
- Compute_Row(s, Row, Step_Size)
- double s;
- register Vector_T *Row;
- int Step_Size;
- /************************************************************************/
- /* */
- /* Compute row of values for a given 's'. */
- /* */
- /************************************************************************/
- {
- double Arguments[2];
- int end;
- register int i;
-
-
- if (s < -FTINY || s > 1.0+FTINY) return;
-
- i = 0;
- end = Step_Size;
-
- Arguments[0] = s;
-
- while (i <= end) {
-
- Arguments[1] = (double) i / Step_Size;
-
- Row[i].X = Func_Value(X_FUNC, 2, Arguments);
- Row[i].Y = Func_Value(Y_FUNC, 2, Arguments);
- Row[i].Z = Func_Value(Z_FUNC, 2, Arguments);
-
- i++;
-
- } /* while */
-
-
- } /* Compute_Row */
-
- int Generate_Object()
- /************************************************************************/
- /* */
- /* Generate the points, edges and faces of the current object. */
- /* */
- /************************************************************************/
- {
- int i, j;
- int New_Step_S;
- int New_Step_T;
- Vector_T *Tmp_Row;
-
-
- /* Get Step_S and Step_T from user variables. */
-
- New_Step_S = Var_Value("step_s");
- New_Step_T = Var_Value("step_t");
-
- if (New_Step_S <= 0 || New_Step_T <= 0 ||
- New_Step_S > 999 || New_Step_T > 999) {
-
- fprintf(stderr, "Illegal values for step_s (%d) or step_t (%d)\n",
- New_Step_S, New_Step_T);
- exit(1);
-
- } /* if */
-
- /* Allocate space for three rows if they have changed size. */
-
- if (Row0 == NULL || Step_T != New_Step_T) {
-
- if (Row0 != NULL) free(Row0);
- Row0 = (Vector_T *) malloc( (New_Step_T+3) * sizeof(Vector_T) );
- if (Row0 == NULL) Error("Error in malloc");
-
- if (Row1 != NULL) free(Row1);
- Row1 = (Vector_T *) malloc( (New_Step_T+3) * sizeof(Vector_T) );
- if (Row1 == NULL) Error("Error in malloc");
-
- if (Row2 != NULL) free(Row2);
- Row2 = (Vector_T *) malloc( (New_Step_T+3) * sizeof(Vector_T) );
- if (Row2 == NULL) Error("Error in malloc");
-
-
- } /* if */
-
- Step_S = New_Step_S;
- Step_T = New_Step_T;
-
-
-
- if (Verbose) fprintf(stderr, "Computing surfaces (%d):\n", Step_S - 1);
-
- /* Initialize the first rows */
- /* It is not neccessary to initialize Row0, as it is */
- /* computed as the first step in the main loop. */
-
- Compute_Row(0.0, Row1, Step_T);
- Compute_Row(1.0/Step_S, Row2, Step_T);
-
-
- for (i = 0; i < Step_S; i++) {
-
- if (Verbose) {
- if ( i != 0 && i % 10 == 0) fprintf(stderr, "%d", i);
- else fprintf(stderr, ".");
- }
- /* compute next row */
- Tmp_Row = Row0;
- Row0 = Row1;
- Row1 = Row2;
- Row2 = Tmp_Row;
-
- Compute_Row((double)(i + 2) / Step_S, Row2, Step_T);
-
- for (j = 0; j < Step_T; j++) {
-
- if ( (i + j) & 1 ) {
-
- Generate_Face((double) i / Step_S, (double) j / Step_T,
- &Row0[j], &Row1[j], &Row0[j+1], &Row1[j+1]);
-
- } else {
-
- Generate_Face((double) i / Step_S, (double) j / Step_T,
- &Row1[j], &Row1[j+1], &Row0[j], &Row0[j+1]);
-
- }
-
- } /* for */
-
- } /* for */
-
- if (Verbose) fprintf(stderr, "\n");
-
- } /* Generate_Object */
-
- Boolean_T On_Off(Text)
- char *Text;
- /************************************************************************/
- /* */
- /* Return TRUE if text is "on" or "yes", otherwise FALSE. */
- /* */
- /************************************************************************/
- {
- if (strcmp(Text, "on") == 0 ||
- strcmp(Text, "yes") == 0) return(TRUE);
-
- return(FALSE);
-
- } /* On_Off */
-
- int Exec_Command(Command_Line, Line_Number)
- char *Command_Line;
- int Line_Number;
- /************************************************************************/
- /* */
- /* Handle special commands: */
- /* */
- /* #name [object_name] */
- /* Set the object name. This name will be used for new objects. */
- /* */
- /* #add */
- /* Generate the surface, and add it to the current object. */
- /* */
- /* #write [object_name] */
- /* Write the current object to the TTDDD file and start a new */
- /* object. */
- /* */
- /* #generate [object_name] */
- /* Generate the surface, add it to the current object, and write */
- /* it to the TTDDD file. This is the same as */
- /* #add followed by #write [object_name] */
- /* */
- /* #scale scale_factor */
- /* Change the scale factor to 'scale_factor'. */
- /* */
- /* #phong [on|off] */
- /* #smooth [on|off] */
- /* Activate/Deactivate phong smoothing. */
- /* */
- /* #color [on|off] */
- /* Activate/deactivate generation of face color info. */
- /* The functions cr, cb and cg MUST be defined! */
- /* */
- /* #refl [on|off] */
- /* Activate/deactivate generation of face reflectance info. */
- /* The functions rr, rb and rg MUST be defined! */
- /* */
- /* #trans [on|off] */
- /* Activate/deactivate generation of face transmittance info. */
- /* The functions tr, tb and tg MUST be defined! */
- /* */
- /************************************************************************/
- {
- char *Command;
- char *Rest;
- int i;
-
- for (i = 0; Command_Line[i] != '\0'; i++)
- Command_Line[i] = tolower(Command_Line[i]);
-
- Command = strtok(&Command_Line[1], "\n \t");
- if (Command == NULL) goto SyntaxError;
- Rest = strtok(NULL, "\n \t");
-
- if (strcmp(Command, "add") == 0) {
-
- Generate_Object();
- Generate_Done = TRUE;
-
- } else if (strcmp(Command, "name") == 0) {
-
- if (Rest != NULL && *Rest != '\0') strcpy(Object_Name, Rest);
-
- } else if (strcmp(Command, "write") == 0) {
-
- if (Rest != NULL && *Rest != '\0') strcpy(Object_Name, Rest);
-
- if (Nbr_Points > 0) Write_TTDDD_Object();
-
- } else if (strcmp(Command, "generate") == 0) {
-
- if (Rest != NULL && *Rest != '\0') strcpy(Object_Name, Rest);
-
- Generate_Object();
- Generate_Done = TRUE;
- if (Nbr_Points > 0) Write_TTDDD_Object();
-
- } else if (strcmp(Command, "scale") == 0) {
-
- if (Rest == NULL) goto SyntaxError;
-
- Scale_Factor = atof(Rest);
- if (Scale_Factor <= 0.0) {
- fprintf(stderr, "Invalid scale factor in line %d:\n",
- Line_Number);
- fprintf(stderr, "%s\n", Command_Line);
- exit(1);
- }
- Precision = 1.0 / Scale_Factor; /* Precision of coordinates */
- if (Verbose) fprintf(stderr, "New scale factor is %lf\n",
- Scale_Factor);
-
- } else if (strcmp(Command, "phong") == 0 ||
- strcmp(Command, "smooth") == 0) {
-
- if (Rest == NULL) goto SyntaxError;
- Phong = On_Off(Rest);
-
- if (Verbose) fprintf(stderr, "Phong smoothing is %s\n",
- Phong ? "on" : "off");
-
-
- } else if (strcmp(Command, "color") == 0) {
-
- if (Rest == NULL) goto SyntaxError;
- Compute_Color = On_Off(Rest);
-
- if (Verbose) fprintf(stderr, "Compute color is %s\n",
- Compute_Color ? "on" : "off");
-
- } else if (strncmp(Command, "refl", 4) == 0) {
-
- if (Rest == NULL) goto SyntaxError;
- Compute_Refl = On_Off(Rest);
-
- if (Verbose) fprintf(stderr, "Compute reflectance is %s\n",
- Compute_Refl ? "on" : "off");
-
-
- } else if (strncmp(Command, "trans", 5) == 0) {
-
- if (Rest == NULL) goto SyntaxError;
- Compute_Trans = On_Off(Rest);
-
- if (Verbose) fprintf(stderr, "Compute Transmittance is %s\n",
- Compute_Trans ? "on" : "off");
-
-
- } else goto SyntaxError;
-
- return(0);
-
- SyntaxError:
- fprintf(stderr, "Invalid command in line %d:\n", Line_Number);
- fprintf(stderr, "%s\n", Command_Line);
- exit(1);
-
-
- } /* Exec_Command */
-
- main(argc, argv)
- int argc;
- char *argv[];
- /************************************************************************/
- /* */
- /* Main program. */
- /* */
- /************************************************************************/
- {
- int i;
- char *O_FileName = NULL;
-
-
-
- if (argc == 1) Usage();
-
- strcpy(Object_Name, "IGENSURF");
-
- for (i = 1; i < argc && *argv[i] == '-'; i++) {
-
- switch (argv[i][1]) {
- case 'C':
- Compute_Color = TRUE;
- break;
-
- case 'R':
- Compute_Refl = TRUE;
- break;
-
- case 'T':
- Compute_Trans = TRUE;
- break;
-
- case 'n':
- strcpy(Object_Name, argv[++i]);
- break;
-
- case 'S':
- Scale_Factor = atof(argv[++i]);
- if (Scale_Factor <= 0.0) {
- fprintf(stderr, "Invalid scale factor %lf:\n", Scale_Factor);
- exit(1);
- }
- Precision = 1.0 / Scale_Factor; /* Precision of coordinates */
- break;
-
- case 'p':
- Phong = TRUE;
- break;
-
- case 'v':
- Verbose = TRUE;
- break;
-
- case 's':
- Step_S = atoi(argv[++i]);
- if (Step_S <= 0) {
- fprintf(stderr, "Invalid Step_S\n", Step_S);
- exit(1);
- }
- break;
-
- case 't':
- Step_T = atoi(argv[++i]);
- if (Step_T <= 0) {
- fprintf(stderr, "Invalid Step_T\n", Step_T);
- exit(1);
- }
- break;
-
- case 'e':
- String_Compile(argv[++i], NULL, 0, NULL);
- break;
-
- case 'o':
- if (O_FileName != NULL) Usage();
- O_FileName = argv[++i];
- break;
-
- default:
- Usage();
- break;
-
- } /* switch */
-
- } /* for */
-
- if (Verbose) fprintf(stderr, "igensurf %s\n", Version);
-
- if (O_FileName == NULL) O_Stream = stdout;
- else {
- O_Stream = fopen(O_FileName, "w");
- if (O_Stream == NULL) Error("Couldn't open the output file");
- }
-
- /* Define PI, step_s and step_t so that they can be used */
- /* in expressions */
-
- eclock = 0;
- Var_Set("PI", ':', PI);
- Var_Set("step_s", ':', (double) Step_S);
- Var_Set("step_t", ':', (double) Step_T);
-
- while (i < argc) {
-
- if (Verbose) fprintf(stderr, "Compiling %s\n", argv[i]);
-
- File_Compile(argv[i++], Exec_Command);
-
- } /* while */
-
- if (!Generate_Done) Generate_Object();
-
- if (Nbr_Points > 0) Write_TTDDD_Object();
-
- if (O_Stream != stdout) fclose(O_Stream);
-
- if (Verbose) fprintf(stderr, "Done.\n");
-
- exit(0);
-
- } /* main */
-