home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- * Generic parser for the "Irit" solid modeller. *
- * *
- * Written by: Gershon Elber Ver 0.2, Sep. 1991 *
- *****************************************************************************/
-
- #ifdef __MSDOS__
- #include <stdlib.h>
- #endif /* __MSDOS__ */
-
- #include <stdio.h>
- #include <ctype.h>
- #include <math.h>
- #include <string.h>
- #include <setjmp.h>
- #include "irit_sm.h"
- #include "iritprsr.h"
-
- #define LOAD_COLOR 14 /* Index color 1 by default. */
-
- #define UNGET_STACK_SIZE 5 /* Internal stack size. */
-
- typedef enum { /* List of all possible tokens enumerated. */
- TOKEN_NONE,
-
- TOKEN_OPEN_PAREN,
- TOKEN_CLOSE_PAREN,
-
- TOKEN_E2,
- TOKEN_P2,
- TOKEN_E3,
- TOKEN_P3,
-
- TOKEN_NUMBER,
- TOKEN_STRING,
- TOKEN_VECTOR,
- TOKEN_MATRIX,
- TOKEN_CTLPT,
- TOKEN_VERTEX,
- TOKEN_POLYGON,
- TOKEN_POLYLINE,
- TOKEN_POINTLIST,
- TOKEN_OBJECT,
- TOKEN_COLOR,
- TOKEN_RGB,
- TOKEN_INTERNAL,
- TOKEN_NORMAL,
- TOKEN_PLANE,
- TOKEN_CURVE,
- TOKEN_SURFACE,
-
- TOKEN_OTHER = 100, /* Probably names & numbers. */
- TOKEN_EOF = -1
- } TokenType;
-
- typedef enum { /* Possible error code during data parsing. */
- IP_NO_ERR = 0,
-
- IP_ERR_NUMBER_EXPECTED,
- IP_ERR_OPEN_PAREN_EXPECTED,
- IP_ERR_CLOSE_PAREN_EXPECTED,
- IP_ERR_LIST_COMP_UNDEF,
- IP_ERR_UNDEF_EXPR_HEADER,
- IP_ERR_PT_TYPE_EXPECTED,
- IP_ERR_OBJECT_EMPTY,
- IP_ERR_MIXED_TYPES,
- IP_STR_NOT_IN_QUOTES,
- IP_ERR_OBJECT_EXPECTED,
- IP_ERR_CAGD_LIB_ERR,
- IP_ERR_STACK_OVERFLOW,
- IP_ERR_DEGEN_POLYGON,
-
- IP_WRN_OBJ_NAME_TRUNC = 100
- } IritPrsrErrType;
-
- static int IPGlblLineCount = 0; /* Used to locate errors in input file. */
- static IritPrsrErrType IPGlblParserError = IP_NO_ERR; /* Last err # found. */
- static char IPGlblTokenError[LINE_LEN_LONG]; /* Last token error was found. */
- static jmp_buf LclLongJumpBuffer; /* Used in error traping. */
- static int GlblToken = 0, /* Used by the parser, to unget token. */
- GlblLineCount = 1; /* Used to locate errors in input file. */
- static char GlblStringToken[UNGET_STACK_SIZE][LINE_LEN_LONG];/* Unget tokens.*/
-
- static IPObjectStruct *AllSrfs = NULL;
- static IPObjectStruct *AllCrvs = NULL;
- static IPObjectStruct *AllPolys = NULL;
-
- int IritPrsrPolyListCirc = TRUE;
- int IritPrsrWasViewMat = FALSE,
- IritPrsrWasPrspMat = FALSE;
- MatrixType IritPrsrViewMat = { /* Isometric view, by default. */
- { -0.707107, -0.408248, 0.577350, 0.000000 },
- { 0.707107, -0.408248, 0.577350, 0.000000 },
- { 0.000000, 0.816496, 0.577350, 0.000000 },
- { 0.000000, 0.000000, 0.000000, 1.000000 }
- };
- MatrixType IritPrsrPrspMat = {
- { 1, 0, 0, 0 },
- { 0, 1, 0, 0 },
- { 0, 0, 0.1, -0.35 },
- { 0, 0, 0.35, 1.0 }
- };
-
- static void UnGetToken(char *StringToken);
- static void GetStringToken(FILE *f, char *StringToken);
- static TokenType GetToken(FILE *f, char *StringToken);
- static void GetVertexAttributes(IPVertexStruct *PVertex, FILE *f);
- static void GetPolygonAttributes(IPPolygonStruct *PPolygon, FILE *f);
- static void GetObjectAttributes(IPObjectStruct *PObject, FILE *f);
- static void GetPointData(FILE *f, IPPolygonStruct *PPolygon);
- static void IPUpdatePolyPlane(IPPolygonStruct *PPoly);
- static void ParserError(IritPrsrErrType ErrNum, char *Msg);
-
- static void IritPrsrGetAllObjects(FILE *f, IPObjectStruct *PObjParent);
- static void GetCloseParenToken(FILE *f);
- static void SkipToCloseParenToken(FILE *f);
- static void GetNumericToken(FILE *f, RealType *r);
- static void IritPrsrGetAuxObject(FILE *f, IPObjectStruct *PObj);
-
- /*****************************************************************************
- * Routine to read the data from a given file. *
- *****************************************************************************/
- IPObjectStruct *IritPrsrGetObjects(FILE *f)
- {
- IPObjectStruct *PObjs, *PTmp;
-
- AllSrfs = NULL;
- AllCrvs = NULL;
- AllPolys = NULL;
-
- /* If the following gain control and is non zero - its from error! */
- if (setjmp(LclLongJumpBuffer) != 0) {
- if (f != NULL) fclose(f);
- return NULL;
- }
-
- GlblToken = 0; /* Used in UnGetToken token buffer. */
- IPGlblParserError = IP_NO_ERR; /* Reset errors. */
- GlblLineCount = 1; /* Reset line counter. */
-
- PTmp = IritPrsrNewObjectStruct();
- IritPrsrGetAllObjects(f, PTmp);
-
- if (AllCrvs != NULL || AllSrfs != NULL) {
- if ((PObjs = IritPrsrProcessFreeForm(AllCrvs, AllSrfs)) != NULL)
- {
- for (PTmp = PObjs; PTmp -> Pnext != NULL; PTmp = PTmp -> Pnext) {
- if (!IP_HAS_OBJ_COLOR(PTmp)) {
- PTmp -> Color = LOAD_COLOR;
- IP_SET_OBJ_COLOR(PTmp);
- }
- }
- PTmp -> Pnext = AllPolys;
- AllPolys = PObjs;
- }
- }
-
- fclose(f);
- return AllPolys;
- }
-
- /*****************************************************************************
- * Routine to read the geometry data from a given file. Reads "[OBJECT ..." *
- * prefixes only and invoke the auxiliary routine. *
- * Note objects may be recursively defined. *
- *****************************************************************************/
- static void IritPrsrGetAllObjects(FILE *f, IPObjectStruct *PObjParent)
- {
- char StringToken[LINE_LEN_LONG];
- TokenType Token;
- int WasObjectToken = FALSE,
- Quit = FALSE;
- IPObjectStruct *PObj;
-
- while (!Quit) {
- while ((Token = GetToken(f, StringToken)) != TOKEN_OPEN_PAREN &&
- Token != TOKEN_CLOSE_PAREN &&
- Token != TOKEN_EOF);
-
- if (Token == TOKEN_CLOSE_PAREN || Token == TOKEN_EOF)
- {
- if (Token == TOKEN_CLOSE_PAREN)
- UnGetToken(StringToken);
- Quit = TRUE;
- break;
- }
-
- switch (GetToken(f, StringToken)) {
- case TOKEN_OBJECT:
- WasObjectToken = TRUE;
- PObj = IritPrsrNewObjectStruct();
-
- /* The following handle optional attributes in record. */
- if (GetToken(f, StringToken) == TOKEN_OPEN_PAREN)
- GetObjectAttributes(PObj, f);
- else
- {
- UnGetToken(StringToken);
- }
-
- if (!IP_HAS_OBJ_COLOR(PObj)) {
- PObj -> Color = LOAD_COLOR;
- IP_SET_OBJ_COLOR(PObj);
- }
-
- if (GetToken(f, StringToken) == TOKEN_OTHER &&
- strcmp(StringToken, "NONE") != 0)
- strcpy(PObj -> Name, StringToken);
-
- IritPrsrGetAllObjects(f, PObj);
-
- GetCloseParenToken(f);
- if (PObjParent) {
- /* This object contains other object - delete it since */
- /* we are flattening the structure here. */
- free((VoidPtr) PObjParent);
- PObjParent = NULL;
- }
- break;
- default:
- if (WasObjectToken) {
- ParserError(IP_ERR_OBJECT_EXPECTED, StringToken);
- }
- UnGetToken(StringToken);
- UnGetToken("[");
- IritPrsrGetAuxObject(f, PObjParent);
- Quit = TRUE;
- break;
- }
- }
- }
-
- /*****************************************************************************
- * Routine to get close paren token from f. *
- *****************************************************************************/
- static void GetCloseParenToken(FILE *f)
- {
- char StringToken[LINE_LEN_LONG];
-
- if (GetToken(f, StringToken) != TOKEN_CLOSE_PAREN)
- ParserError(IP_ERR_CLOSE_PAREN_EXPECTED, StringToken);
- }
-
- /*****************************************************************************
- * Routine to get close paren token from f. *
- *****************************************************************************/
- static void SkipToCloseParenToken(FILE *f)
- {
- char StringToken[LINE_LEN_LONG];
-
- while (!feof(f) && GetToken(f, StringToken) != TOKEN_CLOSE_PAREN);
- }
-
- /*****************************************************************************
- * Routine to get one numeric token into r. *
- *****************************************************************************/
- static void GetNumericToken(FILE *f, RealType *r)
- {
- char StringToken[LINE_LEN_LONG];
-
- GetToken(f, StringToken);
- # ifdef DOUBLE
- if (sscanf(StringToken, "%lf", r) != 1)
- # else
- if (sscanf(StringToken, "%f", r) != 1)
- # endif /* DOUBLE */
- ParserError(IP_ERR_NUMBER_EXPECTED, StringToken);
- }
-
- /*****************************************************************************
- * Routine to read the content of a single object. Return TRUE if data is *
- * useful for this parser, FALSE if data should be purged. *
- *****************************************************************************/
- static void IritPrsrGetAuxObject(FILE *f, IPObjectStruct *PObj)
- {
- int i, j, ErrLine;
- TokenType Token;
- char *ErrStr, StringToken[LINE_LEN_LONG];
- IPPolygonStruct *PPolygon;
- CagdCrvStruct *PCurve;
- CagdSrfStruct *PSurface;
-
- PObj -> Type = IP_OBJ_UNDEF;
-
- while (GetToken(f, StringToken) == TOKEN_OPEN_PAREN) {
- switch (Token = GetToken(f, StringToken)) {
- case TOKEN_POLYGON:
- case TOKEN_POLYLINE:
- case TOKEN_POINTLIST:
- PPolygon = IritPrsrNewPolygonStruct();
- switch (Token) {
- case TOKEN_POLYGON:
- PPolygon -> Type = IP_POLYGON;
- break;
- case TOKEN_POLYLINE:
- PPolygon -> Type = IP_POLYLINE;
- break;
- case TOKEN_POINTLIST:
- PPolygon -> Type = IP_POINTLIST;
- break;
- }
-
- /* The following handle the optional attributes in struct. */
- if (GetToken(f, StringToken) == TOKEN_OPEN_PAREN)
- GetPolygonAttributes(PPolygon, f);
- else
- UnGetToken(StringToken);
-
- /* The following handles reading the vertices. */
- GetPointData(f, PPolygon);
-
- if (PPolygon -> Type == IP_POLYGON &&
- !IP_HAS_POLY_PLANE(PPolygon))
- IPUpdatePolyPlane(PPolygon);
-
- PPolygon -> Pnext = PObj -> U.PPolygon;
- PObj -> U.PPolygon = PPolygon;
- PObj -> Type = IP_OBJ_POLY;
- break;
- case TOKEN_MATRIX:
- if (strcmp(PObj -> Name, "VIEW_MAT") == 0) {
- IritPrsrWasViewMat = TRUE;
- for (i = 0; i < 4; i++)
- for (j = 0; j < 4; j++)
- GetNumericToken(f, &IritPrsrViewMat[i][j]);
- GetCloseParenToken(f);
- }
- else if (strcmp(PObj -> Name, "PRSP_MAT") == 0) {
- IritPrsrWasPrspMat = TRUE;
- for (i = 0; i < 4; i++)
- for (j = 0; j < 4; j++)
- GetNumericToken(f, &IritPrsrPrspMat[i][j]);
- GetCloseParenToken(f);
- }
- else
- SkipToCloseParenToken(f);
- break;
- case TOKEN_SURFACE:
- ErrLine = GlblLineCount;
- PSurface = CagdSrfReadFromFile2(f, &ErrStr, &ErrLine);
- GlblLineCount = ErrLine;
-
- if (ErrStr != NULL) {
- ParserError(IP_ERR_CAGD_LIB_ERR, ErrStr);
- break;
- }
-
- if (PSurface != NULL) {
- PSurface -> Pnext = PObj -> U.PSrfs;
- PObj -> U.PSrfs = PSurface;
- }
- PObj -> Type = IP_OBJ_SURFACE;
- break;
- case TOKEN_CURVE:
- ErrLine = GlblLineCount;
- PCurve = CagdCrvReadFromFile2(f, &ErrStr, &ErrLine);
- GlblLineCount = ErrLine;
-
- if (ErrStr != NULL) {
- ParserError(IP_ERR_CAGD_LIB_ERR, ErrStr);
- break;
- }
-
- if (PCurve != NULL) {
- PCurve -> Pnext = PObj -> U.PCrvs;
- PObj -> U.PCrvs = PCurve;
- }
- PObj -> Type = IP_OBJ_CURVE;
- break;
- case TOKEN_NUMBER:
- case TOKEN_STRING:
- case TOKEN_VECTOR:
- case TOKEN_CTLPT:
- SkipToCloseParenToken(f);
- break;
- default:
- ParserError(IP_ERR_UNDEF_EXPR_HEADER, StringToken);
- break;
- } /* Of switch. */
- } /* Of while. */
-
- switch (Token) {
- case TOKEN_POLYGON:
- case TOKEN_POLYLINE:
- case TOKEN_POINTLIST:
- PObj -> Pnext = AllPolys;
- AllPolys = PObj;
- break;
- case TOKEN_SURFACE:
- PObj -> Pnext = AllSrfs;
- AllSrfs = PObj;
- break;
- case TOKEN_CURVE:
- PObj -> Pnext = AllCrvs;
- AllCrvs = PObj;
- break;
- default:
- free((VoidPtr) PObj);
- break;
- }
-
- UnGetToken(StringToken);
- }
-
- /*****************************************************************************
- * Routine to unget one token (on stack of UNGET_STACK_SIZE levels!) *
- *****************************************************************************/
- static void UnGetToken(char *StringToken)
- {
- if (GlblToken >= UNGET_STACK_SIZE)
- ParserError(IP_ERR_STACK_OVERFLOW, "");
-
- strcpy(GlblStringToken[GlblToken], StringToken);
- GlblToken++; /* GlblToken exists - Something in it (no overflow check). */
- }
-
- /*****************************************************************************
- * Routine to get the next token out of the input file f. *
- * Returns the next token found, as StringToken. *
- * Note: StringToken must be allocated before calling this routine! *
- *****************************************************************************/
- static void GetStringToken(FILE *f, char *StringToken)
- {
- int len;
- char c, *LocalStringToken;
-
- if (GlblToken) { /* get first the unget token */
- GlblToken--;
- strcpy(StringToken, GlblStringToken[GlblToken]);
- return;
- }
- /* skip white spaces: */
- while ((!feof(f))
- && (((c = getc(f)) == ' ') || (c == '\t') || (c == '\n')))
- if (c == '\n') GlblLineCount++; /* Count the lines. */
-
- LocalStringToken = StringToken;
- if (c == '[') /* Its a token by itself so return it. */
- *LocalStringToken++ = c; /* Copy the token into string. */
- else {
- if (!feof(f))
- do *LocalStringToken++ = c; /* Copy the token into string. */
- while ((!feof(f)) &&
- ((c = getc(f)) != ' ') && (c != '\t') && (c != '\n'));
- if (c == '\n') ungetc(c, f); /* Save it to be counted next time. */
- }
- *LocalStringToken = 0; /* Put eos. */
-
- /* The following handles the spacial case were we have XXXX] - we must */
- /* split it into two token XXXX and ], UnGetToken(']') and return XXXX: */
- if ((StringToken[len = strlen(StringToken)-1] == ']') && (len > 0)) {
- /* Return CloseParan */
- UnGetToken(&StringToken[len]); /* Save next token. */
- StringToken[len] = 0; /* Set end of string on "]". */
- }
- }
-
- /*****************************************************************************
- * Routine to get the next token out of the input file f as token number. *
- * Note: StringToken must be allocated before calling this routine! *
- *****************************************************************************/
- static TokenType GetToken(FILE *f, char *StringToken)
- {
- static int IntTokens[] = {
- TOKEN_OPEN_PAREN,
- TOKEN_CLOSE_PAREN,
- TOKEN_VERTEX,
- TOKEN_POLYGON,
- TOKEN_POLYLINE,
- TOKEN_POINTLIST,
- TOKEN_OBJECT,
- TOKEN_COLOR,
- TOKEN_RGB,
- TOKEN_INTERNAL,
- TOKEN_NORMAL,
- TOKEN_PLANE,
- TOKEN_CURVE,
- TOKEN_SURFACE,
- TOKEN_E2,
- TOKEN_P2,
- TOKEN_E3,
- TOKEN_P3,
- TOKEN_NUMBER,
- TOKEN_STRING,
- TOKEN_VECTOR,
- TOKEN_MATRIX,
- TOKEN_CTLPT,
- 0
- };
- static char *StrTokens[] = {
- "[",
- "]",
- "VERTEX",
- "POLYGON",
- "POLYLINE",
- "POINTLIST",
- "OBJECT",
- "COLOR",
- "RGB",
- "INTERNAL",
- "NORMAL",
- "PLANE",
- "CURVE",
- "SURFACE",
- "E2",
- "P2",
- "E3",
- "P3",
- "NUMBER",
- "STRING",
- "VECTOR",
- "MATRIX",
- "CTLPT",
- NULL
- };
- int i;
-
- GetStringToken(f, StringToken);
-
- if (feof(f)) return TOKEN_EOF;
-
- for (i = 0; StrTokens[i] != NULL; i++)
- if (strcmp(StringToken, StrTokens[i]) == 0) return IntTokens[i];
-
- return TOKEN_OTHER; /* Must be number or name. */
- }
-
- /*****************************************************************************
- * Routine to read from input file f the following [ATTR ...] [ATTR ...]. *
- * Note the '[' was allready read. *
- *****************************************************************************/
- static void GetVertexAttributes(IPVertexStruct *PVertex, FILE *f)
- {
- int i;
- RealType Len;
- char StringToken[LINE_LEN_LONG];
-
- do {
- switch (GetToken(f, StringToken)) {
- case TOKEN_INTERNAL:
- GetCloseParenToken(f);
- IP_SET_VRTX_INTERNAL(PVertex);
- break;
- case TOKEN_NORMAL:
- /* The following handles reading 3 coord. of vertex normal. */
- for (i = 0; i < 3; i++)
- GetNumericToken(f, &PVertex -> Normal[i]);
-
- /* Make sure it is normalized. */
- Len = PT_LENGTH(PVertex -> Normal);
- for (i = 0; i < 3; i++) PVertex -> Normal[i] /= Len;
-
- GetCloseParenToken(f);
- IP_SET_VRTX_NORMAL(PVertex);
- break;
- default: /* Ignore this option! */
- SkipToCloseParenToken(f);
- break;
- }
- }
- while (GetToken(f, StringToken) == TOKEN_OPEN_PAREN);
-
- UnGetToken(StringToken);
- }
-
- /*****************************************************************************
- * Routine to read from input file f the following [ATTR ...] [ATTR ...]. *
- * Note the '[' was allready read. *
- *****************************************************************************/
- static void GetPolygonAttributes(IPPolygonStruct *PPolygon, FILE *f)
- {
- int i;
- RealType Len;
- char StringToken[LINE_LEN_LONG];
-
- do {
- switch (GetToken(f, StringToken)) {
- case TOKEN_PLANE:
- /* The following handles reading of 4 coord. of plane eqn.. */
- for (i = 0; i < 4; i++)
- GetNumericToken(f, &PPolygon -> Plane[i]);
-
- /* Make sure it is normalized. */
- Len = PT_LENGTH(PPolygon -> Plane);
- for (i = 0; i < 4; i++) PPolygon -> Plane[i] /= Len;
-
- GetCloseParenToken(f);
- IP_SET_POLY_PLANE(PPolygon);
- break;
- default:
- SkipToCloseParenToken(f);
- break;
- }
- }
- while (GetToken(f, StringToken) == TOKEN_OPEN_PAREN);
-
- UnGetToken(StringToken);
- }
-
- /*****************************************************************************
- * Routine to read from input file f the following [ATTR ...] [ATTR ...]. *
- * Note the '[' was allready read. *
- *****************************************************************************/
- static void GetObjectAttributes(IPObjectStruct *PObject, FILE *f)
- {
- int i, j;
- char StringToken[LINE_LEN_LONG];
-
- do {
- switch (GetToken(f, StringToken)) {
- case TOKEN_RGB:
- /* The following handles reading of 3 coord. of rgb. */
- for (i = 0; i < 3; i++) {
- GetToken(f, StringToken);
- if (sscanf(StringToken, "%d", &j) != 1)
- ParserError(IP_ERR_NUMBER_EXPECTED, StringToken);
- PObject -> RGB[i] = (unsigned char) j;
- }
- GetCloseParenToken(f);
- IP_SET_OBJ_RGB(PObject);
- break;
- case TOKEN_COLOR:
- GetToken(f, StringToken);
- if (sscanf(StringToken, "%d", &i) != 1)
- ParserError(IP_ERR_NUMBER_EXPECTED, StringToken);
- GetCloseParenToken(f);
- PObject -> Color = i;
- IP_SET_OBJ_COLOR(PObject);
- break;
- default:
- if ((i = PObject -> Attrs.NumStrAttribs) < MAX_NUM_ATTRS)
- {
- PObject -> Attrs.StrAttrName[i] = strdup(StringToken);
- if (GetToken(f, StringToken) == TOKEN_CLOSE_PAREN) {
- UnGetToken(StringToken);
- PObject -> Attrs.StrAttrData[i] = "";
- }
- else {
- PObject -> Attrs.StrAttrData[i] = strdup(StringToken);
- }
- PObject -> Attrs.NumStrAttribs++;
- }
- SkipToCloseParenToken(f);
- break;
- }
- }
- while (GetToken(f, StringToken) == TOKEN_OPEN_PAREN);
-
- if (!IP_HAS_OBJ_COLOR(PObject)) {
- PObject -> Color = LOAD_COLOR;
- IP_SET_OBJ_COLOR(PObject);
- }
-
- UnGetToken(StringToken);
- }
-
- /*****************************************************************************
- * Routine to read poly* vertex information. *
- *****************************************************************************/
- static void GetPointData(FILE *f, IPPolygonStruct *PPolygon)
- {
- int i, j, Length;
- char StringToken[LINE_LEN_LONG];
- IPVertexStruct *V,
- *VTail = NULL;
-
- if (GetToken(f, StringToken) != TOKEN_OTHER ||
- sscanf(StringToken, "%d", &Length) != 1)
- ParserError(IP_ERR_NUMBER_EXPECTED, StringToken);
-
- for (i = 0; i < Length; i++) {
- if (GetToken(f, StringToken) != TOKEN_OPEN_PAREN)
- ParserError(IP_ERR_OPEN_PAREN_EXPECTED, StringToken);
-
- V = IritPrsrNewVertexStruct();
-
- /* The following handle the optional attributes in struct. */
- if (GetToken(f, StringToken) == TOKEN_OPEN_PAREN)
- GetVertexAttributes(V, f);
- else
- UnGetToken(StringToken);
-
- for (j = 0; j < 3; j++) /* Read coordinates. */
- GetNumericToken(f, &V -> Coord[j]);
-
- GetCloseParenToken(f);
-
- if (!IP_HAS_VRTX_NORMAL(V))
- PT_COPY(V -> Normal, PPolygon -> Plane);
-
- if (VTail == NULL)
- PPolygon -> PVertex = VTail = V;
- else {
- VTail -> Pnext = V;
- VTail = V;
- }
- }
-
- if (IritPrsrPolyListCirc && PPolygon -> Type == IP_POLYGON)
- VTail -> Pnext = PPolygon -> PVertex;
-
- GetCloseParenToken(f);
- }
-
- /*****************************************************************************
- * Routine to update the Plane equation of the given polygon by the order *
- * of the first 3 vertices of that polygon. *
- *****************************************************************************/
- static void IPUpdatePolyPlane(IPPolygonStruct *PPoly)
- {
- int i;
- RealType Len, V1[3], V2[3];
- IPVertexStruct *V = PPoly -> PVertex;
-
- if (V == NULL || V -> Pnext == NULL || V -> Pnext -> Pnext == NULL)
- ParserError(IP_ERR_DEGEN_POLYGON, "");
-
- PT_SUB(V1, V -> Coord, V -> Pnext -> Coord);
- V = V -> Pnext;
- PT_SUB(V2, V -> Coord, V -> Pnext -> Coord);
-
- PPoly -> Plane[0] = V1[1] * V2[2] - V2[1] * V1[2];
- PPoly -> Plane[1] = V1[2] * V2[0] - V2[2] * V1[0];
- PPoly -> Plane[2] = V1[0] * V2[1] - V2[0] * V1[1];
- PPoly -> Plane[3] = (-DOT_PROD(PPoly -> Plane, PPoly -> PVertex -> Coord));
-
- /* Normalize the plane such that the normal has length of 1: */
- Len = PT_LENGTH(PPoly -> Plane);
- for (i = 0; i < 4; i++) PPoly -> Plane[i] /= Len;
- }
-
- /*****************************************************************************
- * Routine to set a string attribute. A string attribute consists of an *
- * attribute name (string) and data (also string). *
- * If Data = "", the attribute with name Name is been freed. *
- * If attribute by the given name already exists, it is replaced. *
- *****************************************************************************/
- void IritPrsrSetStrAttrib(IPObjectStruct *PObj, char *Name, char *Data)
- {
- int i;
- IPAttributeStruct *Attr = &PObj -> Attrs;
-
- for (i = 0; i < Attr -> NumStrAttribs; i++) {
- if (strcmp(Name, Attr -> StrAttrName[i]) == 0) {
- /* If Data is an empty string, remove this entry. */
- if (strlen(Data) == 0) {
- free((VoidPtr) Attr -> StrAttrName[i]);
- free((VoidPtr) Attr -> StrAttrData[i]);
- for ( ; i < (int) Attr -> NumStrAttribs - 2; i++) {
- Attr -> StrAttrName[i] = Attr -> StrAttrName[i + 1];
- Attr -> StrAttrData[i] = Attr -> StrAttrData[i + 1];
- }
- Attr -> NumStrAttribs--;
- }
- else {
- free((VoidPtr) Attr -> StrAttrData[i]);
- Attr -> StrAttrData[i] = strdup(Data);
- }
-
- return;
- }
- }
-
- /* O.k. it is a new attribute. */
- if (Attr -> NumStrAttribs >= MAX_NUM_ATTRS) {
- return;
- }
- Attr -> StrAttrName[Attr -> NumStrAttribs] = strdup(Name);
- Attr -> StrAttrData[Attr -> NumStrAttribs++] = strdup(Data);
- }
-
- /*****************************************************************************
- * Routine to get a string attribute. A string attribute consists of an *
- * attribute name (string) and data (also string). *
- * Returns a pointer to data if string name is found, NULL otherwise. *
- *****************************************************************************/
- char *IritPrsrGetStrAttrib(IPObjectStruct *PObj, char *Name)
- {
- int i;
- IPAttributeStruct *Attr = &PObj -> Attrs;
-
- /* If Name is an empty string - print all attributes. */
- if (Name == NULL || strlen(Name) == 0) return NULL;
-
- for (i = 0; i < Attr -> NumStrAttribs; i++)
- if (strcmp(Name, Attr -> StrAttrName[i]) == 0)
- return Attr -> StrAttrData[i];
-
- return NULL;
- }
-
- /*****************************************************************************
- * Routine to allocate a new VertexStruct. *
- *****************************************************************************/
- IPVertexStruct *IritPrsrNewVertexStruct(void)
- {
- IPVertexStruct *V = (IPVertexStruct *) malloc(sizeof(IPVertexStruct));
- V -> Pnext = NULL;
- V -> VAux = NULL;
- V -> VTags = 0;
- return V;
- }
-
- /*****************************************************************************
- * Routine to allocate a new PolygonStruct. *
- *****************************************************************************/
- IPPolygonStruct *IritPrsrNewPolygonStruct(void)
- {
- IPPolygonStruct *P = (IPPolygonStruct *) malloc(sizeof(IPPolygonStruct));
- P -> Pnext = NULL;
- P -> PVertex = NULL;
- P -> PAux = NULL;
- P -> PTags = 0;
- return P;
- }
-
- /*****************************************************************************
- * Routine to allocate a new ObjectStruct. *
- *****************************************************************************/
- IPObjectStruct *IritPrsrNewObjectStruct(void)
- {
- IPObjectStruct *O = (IPObjectStruct *) malloc(sizeof(IPObjectStruct));
- O -> Pnext = NULL;
- O -> U.PPolygon = NULL;
- O -> OAux = NULL;
- O -> Attrs.NumStrAttribs = 0;
- O -> OTags = 0;
- O -> Name[0] = 0;
- O -> Color = LOAD_COLOR;
- O -> FFPolylines = O -> FFPolygons = NULL;
- return O;
- }
-
- /*****************************************************************************
- * Routine to print pasring error according to ErrNum and set GlblParserError.*
- *****************************************************************************/
- static void ParserError(IritPrsrErrType ErrNum, char *Msg)
- {
- IPGlblLineCount = GlblLineCount;
- IPGlblParserError = ErrNum;
- strcpy(IPGlblTokenError, Msg); /* Keep the message in safe place... */
-
- longjmp(LclLongJumpBuffer, 1); /* Jump to... */
- }
-
- /*****************************************************************************
- * Returns TRUE if error happened, FALSE otherwise. *
- * If error, then ErrorMsg is updated to point on static str describing it. *
- *****************************************************************************/
- int IritPrsrParseError(char **ErrorMsg)
- {
- IritPrsrErrType Temp;
- char TempCopy[LINE_LEN_LONG];
-
- if ((Temp = IPGlblParserError) == IP_NO_ERR) return FALSE;
-
- strcpy(TempCopy, IPGlblTokenError);
- IPGlblParserError = IP_NO_ERR;
-
- switch (Temp) {
- case IP_ERR_NUMBER_EXPECTED:
- sprintf(IPGlblTokenError, "Line %d: Numeric data expected - found %s",
- IPGlblLineCount, TempCopy);
- break;
- case IP_ERR_OPEN_PAREN_EXPECTED:
- sprintf(IPGlblTokenError, "Line %d: '[' expected - found '%s'",
- IPGlblLineCount, TempCopy);
- break;
- case IP_ERR_CLOSE_PAREN_EXPECTED:
- sprintf(IPGlblTokenError, "Line %d: ']' expected - found '%s'",
- IPGlblLineCount, TempCopy);
- break;
- case IP_ERR_LIST_COMP_UNDEF:
- sprintf(IPGlblTokenError, "Line %d: Undefined list element - \"%s\"",
- IPGlblLineCount, TempCopy);
- break;
- case IP_ERR_UNDEF_EXPR_HEADER:
- sprintf(IPGlblTokenError, "Line %d: Undefined TOKEN - \"%s\"",
- IPGlblLineCount, TempCopy);
- break;
- case IP_ERR_PT_TYPE_EXPECTED:
- sprintf(IPGlblTokenError, "Line %d: Point type expected",
- IPGlblLineCount);
- break;
- case IP_ERR_OBJECT_EMPTY:
- sprintf(IPGlblTokenError, "Line %d: Empty object found",
- IPGlblLineCount);
- break;
- case IP_ERR_MIXED_TYPES:
- sprintf(IPGlblTokenError,
- "Line %d: Mixed data types in same object",
- IPGlblLineCount);
- break;
- case IP_STR_NOT_IN_QUOTES:
- sprintf(IPGlblTokenError,
- "Line %d: String not in quotes (%s)",
- IPGlblLineCount, TempCopy);
- break;
- case IP_ERR_OBJECT_EXPECTED:
- sprintf(IPGlblTokenError,
- "Line %d: 'OBJECT' expected, found '%s'",
- IPGlblLineCount, TempCopy);
- break;
- case IP_ERR_CAGD_LIB_ERR:
- sprintf(IPGlblTokenError, "Line %d: %s",
- IPGlblLineCount, TempCopy);
- break;
- case IP_ERR_STACK_OVERFLOW:
- sprintf(IPGlblTokenError, "Line %d: Parser Stack overflow",
- IPGlblLineCount);
- break;
- default:
- sprintf(IPGlblTokenError,
- "Line %d: Data file parser - undefined error",
- IPGlblLineCount);
- break;
- }
-
- *ErrorMsg = IPGlblTokenError;
-
- return TRUE;
- }
-