/*****************************************************************************
* Generic parser for the "Irit" solid modeller.				     *
******************************************************************************
* (C) Gershon Elber, Technion, Israel Institute of Technology                *
******************************************************************************
* Written by:  Gershon Elber				Ver 0.2, Sep. 1991   *
*****************************************************************************/

#ifndef	IRIT_PRSR_H
#define	IRIT_PRSR_H

#include <setjmp.h>

#include "irit_sm.h"
#include "cagd_lib.h"
#include "trim_lib.h"
#include "triv_lib.h"
#include "trng_lib.h"
#include "mdl_lib.h"
#include "mvar_lib.h"
#include "misc_lib.h"

/* Dont change the order of these objects (or there values as overloaded     */
/* tables (see overload.c) are hardwired to it. If you add objects update    */
/* that module properly.						     */
typedef enum {
    IP_OBJ_UNDEF = 0,

    IP_OBJ_POLY,                     /* These are the objects in overload.c. */
    IP_OBJ_NUMERIC,
    IP_OBJ_POINT,
    IP_OBJ_VECTOR,
    IP_OBJ_PLANE,
    IP_OBJ_MATRIX,
    IP_OBJ_CURVE,
    IP_OBJ_SURFACE,
    IP_OBJ_STRING,
    IP_OBJ_LIST_OBJ,
    IP_OBJ_CTLPT,
    IP_OBJ_TRIMSRF,
    IP_OBJ_TRIVAR,
    IP_OBJ_INSTANCE,
    IP_OBJ_TRISRF,
    IP_OBJ_MODEL,
    IP_OBJ_MULTIVAR,

    ANY_OBJ = 100		 /* Match any object type, in type checking. */
} IPObjStructType;

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_FILE_EMPTY,
    IP_ERR_MIXED_TYPES,
    IP_ERR_STR_NOT_IN_QUOTES,
    IP_ERR_STR_TOO_LONG,
    IP_ERR_OBJECT_EXPECTED,
    IP_ERR_CAGD_LIB_ERR,
    IP_ERR_TRIM_LIB_ERR,
    IP_ERR_TRIV_LIB_ERR,
    IP_ERR_TRNG_LIB_ERR,
    IP_ERR_MDL_LIB_ERR,
    IP_ERR_MVAR_LIB_ERR,
    IP_ERR_STACK_OVERFLOW,
    IP_ERR_DEGEN_POLYGON,
    IP_ERR_DEGEN_NORMAL,
    IP_ERR_SOCKET_BROKEN,
    IP_ERR_SOCKET_TIME_OUT,
    IP_ERR_BIN_IN_TEXT,
    IP_ERR_BIN_UNDEF_OBJ,
    IP_ERR_BIN_WRONG_SIZE,

    IP_WRN_OBJ_NAME_TRUNC = 100
} IPErrType;

typedef enum {
    IP_FILE_TEXT,
    IP_FILE_BINARY,
    IP_FILE_COMPRESSED
} IPFileType;

#define IRIT_DATA_HEADER(File, Name) \
	fprintf(File, "Irit %s, %s,\nCreator: %s,\nDate: %s.\n\n", \
		IRIT_VERSION, IRIT_COPYRIGHT, Name, IritRealTimeDate());

/*****************************************************************************
* An instance object - a duplicate at a different location.                  *
*****************************************************************************/
typedef struct IPInstanceStruct {
    struct IPInstanceStruct *Pnext;		        /* To next in chain. */
    struct IPAttributeStruct *Attr;
    struct IPObjectStruct *PRef;/* Reference to object this is its instance. */
    char *Name;		             /* Name of object this is its instance. */
    MatrixType Mat;	  /* Transformation from Object Name to this object. */
} IPInstanceStruct;

/*****************************************************************************
* Global data structures:						     *
* Objects in the system might be (real) scalars, (R3) vectors, matrices      *
* (4 by 4 - transformation matrix), strings of chars, lists of objects, or   *
* geometric objects. All but the last are simple and all their data is saved *
* in the object space itself. The last (geometric) object points on a	     *
* curve or a surface or a polygonal list of the form:			     *
*									     *
* Polygon -> Polygon -> Polygon -> Polygon -> .... -> NULL		     *
*    |		|	   |	      |					     *
*    V          V          V          V					     *
*  VList      VList      VList      VList	(VList = Vertex List)	     *
*									     *
* Each VList is usually a CIRCULAR vertex list. Each VList element           *
* (IPVertexStruct) implicitly defines an edge from this vertex, to the next. *
* As each edge is used by exactly two polygons, a pointer to the other       *
* polygon using this edge exists in the IPVertexStruct as PAdj. Each polygon *
* has also its Plane definition for fast processing, with its normal         *
* pointing INTO the object.						     *
*   Few other tags & flags are included in the data structures for different *
* modules.								     *
*   Note, vertices are not shared by few VLists/Polygons although it may     *
* decrease memory usage (suprisingly, not much). The main reason to that is  *
* the basic assumption of this solid modeller, which is simplicity...	     *
*****************************************************************************/

/*****************************************************************************
* Vertex Type - holds single 3D point, including some attributes on it as    *
* Tags. The 3D coordinates are saved in Pt. Pointer to next in chain	     *
* is Pnext, and the pointer to the adjacent polygon (to the edge defined by  *
* this Vertex and Vertex -> Pnext) is PAdj.				     *
*****************************************************************************/

/* Internal edge, or edge generated by the polygon decomposition stage when  */
/* only convex polygons are allowed. This edge was not in the input	     */
/* non-convex polygon, and therefore one may not want to see/display it.     */
/* Note bits 4-7 (high nibble of Tags) are reserved for the different	     */
/* modules to perform their local tasks and so should not be used here.	     */
#define IP_VRTX_INTERNAL_TAG	0x01    /* Internal Tag - Edge is internal.  */
#define IP_VRTX_NORMAL_TAG	0x02     /* Normal Tag - Vertex has normal.  */

#define IP_IS_INTERNAL_VRTX(Vrtx)	(Vrtx -> Tags & IP_VRTX_INTERNAL_TAG)
#define IP_SET_INTERNAL_VRTX(Vrtx)	(Vrtx -> Tags |= IP_VRTX_INTERNAL_TAG)
#define IP_RST_INTERNAL_VRTX(Vrtx)	(Vrtx -> Tags &= ~IP_VRTX_INTERNAL_TAG)
#define IP_HAS_NORMAL_VRTX(Vrtx)	(Vrtx -> Tags & IP_VRTX_NORMAL_TAG)
#define IP_SET_NORMAL_VRTX(Vrtx)	(Vrtx -> Tags |= IP_VRTX_NORMAL_TAG)
#define IP_RST_NORMAL_VRTX(Vrtx)	(Vrtx -> Tags &= ~IP_VRTX_NORMAL_TAG)

typedef struct IPVertexStruct {
    struct IPVertexStruct *Pnext;		        /* To next in chain. */
    struct IPAttributeStruct *Attr;
    struct IPPolygonStruct *PAdj;		     /* To adjacent polygon. */
    ByteType Tags;					 /* Some attributes. */
    PointType Coord;			       /* Holds X, Y, Z coordinates. */
    NormalType Normal;		       /* Hold Vertex normal into the solid. */
} IPVertexStruct;

/*****************************************************************************
* Polygon Type - holds single polygon - Its Plane definition, and a pointer  *
* to its vertices contour list V. As for IPVertexStruct, different attributes*
* can be saved in Tags. PAux can be used locally by different modules, for   *
* local usage only, and nothing sould be assumed on entry.		     *
*****************************************************************************/

/* Note bits 4-7 (high nibble of Tags) are reserved for the different	     */
/* modules to perform their local tasks and so should not be used here.	     */
#define IP_POLY_CONVEX_TAG	0x01	   /* Convex Tag - Set if is convex. */
#define IP_POLY_BBOX_TAG	0x02  /* BBox Tag - Set if BBox is computed. */
#define IP_POLY_PLANE_TAG	0x04    /* Plane Tag - set of has plane def. */
#define IP_POLY_STRIP_TAG	0x08     /* A strip of polygons starts/ends. */

#define	IP_IS_CONVEX_POLY(Poly)		((Poly) -> Tags & IP_POLY_CONVEX_TAG)
#define	IP_SET_CONVEX_POLY(Poly)	((Poly) -> Tags |= IP_POLY_CONVEX_TAG)
#define	IP_RST_CONVEX_POLY(Poly)	((Poly) -> Tags &= ~IP_POLY_CONVEX_TAG)
#define	IP_HAS_BBOX_POLY(Poly)		((Poly) -> Tags & IP_POLY_BBOX_TAG)
#define	IP_SET_BBOX_POLY(Poly)		((Poly) -> Tags |= IP_POLY_BBOX_TAG)
#define	IP_RST_BBOX_POLY(Poly)		((Poly) -> Tags &= ~IP_POLY_BBOX_TAG)
#define IP_HAS_PLANE_POLY(Poly)		((Poly) -> Tags & IP_POLY_PLANE_TAG)
#define IP_SET_PLANE_POLY(Poly)		((Poly) -> Tags |= IP_POLY_PLANE_TAG)
#define IP_RST_PLANE_POLY(Poly)		((Poly) -> Tags &= ~IP_POLY_PLANE_TAG)
#define IP_IS_STRIP_POLY(Poly)		((Poly) -> Tags & IP_POLY_STRIP_TAG)
#define IP_SET_STRIP_POLY(Poly)		((Poly) -> Tags |= IP_POLY_STRIP_TAG)
#define IP_RST_STRIP_POLY(Poly)		((Poly) -> Tags &= ~IP_POLY_STRIP_TAG)

typedef struct IPPolygonStruct {
    struct IPPolygonStruct *Pnext;		        /* To next in chain. */
    struct IPAttributeStruct *Attr;
    IPVertexStruct *PVertex;		    		/* To vertices list. */
    VoidPtr PAux;
    ByteType Tags;				         /* Some attributes. */
    int IAux, IAux2, IAux3;
    PlaneType Plane;			 /* Holds Plane as Ax + By + Cz + D. */
    BBoxType BBox;					/* BBox of polygons. */
} IPPolygonStruct;

typedef struct IPPolyVrtxIdxStruct {
    struct IPPolyVrtxIdxStruct *Pnext;                  /* To next in chain. */
    struct IPAttributeStruct *Attr;                  /* Object's attributes. */
    struct IPObjectStruct *PObj;    /* Pointer to original polygonal object. */
    IPVertexStruct **Vertices;       /* A linear vector of all the vertices. */
    int **Polygons;          /* A vector of -1 terminated lists of vertices. */
    int *_AuxVIndices;  /* Auxiliary memory to hold all indices in Polygons. */
    int MaxNumVrtcs;		           /* Max length of vector Vertices. */
    int MaxNumPlys;		           /* Max length of vector Polygons. */
} IPPolyVrtxIdxStruct;

/*****************************************************************************
* Object Type - main system structure, which holds all the objects defined   *
* in the system like Numeric, Geometric etc.				     *
*   Note that as the number of objects will be usually extermely low (100 is *
* high estimate!) we can waste some memory here...			     *
*****************************************************************************/

#define IP_IS_UNDEF_OBJ(Obj)	((Obj) -> ObjType == IP_OBJ_UNDEF)
#define IP_IS_POLY_OBJ(Obj)	((Obj) -> ObjType == IP_OBJ_POLY)
#define IP_IS_NUM_OBJ(Obj)	((Obj) -> ObjType == IP_OBJ_NUMERIC)
#define IP_IS_POINT_OBJ(Obj)	((Obj) -> ObjType == IP_OBJ_POINT)
#define IP_IS_VEC_OBJ(Obj)	((Obj) -> ObjType == IP_OBJ_VECTOR)
#define IP_IS_PLANE_OBJ(Obj)	((Obj) -> ObjType == IP_OBJ_PLANE)
#define IP_IS_CTLPT_OBJ(Obj)	((Obj) -> ObjType == IP_OBJ_CTLPT)
#define IP_IS_MAT_OBJ(Obj)	((Obj) -> ObjType == IP_OBJ_MATRIX)
#define IP_IS_STR_OBJ(Obj)	((Obj) -> ObjType == IP_OBJ_STRING)
#define IP_IS_OLST_OBJ(Obj)	((Obj) -> ObjType == IP_OBJ_LIST_OBJ)
#define IP_IS_CRV_OBJ(Obj)	((Obj) -> ObjType == IP_OBJ_CURVE)
#define IP_IS_SRF_OBJ(Obj)	((Obj) -> ObjType == IP_OBJ_SURFACE)
#define IP_IS_TRIMSRF_OBJ(Obj)	((Obj) -> ObjType == IP_OBJ_TRIMSRF)
#define IP_IS_TRIVAR_OBJ(Obj)	((Obj) -> ObjType == IP_OBJ_TRIVAR)
#define IP_IS_TRISRF_OBJ(Obj)	((Obj) -> ObjType == IP_OBJ_TRISRF)
#define IP_IS_INSTNC_OBJ(Obj)	((Obj) -> ObjType == IP_OBJ_INSTANCE)
#define IP_IS_MODEL_OBJ(Obj)	((Obj) -> ObjType == IP_OBJ_MODEL)
#define IP_IS_MVAR_OBJ(Obj)	((Obj) -> ObjType == IP_OBJ_MULTIVAR)

#define IP_IS_GEOM_OBJ(Obj)	(IP_IS_UNDEF_OBJ(Obj) || \
				 IP_IS_POLY_OBJ(Obj) || \
				 IP_IS_POINT_OBJ(Obj) || \
				 IP_IS_CTLPT_OBJ(Obj) || \
				 IP_IS_VEC_OBJ(Obj) || \
				 IP_IS_CRV_OBJ(Obj) || \
				 IP_IS_SRF_OBJ(Obj) || \
				 IP_IS_TRIMSRF_OBJ(Obj) || \
				 IP_IS_TRIVAR_OBJ(Obj) || \
				 IP_IS_TRISRF_OBJ(Obj) || \
				 IP_IS_MODEL_OBJ(Obj) || \
				 IP_IS_MVAR_OBJ(Obj) || \
				 IP_IS_INSTNC_OBJ(Obj))

#define IP_IS_FFGEOM_OBJ(Obj)	(IP_IS_CRV_OBJ(Obj) || \
				 IP_IS_SRF_OBJ(Obj) || \
				 IP_IS_TRIMSRF_OBJ(Obj) || \
				 IP_IS_TRIVAR_OBJ(Obj) || \
				 IP_IS_TRISRF_OBJ(Obj) || \
				 IP_IS_MODEL_OBJ(Obj) || \
				 IP_IS_MVAR_OBJ(Obj) || \
				 IP_IS_INSTNC_OBJ(Obj))

#define IP_IS_POLYGON_OBJ(Obj)	  (((Obj) -> Tags & 0x03) == 0)
#define IP_SET_POLYGON_OBJ(Obj)	  ((Obj) -> Tags = ((Obj) -> Tags & 0xfc))
#define IP_IS_POLYLINE_OBJ(Obj)	  (((Obj) -> Tags & 0x03) == 1)
#define IP_SET_POLYLINE_OBJ(Obj)  ((Obj) -> Tags = ((Obj) -> Tags & 0xfc) + 1)
#define IP_IS_POINTLIST_OBJ(Obj)  (((Obj) -> Tags & 0x03) == 2)
#define IP_SET_POINTLIST_OBJ(Obj) ((Obj) -> Tags = ((Obj) -> Tags & 0xfc) + 2)
#define IP_IS_POLYSTRIP_OBJ(Obj)  (((Obj) -> Tags & 0x03) == 3)
#define IP_SET_POLYSTRIP_OBJ(Obj) ((Obj) -> Tags = ((Obj) -> Tags & 0xfc) + 3)

#define IP_OBJ_BBOX_TAG		  0x04
#define	IP_HAS_BBOX_OBJ(Obj)	  ((Obj) -> Tags & IP_OBJ_BBOX_TAG)
#define	IP_SET_BBOX_OBJ(Obj)	  ((Obj) -> Tags |= IP_OBJ_BBOX_TAG)
#define	IP_RST_BBOX_OBJ(Obj)	  ((Obj) -> Tags &= ~IP_OBJ_BBOX_TAG)

/* Maximum size of object list to start with (reallocated dynamically). */
#define IP_MAX_OBJ_LIST	10

/* This handler forces the writing to all active clients (broadcasting). */
#define IP_CLNT_BROADCAST_ALL_HANDLES 	13030

typedef struct IPObjectStruct {
    struct IPObjectStruct *Pnext;                       /* To next in chain. */
    struct IPAttributeStruct *Attr;                  /* Object's attributes. */
    struct IPODObjectDpndncyStruct *Dpnds;   /* Dependencies and parameters. */
    unsigned int Count;                                  /* Reference Count. */
    unsigned int Tags;                                   /* Some attributes. */
    IPObjStructType ObjType;        /* Object Type: Numeric, Geometric, etc. */
    BBoxType BBox;					  /* BBox of object. */
    union {
        IPPolygonStruct *Pl;                           /* Polygon/line list. */
        CagdCrvStruct *Crvs;                          /* Free form curve(s). */
        CagdSrfStruct *Srfs;                        /* Free form surface(s). */
        TrimSrfStruct *TrimSrfs;            /* Free form trimmed surface(s). */
        TrivTVStruct *Trivars;                   /* Free form trivariate(s). */
        TrngTriangSrfStruct *TriSrfs;    /* Free form triangular surface(s). */
        IPInstanceStruct *Instance;             /* An instance of an object. */
        MdlModelStruct *Mdls;                                    /* A model. */
        MvarMVStruct *MultiVars;                  /* Multivariate functions. */
        RealType R;                                    /* Numeric real data. */
        PointType Pt;                            /* Numeric real point data. */
        VectorType Vec;                         /* Numeric real vector data. */
        PlaneType Plane;                         /* Numeric real plane data. */
        CagdCtlPtStruct CtlPt;                        /* Control point data. */
        MatrixType *Mat;            /* Numeric 4 by 4 transformation matrix. */
        struct {
            struct IPObjectStruct **PObjList;            /* List of objects. */
            int ListMaxLen;           /* Maximum number of elements in list. */
        } Lst;
        char *Str;                        /* General string for text object. */
        VoidPtr *VPtr;
    } U;
    char Name[OBJ_NAME_LEN];                              /* Name of object. */
} IPObjectStruct;

typedef void (*IPPrintFuncType)(char *);
typedef void (*IPProcessLeafObjType)(IPObjectStruct *PObj);
typedef void (*IPApplyObjFuncType)(IPObjectStruct *PObj, MatrixType Mat);
typedef char (*IPMemoryStreamIOFuncType)(char);

#define IRIT_TEXT_DATA_FILE	    "itd"
#define IRIT_BINARY_DATA_FILE	    "ibd"
#define IRIT_COMPRESSED_DATA_FILE   "icd"
#define IRIT_MATRIX_DATA_FILE	    "imd"

typedef enum {
    IP_IDAT_FILE,
    IP_VRML_FILE,
    IP_HPGL_FILE,
    IP_PS_FILE,
    IP_IGS_FILE,
    IP_NFF_FILE,
    IP_OFF_FILE,
    IP_PLG_FILE,
    IP_POV_FILE,
    IP_RAY_FILE,
    IP_SCN_FILE,
    IP_XFG_FILE
} IPStreamFormatType;

#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif

/* Different data file types support: IGES. */
IPObjectStruct *IPLoadIgesFile(char *IgesFileName,
			       int ClipTrimmedSrf,
			       int DumpAll,
			       int Messages);
int IPSaveIgesFile(IPObjectStruct *PObj,
		   MatrixType CrntViewMat,
		   char *IgesFileName,
		   int Messages);
void IPSaveIgesFileSetup(int SaveEucTrimCrvs);

/* Different data file types support: VRML. */
int IPOpenVrmlFile(char *FileName, int Messages, RealType Resolution);
int IPOpenStreamFromVrml(FILE *f, int Read, int IsBinary, int IsPipe);
void IPPutVrmlObject(int Handler, IPObjectStruct *PObj, int Indent);
void IPPutVrmlViewPoint(int Handler, MatrixType *Mat, int Indent);
int IPSetVrmlExternalMode(int On);

int IPOpenDataFile(char *FileName, int Read, int Messages);
int IPOpenStreamFromMemory(IPMemoryStreamIOFuncType MemoryStreamIO,
			   int Read,
			   int IsBinary);
int IPOpenStreamFromFile(FILE *f,
			 int Read,
			 int IsBinary,
			 int IsCompressed,
			 int IsPipe);
int IPOpenStreamFromFile2(FILE *f, 
			  int Read,
			  IPStreamFormatType Format,
			  int IsBinary,
			  int IsCompressed,
			  int IsPipe);
int IPOpenStreamFromSocket(int Soc, int IsBinary);
void IPCloseStream(int Handler, int Free);
IPObjectStruct *IPGetDataFiles(char **DataFileNames,
			       int NumOfDataFiles,
			       int Messages,
			       int MoreMessages);
IPObjectStruct *IPGetDataFromFilehandles(FILE **Files,
					 int NumOfFiles,
					 char **Extensions,
					 int Messages,
					 int MoreMessages);
IPObjectStruct *IPGetDataFromFilehandles2(FILE **Files,
					  int NumOfFiles,
					  IPStreamFormatType *Formats,
					  int *IsBinaryIndicators,
					  int Messages,
					  int MoreMessages);
IPObjectStruct *IPGetObjects(int Handler);
IPObjectStruct *IPResolveInstances(IPObjectStruct *PObjects);
IPStreamFormatType IPSenseFileType(char *FileName);
int IPSenseBinaryFile(char *FileName);
IPObjectStruct *IPProcessReadObject(IPObjectStruct *PObj);
IPObjectStruct *IPFlattenTree(IPObjectStruct *PObj);
IPObjectStruct *IPFlattenForrest(IPObjectStruct *PObjList);
void IPStdoutObject(IPObjectStruct *PObj, int IsBinary);
void IPStderrObject(IPObjectStruct *PObj);
void IPPutObjectToFile(FILE *f, IPObjectStruct *PObj, int IsBinary);
void IPPutObjectToFile2(FILE *f, IPObjectStruct *PObj, int Indent);
void IPPutObjectToHandler(int Handler, IPObjectStruct *PObj);
int IPParseError(int LineNum, char **ErrorMsg);
void IPInputUnGetC(int Handler, char c);
int IPSetPolyListCirc(int Circ);
int IPSetFlattenObjects(int Flatten);
int IPSetPropagateAttrs(int Propagate);
int IPFlattenInvisibleObjects(int FlattenInvisib);
int IPSetReadOneObject(int OneObject);
IPProcessLeafObjType IPSetProcessLeafFunc(IPProcessLeafObjType ProcessLeafFunc);
IPPrintFuncType IPSetPrintFunc(IPPrintFuncType PrintFunc);
int IPSetFilterDegen(int FilterDegeneracies);
char *IPSetFloatFormat(char *FloatFormat);
#ifdef IRIT_QUIET_STRINGS
#define IPFatalError(Msg)
#else
void IPFatalError(char *Msg);
#endif /* IRIT_QUIET_STRINGS */

/* Binary stream functions. */
IPObjectStruct *IPGetBinObject(int Handler);
void IPPutBinObject(int Handler, IPObjectStruct *PObj);

/* Will be set to VIEW_MAT and PERS_MAT respectively if found in parsed data.*/
extern GLOBAL_DATA MatrixType IPViewMat, IPPrspMat;
extern GLOBAL_DATA int IPWasViewMat, IPWasPrspMat;

/* Gets lists of all freeform curves/(trimmed/triangular) surfaces/          */
/* trivariates in the datafile, process them as needed.			     */
/*   May return a processed version to be put on returned list from          */
/* IPGetObjects (polygonal approximation of the free form data for           */
/* example), or NULL otherwise.						     */
/*   This function is responsible to free the freeform data given if not     */
/* needed any more.							     */
/*   Is function is a call back function that must be provided by the using  */
/* application.	A default function will just concat the data into one list.  */
typedef struct IPFreeFormStruct {
    IPObjectStruct *CrvObjs;
    IPObjectStruct *SrfObjs;
    IPObjectStruct *TrimSrfObjs;
    IPObjectStruct *TrivarObjs;
    IPObjectStruct *TriSrfObjs;
    IPObjectStruct *ModelObjs;
    IPObjectStruct *MultiVarObjs;
} IPFreeFormStruct;
IPObjectStruct *IPProcessFreeForm(IPFreeFormStruct *FreeForms);
IPObjectStruct *IPConcatFreeForm(IPFreeFormStruct *FreeForms);
IPObjectStruct *IPEvalFreeForms(IPObjectStruct *PObj);

/* Last previous and other element retrieval routines. */
int IPUpdatePolyPlane(IPPolygonStruct *PPoly);
int IPUpdatePolyPlane2(IPPolygonStruct *PPoly, VectorType Vin);
void IPUpdateVrtxNrml(IPPolygonStruct *PPoly, VectorType DefNrml);
IPObjectStruct *IPReverseListObj(IPObjectStruct *ListObj);
IPObjectStruct *IPReverseObjList(IPObjectStruct *PObj);
IPPolygonStruct *IPReversePlList(IPPolygonStruct *PPl);
void IPReverseVrtxList(IPPolygonStruct *Pl);
IPVertexStruct *IPReverseVrtxList2(IPVertexStruct *PVrtx);
IPObjectStruct *IPGetObjectByName(char *Name,
				  IPObjectStruct *PObjList,
				  int TopLevel);
void IPSetSubObjectName(IPObjectStruct *PListObj, int Index, char *Name);

IPObjectStruct *IPGetLastObj(IPObjectStruct *OList);
IPObjectStruct *IPGetPrevObj(IPObjectStruct *OList, IPObjectStruct *O);
IPObjectStruct *IPAppendObjLists(IPObjectStruct *OList1,
				 IPObjectStruct *OList2);
IPObjectStruct *IPAppendListObjects(IPObjectStruct *ListObj1,
				    IPObjectStruct *ListObj2);
IPObjectStruct *IPObjLnkListToListObject(IPObjectStruct *ObjLnkList);
IPPolygonStruct *IPGetLastPoly(IPPolygonStruct *PList);
IPPolygonStruct *IPGetPrevPoly(IPPolygonStruct *PList,
			       IPPolygonStruct *P);
IPPolygonStruct *IPAppendPolyLists(IPPolygonStruct *PList1,
				   IPPolygonStruct *PList2);
IPVertexStruct *IPGetLastVrtx(IPVertexStruct *VList);
IPVertexStruct *IPGetPrevVrtx(IPVertexStruct *VList, IPVertexStruct *V);
IPVertexStruct *IPAppendVrtxLists(IPVertexStruct *VList1,
				  IPVertexStruct *VList2);
int IPObjListLen(IPObjectStruct *O);
int IPPolyListLen(IPPolygonStruct *P);
int IPVrtxListLen(IPVertexStruct *V);
void IPForEachPoly(IPObjectStruct *OList,
		   void (*CallBack) (IPPolygonStruct *));
void IPForEachVertex(IPObjectStruct *OList,
		     void (*CallBack) (IPVertexStruct *));
int IPTraverseObjectCopy(int TraverseObjCopy);
void IPTraverseObjListHierarchy(IPObjectStruct *PObjList,
				MatrixType CrntViewMat,
				IPApplyObjFuncType ApplyFunc);
void IPTraverseObjHierarchy(IPObjectStruct *PObj,
			    IPObjectStruct *PObjList,
			    IPApplyObjFuncType ApplyFunc,
			    MatrixType Mat,
			    int PrntInstance);
IPObjectStruct *IPLinkedListToObjList(IPObjectStruct *LnkList);

/* Coercion of objects. */
CagdPointType IPCoerceCommonSpace(IPObjectStruct *PtObjList,
				  CagdPointType Type);
CagdPointType IPCoercePtsListTo(IPObjectStruct *PtObjList, CagdPointType Type);
IPObjectStruct *IPCoerceObjectTo(IPObjectStruct *PObj, int NewType);
IPObjectStruct *IPReverseObject(IPObjectStruct *PObj);

/* Client Server - communication functions. */

/* Socket Read/Write routines. */
int IPSocWriteLine(int Handler, char *Line, int LineLen);
void IPSocWriteOneObject(int Handler, IPObjectStruct *PObj);
int IPSocReadCharNonBlock(int Handler);
char *IPSocReadLineNonBlock(int Handler);
IPObjectStruct *IPSocReadOneObject(int Handler);

/* Socket Server routines. */
int IPSocSrvrInit(void);
int IPSocSrvrListen(void);
void IPSocHandleClientEvent(int Handler, IPObjectStruct *PObj);

/* Socket Client routines. */
int IPSocClntInit(void);

/* Socket Communication with other processes. */
int IPSocExecAndConnect(char *Program, int IsBinary);
int IPSocDisConnectAndKill(int Kill, int Handler);
void IPSocEchoInput(int Handler, int EchoInput);

/* Dat to IRT conversion. */
void IPCnvDataToIrit(IPObjectStruct *PObjects);
void IPCnvDataToIritOneObject(char *Indent,
			      IPObjectStruct *PObject,
			      int Level);
char *IPCnvReal2Str(RealType R);
IPPrintFuncType IPCnvSetPrintFunc(IPPrintFuncType CnvPrintFunc);
int IPCnvSetLeastSquaresFit(int MinLenFit, int Percent, RealType MaxError);
char IPCnvSetDelimitChar(char Delimit);
int IPCnvSetCompactList(int CompactList);
int IPCnvSetDumpAssignName(int DumpAssignName);
IPPolyVrtxIdxStruct *IPCnvPolyToPolyVrtxIdxStruct(IPObjectStruct *PObj);

/* Special objects' read and write functions. These functions are used to   */
/* read and write objects of other libraries to and from data files.        */

CagdCrvStruct *CagdCrvReadFromFile(char *FileName, char **ErrStr, int *ErrLine);
CagdCrvStruct *CagdCrvReadFromFile2(int Handler, char **ErrStr, int *ErrLine);
int CagdCrvWriteToFile(CagdCrvStruct *Crvs,
		       char *FileName,
		       int Indent,
		       char *Comment,
		       char **ErrStr);
int CagdCrvWriteToFile2(CagdCrvStruct *Crvs,
			int Handler,
			int Indent,
			char *Comment,
			char **ErrStr);
int CagdCrvWriteToFile3(CagdCrvStruct *Crvs,
			FILE *f,
			int Indent,
			char *Comment,
			char **ErrStr);

CagdSrfStruct *CagdSrfReadFromFile(char *FileName,
				   char **ErrStr,
				   int *ErrLine);
CagdSrfStruct *CagdSrfReadFromFile2(int Handler, char **ErrStr, int *ErrLine);
int CagdSrfWriteToFile(CagdSrfStruct *Srfs,
		       char *FileName,
		       int Indent,
		       char *Comment,
		       char **ErrStr);
int CagdSrfWriteToFile2(CagdSrfStruct *Srfs,
			int Handler,
			int Indent,
			char *Comment,
			char **ErrStr);
int CagdSrfWriteToFile3(CagdSrfStruct *Srfs,
			FILE *f,
			int Indent,
			char *Comment,
			char **ErrStr);
CagdCrvStruct *BzrCrvReadFromFile(char *FileName, char **ErrStr, int *ErrLine);
CagdCrvStruct *BzrCrvReadFromFile2(int Handler,
				   CagdBType NameWasRead,
				   char **ErrStr,
				   int *ErrLine);
int BzrCrvWriteToFile(CagdCrvStruct *Crvs,
		      char *FileName,
		      int Indent,
		      char *Comment,
		      char **ErrStr);
int BzrCrvWriteToFile2(CagdCrvStruct *Crvs,
		       int Handler,
		       int Indent,
		       char *Comment,
		       char **ErrStr);
CagdSrfStruct *BzrSrfReadFromFile(char *FileName, char **ErrStr, int *ErrLine);
CagdSrfStruct *BzrSrfReadFromFile2(int Handler,
				   CagdBType NameWasRead,
				   char **ErrStr,
				   int *ErrLine);
int BzrSrfWriteToFile(CagdSrfStruct *Srfs,
		      char *FileName,
		      int Indent,
		      char *Comment,
		      char **ErrStr);
int BzrSrfWriteToFile2(CagdSrfStruct *Srfs,
		       int Handler,
		       int Indent,
		       char *Comment,
		       char **ErrStr);
CagdCrvStruct *BspCrvReadFromFile(char *FileName, char **ErrStr, int *ErrLine);
CagdCrvStruct *BspCrvReadFromFile2(int Handler,
				   CagdBType NameWasRead,
				   char **ErrStr,
				   int *ErrLine);
int BspCrvWriteToFile(CagdCrvStruct *Crvs,
		      char *FileName,
		      int Indent,
		      char *Comment,
		      char **ErrStr);
int BspCrvWriteToFile2(CagdCrvStruct *Crvs,
		       int Handler,
		       int Indent,
		       char *Comment,
		       char **ErrStr);
CagdSrfStruct *BspSrfReadFromFile(char *FileName, char **ErrStr, int *ErrLine);
CagdSrfStruct *BspSrfReadFromFile2(int Handler,
				   CagdBType NameWasRead,
				   char **ErrStr,
				   int *ErrLine);
int BspSrfWriteToFile(CagdSrfStruct *Srfs,
		      char *FileName,
		      int Indent,
		      char *Comment,
		      char **ErrStr);
int BspSrfWriteToFile2(CagdSrfStruct *Srfs,
		       int Handler,
		       int Indent,
		       char *Comment,
		       char **ErrStr);

TrivTVStruct *TrivTVReadFromFile(char *FileName, char **ErrStr, int *ErrLine);
TrivTVStruct *TrivTVReadFromFile2(int Handler, char **ErrStr, int *ErrLine);
TrivTVStruct *TrivBzrTVReadFromFile(char *FileName,
				    char **ErrStr,
				    int *ErrLine);
TrivTVStruct *TrivBzrTVReadFromFile2(int Handler, CagdBType NameWasRead,
				     char **ErrStr,
				     int *ErrLine);
TrivTVStruct *TrivBspTVReadFromFile(char *FileName,
				    char **ErrStr,
				    int *ErrLine);
TrivTVStruct *TrivBspTVReadFromFile2(int Handler,
				     CagdBType NameWasRead,
				     char **ErrStr,
				     int *ErrLine);
int TrivTVWriteToFile(TrivTVStruct *TVs,
		      char *FileName, 
		      int Indent,
		      char *Comment,
		      char **ErrStr);
int TrivTVWriteToFile2(TrivTVStruct *TVs,
		       int Handler,
		       int Indent,
		       char *Comment,
		       char **ErrStr);
int TrivTVWriteToFile3(TrivTVStruct *TVs,
		       FILE *f,
		       int Indent,
		       char *Comment,
		       char **ErrStr);
int TrivBzrTVWriteToFile(TrivTVStruct *TVs,
			 char *FileName,
			 int Indent,
			 char *Comment,
			 char **ErrStr);
int TrivBzrTVWriteToFile2(TrivTVStruct *TVs,
			  int Handler,
			  int Indent,
			  char *Comment,
			  char **ErrStr);
int TrivBspTVWriteToFile(TrivTVStruct *TVs,
			 char *FileName,
			 int Indent,
			 char *Comment,
			 char **ErrStr);
int TrivBspTVWriteToFile2(TrivTVStruct *TVs,
			  int Handler,
			  int Indent,
			  char *Comment,
			  char **ErrStr);

TrimSrfStruct *TrimReadTrimmedSrfFromFile(char *FileName,
					  char **ErrStr,
					  int *ErrLine);
TrimSrfStruct *TrimReadTrimmedSrfFromFile2(int Handler,
					   CagdBType NameWasRead,
					   char **ErrStr,
					   int *ErrLine);
int TrimWriteTrimmedSrfToFile(TrimSrfStruct *TrimSrfs,
			      char *FileName,
			      int Indent,
			      char *Comment,
			      char **ErrStr);
int TrimWriteTrimmedSrfToFile2(TrimSrfStruct *TrimSrfs,
			       int Handler,
			       int Indent,
			       char *Comment,
			       char **ErrStr);
int TrimWriteTrimmedSrfToFile3(TrimSrfStruct *TrimSrfs,
			       FILE *f,
			       int Indent,
			       char *Comment,
			       char **ErrStr);
TrngTriangSrfStruct *TrngTriSrfReadFromFile(char *FileName,
					    char **ErrStr,
					    int *ErrLine);
TrngTriangSrfStruct *TrngTriSrfReadFromFile2(int Handler,
					     char **ErrStr,
					     int *ErrLine);
TrngTriangSrfStruct *TrngBzrTriSrfReadFromFile(char *FileName,
					       char **ErrStr,
					       int *ErrLine);
TrngTriangSrfStruct *TrngBzrTriSrfReadFromFile2(int Handler,
						CagdBType NameWasRead,
						char **ErrStr,
						int *ErrLine);
TrngTriangSrfStruct *TrngBspTriSrfReadFromFile(char *FileName,
					       char **ErrStr,
					       int *ErrLine);
TrngTriangSrfStruct *TrngBspTriSrfReadFromFile2(int Handler,
						CagdBType NameWasRead,
						char **ErrStr,
						int *ErrLine);
TrngTriangSrfStruct *TrngGrgTriSrfReadFromFile(char *FileName,
					       char **ErrStr,
					       int *ErrLine);
TrngTriangSrfStruct *TrngGrgTriSrfReadFromFile2(int Handler,
						CagdBType NameWasRead,
						char **ErrStr,
						int *ErrLine);
int TrngTriSrfWriteToFile(TrngTriangSrfStruct *TriSrfs,
			  char *FileName,
			  int Indent,
			  char *Comment,
			  char **ErrStr);
int TrngTriSrfWriteToFile2(TrngTriangSrfStruct *TriSrfs,
			   int Handler,
			   int Indent,
			   char *Comment,
			   char **ErrStr);
int TrngTriSrfWriteToFile3(TrngTriangSrfStruct *TriSrfs,
			   FILE *f,
			   int Indent,
			   char *Comment,
			   char **ErrStr);
int TrngBzrTriSrfWriteToFile(TrngTriangSrfStruct *TriSrfs,
			     char *FileName,
			     int Indent,
			     char *Comment,
			     char **ErrStr);
int TrngBzrTriSrfWriteToFile2(TrngTriangSrfStruct *TriSrfs,
			      int Handler,
			      int Indent,
			      char *Comment,
			      char **ErrStr);
int TrngBspTriSrfWriteToFile(TrngTriangSrfStruct *TriSrfs,
			     char *FileName,
			     int Indent,
			     char *Comment,
			     char **ErrStr);
int TrngBspTriSrfWriteToFile2(TrngTriangSrfStruct *TriSrfs,
			      int Handler,
			      int Indent,
			      char *Comment,
			      char **ErrStr);
int TrngGrgTriSrfWriteToFile(TrngTriangSrfStruct *TriSrfs,
			     char *FileName,
			     int Indent,
			     char *Comment,
			     char **ErrStr);
int TrngGrgTriSrfWriteToFile2(TrngTriangSrfStruct *TriSrfs,
			      int Handler,
			      int Indent,
			      char *Comment,
			      char **ErrStr);

MdlModelStruct *MdlReadModelFromFile(char *FileName,
				     char **ErrStr,
				     int *ErrLine);
MdlModelStruct *MdlReadModelFromFile2(int Handler,
				      CagdBType NameWasRead,
				      char **ErrStr,
				      int *ErrLine);
int MdlWriteModelToFile(MdlModelStruct *Models,
			char *FileName,
			int Indent,
			char *Comment,
			char **ErrStr);
int MdlWriteModelToFile2(MdlModelStruct *Models,
			 int Handler,
			 int Indent,
			 char *Comment,
			 char **ErrStr);
int MdlWriteModelToFile3(MdlModelStruct *Models,
			 FILE *f,
			 int Indent,
			 char *Comment,
			 char **ErrStr);

MvarMVStruct *MvarMVReadFromFile(char *FileName, char **ErrStr, int *ErrLine);
MvarMVStruct *MvarMVReadFromFile2(int Handler, char **ErrStr, int *ErrLine);
MvarMVStruct *MvarBzrMVReadFromFile(char *FileName,
				    char **ErrStr,
				    int *ErrLine);
MvarMVStruct *MvarBzrMVReadFromFile2(int Handler,
				     CagdBType NameWasRead,
				     char **ErrStr,
				     int *ErrLine);
MvarMVStruct *MvarBspMVReadFromFile(char *FileName,
				    char **ErrStr,
				    int *ErrLine);
MvarMVStruct *MvarBspMVReadFromFile2(int Handler,
				     CagdBType NameWasRead,
				     char **ErrStr,
				     int *ErrLine);
int MvarMVWriteToFile(MvarMVStruct *MVs,
		      char *FileName,
		      int Indent,
		      char *Comment,
		      char **ErrStr);
int MvarMVWriteToFile2(MvarMVStruct *MVs,
		       int Handler,
		       int Indent,
		       char *Comment,
		       char **ErrStr);
int MvarMVWriteToFile3(MvarMVStruct *MVs,
		       FILE *f,
		       int Indent,
		       char *Comment,
		       char **ErrStr);
int MvarBzrMVWriteToFile(MvarMVStruct *MVs,
			 char *FileName,
			 int Indent,
			 char *Comment,
			 char **ErrStr);
int MvarBzrMVWriteToFile2(MvarMVStruct *MVs,
			  int Handler,
			  int Indent,
			  char *Comment,
			  char **ErrStr);
int MvarBspMVWriteToFile(MvarMVStruct *MVs,
			 char *FileName,
			 int Indent,
			 char *Comment,
			 char **ErrStr);
int MvarBspMVWriteToFile2(MvarMVStruct *MVs,
			  int Handler,
			  int Indent,
			  char *Comment,
			  char **ErrStr);

/************************************************************************
* Compress/decompress binary file support.                              *
************************************************************************/

/* IPC quantization steps. */
#define IPC_QUANTIZATION_DEFAULT  0.0000001f
#define IPC_QUANTIZATION_NONE     1.0          /* Quantization is not used. */

#ifdef IPC_BIN_COMPRESSION

/* Compressed stream functions: */
void IpcSetQuantization(int Handler, float QntError);
int IpcCompressObjToFile(char *FileName, IPObjectStruct *PObj, float QntError);
int IpcCompressObj(int Handler, IPObjectStruct *PObj);
IPObjectStruct *IpcDecompressObjFromFile(char *FileName);
IPObjectStruct *IpcDecompressObj(int Handler);

#endif /* IPC_BIN_COMPRESSION */

int IPSenseCompressedFile(char *FileName);

#ifdef DEBUG
void IPDbg(void);
void IPVertexDbg(IPVertexStruct *V);
void IPPolygonDbg(IPPolygonStruct *Pl);
#endif /* DEBUG */

#if defined(__cplusplus) || defined(c_plusplus)
}
#endif

#endif	/* IRIT_PRSR_H */
