/******************************************************************************
* GeomLib.h - header file of the geometry library.			      *
*******************************************************************************
* (C) Gershon Elber, Technion, Israel Institute of Technology                 *
*******************************************************************************
* Written by Gershon Elber, June 1996.					      *
******************************************************************************/

#ifndef	GEOM_LIB_H
#define GEOM_LIB_H

#include "iritprsr.h"
#include "attribut.h"
#include "allocate.h"
#include "bool_lib.h"
#include "ip_cnvrt.h"

typedef enum {
    GEOM_ERR_NO_OGL_SUPPORT,
    GEOM_ERR_OGL_NO_X_SERVER,
    GEOM_ERR_X_NO_OGL_SERVER,
    GEOM_ERR_X_NO_VISUAL,
    GEOM_ERR_X_NO_GCONTEXT,
    GEOM_ERR_CH_STACK_OVERFLOW,
    GEOM_ERR_CH_STACK_UNDERFLOW,
    GEOM_ERR_NO_INSTANCE_ORIGIN,
    GEOM_ERR_ANIM_MAT_OR_CRV,
    GEOM_ERR_UNKNOWN_ANIM_CRVS,
    GEOM_ERR_NO_ANIM_CRVS,
    GEOM_ERR_UNEQUAL_NUM_OF_POLYS,
    GEOM_ERR_UNEQUAL_NUM_OF_VRTXS,
    GEOM_ERR_TOO_MANY_ADJACENCIES,
    GEOM_ERR_NO_IRIT_PATH,
    GEOM_ERR_INVALID_FONT,
    GEOM_ERR_MSC_TOO_FEW_PTS,
    GEOM_ERR_MSC_COLIN_CIRC,
    GEOM_ERR_TRIANGLES_ONLY,
    GEOM_ERR_INVALID_POLYGON,
    GEOM_ERR_VRTX_MTCH_FAILED,
    GEOM_ERR_EXPCT_POLYHEDRA,
    GEOM_ERR_EXPCT_POLYLINE,
    GEOM_ERR_EXPCT_LIST_OBJ,
    GEOM_ERR_EXPCT_TWO_PTS,
    GEOM_ERR_PROJ_FAILED,
    GEOM_ERR_DECIM_BDRY_FAILED,
    GEOM_ERR_OPEN_OBJ_VOL_COMP,
    GEOM_ERR_NO_INV_MAT,
    GEOM_ERR_NO_POLY_PLANE,
    GEOM_ERR_NO_VRTX_NRML,
    GEOM_ERR_REGULAR_POLY,
    GEOM_ERR_REORIENT_STACK_OF,
    GEOM_ERR_DISJOINT_PARTS,

    GEOM_ERR_UNDEFINE_ERR
} GeomFatalErrorType;

typedef enum {
    GM_FIT_OTHER = -1,
    GM_FIT_PLANE = 0,
    GM_FIT_SPHERE,
    GM_FIT_CYLINDER,
    GM_FIT_CIRCLE,
    GM_FIT_CONE,
    GM_FIT_TORUS
} GMFittingModelType;

#define GM_FIT_MODEL_MAX_PARAM 10

/* Used by the Ray & Polygon intersection (Jordan theorem): */
#define GM_BELOW_RAY		1
#define GM_ON_RAY		2
#define GM_ABOVE_RAY		3
#define GM_ANIM_DEFAULT_FILE_NAME	"IAnim"
#define PRIM_MIN_RESOLUTION	4

#define GM_ANIM_NO_DEFAULT_TIME IRIT_INFNTY

#define GM_QUAT_COPY(SrcQ, DstQ)       GEN_COPY(DstQ, SrcQ, sizeof(GMQuatType))

typedef struct GMAnimationStruct {
    RealType
	StartT,		                     /* Starting time of animation. */
	FinalT,		                  /* Termination time of animation. */
	Dt,		                         /* Step size pf animation. */
	RunTime;		              /* Current time of animation. */
    int TwoWaysAnimation,   /* Should the animation bounce back and forth!? */
	SaveAnimationGeom,          /* Save animation geometry into files!? */
	SaveAnimationImage,           /* Save animation images into files!? */
	BackToOrigin,	           /* Should we terminate at the beginning? */
	NumOfRepeat,			            /* How many iterations? */
	StopAnim,		   /* If TRUE, must stop the animation now. */
	SingleStep,			     /* Are we in single step mode? */
	TextInterface,		/* Are we communicating using a textual UI? */
	MiliSecSleep,	   /* How many miliseconds to sleep between frames. */
	_Count;						/* Used internally. */
    char
	*ExecEachStep,		      /* Program to execute each iteration. */
	BaseFileName[LINE_LEN];      /* Base name of animation files saved. */
} GMAnimationStruct;

typedef struct GMR2PtStruct {
     RealType Pt[2];
} GMR2PtStruct;

typedef struct GMR3PtStruct {
     RealType Pt[3];
} GMR3PtStruct;

typedef struct GMBBBboxStruct {
    RealType Min[3];
    RealType Max[3];
} GMBBBboxStruct;

typedef RealType GMLsPoint[3];    /* The Z component is pretty much ignored. */

typedef struct GMLsLineSegStruct {
    struct GMLsLineSegStruct *Pnext;
    GMLsPoint Pts[2];
    long Id;			    /* Lines with unique ID never intersect. */
    VoidPtr PAux;	    /* Auxiliary backpointer - not used by ln_sweep. */
    struct GMLsIntersectStruct *Inters;
    GMLsPoint _MinVals;			         /* Bounding box on the line */
    GMLsPoint _MaxVals;
    GMLsPoint _Vec;		     /* A vector from first point to second. */
    RealType _ABC[3];			    /* Line equation as Ax + By + C. */
} GMLsLineSegStruct;

typedef struct GMLsIntersectStruct {
    struct GMLsIntersectStruct *Pnext;
    RealType t;
    RealType OtherT;
    struct GMLsLineSegStruct *OtherSeg;
    long Id;				       /* Unique ID of intersection. */
} GMLsIntersectStruct;

typedef RealType (*GMPolyOffsetAmountFuncType)(RealType *Coord);

typedef enum {             /* Predefined indices for the TransformVectorType */
    GM_QUAT_ROT_X = 0,
    GM_QUAT_ROT_Y,
    GM_QUAT_ROT_Z, 
    GM_QUAT_TRANS_X,
    GM_QUAT_TRANS_Y,
    GM_QUAT_TRANS_Z, 
    GM_QUAT_SCALE
} GMQuatTransformationsType;

typedef enum {
    GM_ZBUF_Z_LARGER,
    GM_ZBUF_Z_LARGER_EQUAL,
    GM_ZBUF_Z_SMALLER,
    GM_ZBUF_Z_SMALLER_EQUAL,
    GM_ZBUF_Z_ALWAYS,
    GM_ZBUF_Z_NEVER
} GMZTestsType;

typedef enum {
    GMPL_CRVTR_PARABOLOID_FIT = 0,
    GMPL_CRVTR_GAUSS_BONNET = 1
} GMPlCrvtrAlgorithmType;

typedef struct GMPlCrvtrDListStruct {
    struct GMPlCrvtrDListStruct *Pnext, *Pprev, *Tail;
    VoidPtr Data;
    size_t ElSize;
} GMPlCrvtrDListStruct;

typedef struct GMPlCrvtrVertexStruct {
    IPVertexStruct *Vert;
    /* The list of edges contains one edge with twin if the vertex is a      */
    /* two-manifold, or list of first edges for the vertex on the boudary    */
    struct GMPlCrvtrDListStruct *Edges;
} GMPlCrvtrVertexStruct;

typedef struct GMPlCrvtrMeshStruct {
    GMPlCrvtrDListStruct *Faces, *Vertices, *Edges;
    int NumOfVertices, NumOfFaces, NumOfEdges, InMesh;
} GMPlCrvtrMeshStruct;

typedef struct GMPlCrvtrAlgorithmStruct {
    GMPlCrvtrDListStruct *CurrVertex, *AlgVertices;
    GMPlCrvtrAlgorithmType WhichAlg;
    int NumberOfRings;
} GMPlCrvtrAlgorithmStruct;

typedef	RealType GMQuatType[4];                             /* A Quaternion. */
typedef RealType GMQuatTransVecType[7];        /* Transformation parameters. */

typedef void (*GMZBufferUpdateFuncType)(int ZbufferID, int x, int y);

typedef RealType (*GMDistEnergy1DFuncType)(RealType);

typedef void (*GMScanConvertApplyFuncType)(int x, int y);

typedef void (*GMTransObjUpdateFuncType)(IPObjectStruct *OldPObj,
					 IPObjectStruct *NewPObj,
					 MatrixType Mat,
					 int AnimUpdate);

typedef RealType (*GMFetchVertexPropertyFuncType)(IPVertexStruct *V,
						  IPPolygonStruct *Pl);

typedef void (* GMSphConeQueryCallBackFuncType)(IPVertexStruct *V);
typedef int (* GMSphConeQueryDirFuncType)(VectorType Vec, RealType ConeAngle);

typedef void (*GMPolyAdjacncyVertexFuncType)(IPVertexStruct *V1,
					     IPVertexStruct *V2,
					     IPPolygonStruct *Pl1,
					     IPPolygonStruct *Pl2);

typedef IPObjectStruct *(*GMTransObjUpdateAnimCrvsFuncType)(IPObjectStruct *PAnim,
							    MatrixType Mat);

extern GLOBAL_DATA int _PrimGlblResolution;

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

/* And prototypes of the functions: */

void GMVecCopy(VectorType Vdst, VectorType Vsrc);
void GMVecNormalize(VectorType V);
RealType GMVecLength(VectorType V);
void GMVecCrossProd(VectorType Vres, VectorType V1, VectorType V2);
RealType GMPlanarVecVecAngle(VectorType V1, VectorType V2, int Normalize);
int GMCollinear3Pts(PointType Pt1, PointType Pt2, PointType Pt3);
int GMCollinear3PtsInside(PointType Pt1, PointType Pt2, PointType Pt3);
int GMCoplanar4Pts(PointType Pt1, PointType Pt2, PointType Pt3, PointType Pt4);
RealType GMVecDotProd(VectorType V1, VectorType V2);

IPObjectStruct *GMGenMatObjectRotX(RealType *Degree);
IPObjectStruct *GMGenMatObjectRotY(RealType *Degree);
IPObjectStruct *GMGenMatObjectRotZ(RealType *Degree);
IPObjectStruct *GMGenMatObjectTrans(VectorType Vec);
IPObjectStruct *GMGenMatObjectScale(VectorType Vec);
IPObjectStruct *GMGetMatTransPortion(IPObjectStruct *MatObj, int TransPortion);
IPObjectStruct *GMGenMatObjectGeneric(IPObjectStruct *LstObjList);
IPPolygonStruct *GMTransformPolyList(IPPolygonStruct *Pls,
				     MatrixType Mat,
				     int IsPolygon);
GMTransObjUpdateFuncType GMTransObjSetUpdateFunc(GMTransObjUpdateFuncType
								   UpdateFunc);
GMTransObjUpdateAnimCrvsFuncType GMTransObjSetAnimCrvUpdateFunc(
			      GMTransObjUpdateAnimCrvsFuncType AnimUpdateFunc);
IPObjectStruct *GMTransformObject(IPObjectStruct *PObj, MatrixType Mat);
IPObjectStruct *GMTransformObjectList(IPObjectStruct *PObj, MatrixType Mat);
IPObjectStruct *GMTransObjUpdateAnimCrvs(IPObjectStruct *PAnim,
					 MatrixType Mat);
IPObjectStruct *GMGenMatObjectZ2Dir(VectorType Dir);
IPObjectStruct *GMGenMatObjectZ2Dir2(VectorType Dir, VectorType Dir2);
IPObjectStruct *GMGenMatObjectRotVec(VectorType Vec, RealType *Degree);

/* General basic computational geometry routines: */

RealType GMDistPointPoint(PointType P1, PointType P2);
int GMFindLinComb2Vecs(VectorType V1,
		       VectorType V2,
		       VectorType V,
		       RealType w[2]);
int GMLineFrom2Points(LineType Line, PointType Pt1, PointType Pt2);
void GMPointVecFromLine(LineType Line, PointType Pt, VectorType Dir);
int GMPlaneFrom3Points(PlaneType Plane,
		       PointType Pt1,
		       PointType Pt2,
		       PointType Pt3);
void GMPointFromPointLine(PointType Point,
			  PointType Pl,
			  PointType Vl,
			  PointType ClosestPoint);
RealType GMDistPointLine(PointType Point, PointType Pl, PointType Vl);
RealType GMDistPointPlane(PointType Point, RealType Plane[4]);
int GMPointFromLinePlane(PointType Pl,
			 PointType Vl,
			 RealType Plane[4],
			 PointType InterPoint,
			 RealType *t);
int GMPointFromLinePlane01(PointType Pl,
			   PointType Vl,
			   RealType Plane[4],
			   PointType InterPoint,
			   RealType *t);
int GM2PointsFromLineLine(PointType Pl1,
			  PointType Vl1,
			  PointType Pl2,
			  PointType Vl2,
			  PointType Pt1,
			  RealType *t1,
			  PointType Pt2,
			  RealType *t2);
RealType GMDistLineLine(PointType Pl1,
			PointType Vl1,
			PointType Pl2,
			PointType Vl2);
int GMPointFrom3Planes(PlaneType Pl1,
		       PlaneType Pl2,
		       PlaneType Pl3,
		       PointType Pt);

int GMPolygonPlaneInter(IPPolygonStruct *Pl, PlaneType Pln, RealType *MinDist);
int GMPolygonRayInter(IPPolygonStruct *Pl, PointType PtRay, int RayAxes);
int GMPolygonRayInter3D(IPPolygonStruct *Pl, PointType PtRay, int RayAxes);
void GMGenTransMatrixZ2Dir(MatrixType Mat,
			   VectorType Trans,
			   VectorType Dir,
			   RealType Scale);
void GMGenMatrixX2Dir(MatrixType Mat, VectorType Dir);
void GMGenMatrixY2Dir(MatrixType Mat, VectorType Dir);
void GMGenMatrixZ2Dir(MatrixType Mat, VectorType Dir);
void GMGenTransMatrixZ2Dir2(MatrixType Mat,
			    VectorType Trans,
			    VectorType Dir,
			    VectorType Dir2,
			    RealType Scale);
void GMGenMatrixZ2Dir2(MatrixType Mat, VectorType Dir, VectorType Dir2);
int GMMatFromPosDir(PointType Pos,
		    VectorType Dir,
		    VectorType UpDir,
		    MatrixType M);
void GMGenMatrixRotVec(MatrixType Mat, VectorType Vec, RealType Angle);
void GMGenProjectionMat(PlaneType ProjPlane,
			RealType EyePos[4],
			MatrixType Mat);
void GMGenReflectionMat(PlaneType ReflectPlane, MatrixType Mat);

RealType *GMBaryCentric3Pts(PointType Pt1,
			    PointType Pt2,
			    PointType Pt3,
			    PointType Pt);
int GM2PointsFromCircCirc(PointType Center1,
			  RealType Radius1,
			  PointType Center2,
			  RealType Radius2,
			  PointType Inter1,
			  PointType Inter2);
int GM2PointsFromCircCirc3D(PointType Cntr1,
			    VectorType Nrml1,
			    RealType Rad1,
			    PointType Cntr2,
			    VectorType Nrml2,
			    RealType Rad2,
			    PointType Inter1,
			    PointType Inter2);
int GMCircleFrom3Points(PointType Center,
			RealType *Radius,
			PointType Pt1,
			PointType Pt2,
			PointType Pt3);
int GMCircleFrom2Pts2Tans(PointType Center,
			  RealType *Radius,
			  PointType Pt1,
			  PointType Pt2,
			  VectorType Tan1,
			  VectorType Tan2);
int GM2BiTansFromCircCirc(PointType Center1,
			  RealType Radius1,
			  PointType Center2,
			  RealType Radius2,
			  int OuterTans,
			  PointType TanPts[2][2]);
int GM2TanLinesFromCircCirc(PointType Center1,
			    RealType Radius1,
			    PointType Center2,
			    RealType Radius2,
			    int OuterTans,
			    LineType Tans[2]);

/* Convex polygon - ray intersections in R3. */

int GMRayCnvxPolygonInter(PointType RayOrigin,
			  VectorType RayDir,
			  IPPolygonStruct *Pl,
			  PointType InterPoint);
int GMPointInsideCnvxPolygon(PointType Pt, IPPolygonStruct *Pl);

/* Polynomial solvers. */

int GMSolveQuadraticEqn(RealType A, RealType B, RealType *Sols);
int GMSolveCubicEqn(RealType A, RealType B, RealType C, RealType *Sols);

/* Geometric properties routines: */

double GMPolyObjectArea(IPObjectStruct *PObj);
double GMPolyOnePolyArea(IPPolygonStruct *Pl);
double GMPolyObjectVolume(IPObjectStruct *PObj);

/* Functions from sphere's cone distribution - Sph_Cone.c. */

void GMSphConeSetConeDensity(int n);
VoidPtr GMSphConeQueryInit(IPObjectStruct *PObj);
void GMSphConeQueryFree(VoidPtr SphCone);
void GMSphConeQueryGetVectors(VoidPtr SphConePtr,
			      VectorType Dir,
			      RealType Angle,
			      GMSphConeQueryCallBackFuncType SQFunc);
void GMSphConeQuery2GetVectors(VoidPtr SphConePtr,
			       GMSphConeQueryDirFuncType SQQuery,
			       GMSphConeQueryCallBackFuncType SQFunc);

/* Functions from the convex hull computation package. */

int GMConvexHull(GMR2PtStruct *DTPts, int *NumOfPoints);

/* Functions from the minimum spanning circle package. */

int GMMinSpanCirc(GMR2PtStruct *DTPts,
		  int NumOfPoints,
		  GMR2PtStruct *Center,
		  RealType *Radius);
int GMMinSpanConeAvg(VectorType *DTVecs,
		     int VecsNormalized,
		     int NumOfPoints,
		     VectorType Center,
		     RealType *Angle);
int GMMinSpanCone(VectorType *DTVecs,
		  int VecsNormalized,
		  int NumOfPoints,
		  VectorType Center,
		  RealType *Angle);

/* Functions to extract silhouette and boundary curves from polygonal data. */

VoidPtr GMSilPreprocessPolys(IPObjectStruct *PObj, int n);
int GMSilPreprocessRefine(VoidPtr PrepSils, int n);
IPObjectStruct *GMSilExtractSil(VoidPtr PrepSils, MatrixType ViewMat);
IPObjectStruct *GMSilExtractSilDirect(IPObjectStruct *PObj,
				      MatrixType ViewMat);
IPObjectStruct *GMSilExtractBndry(IPObjectStruct *PObj);
void GMSilProprocessFree(VoidPtr PrepSils);
int GMSilOrigObjAlive(int ObjAlive);

/* Functions from the animate package. */

void GMAnimResetAnimStruct(GMAnimationStruct *Anim);
void GMAnimGetAnimInfoText(GMAnimationStruct *Anim);
int GMAnimHasAnimation(IPObjectStruct *PObjs);
int GMAnimHasAnimationOne(IPObjectStruct *PObj);
void GMAnimFindAnimationTimeOne(GMAnimationStruct *Anim, IPObjectStruct *PObj);
void GMAnimFindAnimationTime(GMAnimationStruct *Anim, IPObjectStruct *PObjs);
void GMAnimSaveIterationsToFiles(GMAnimationStruct *Anim,
				 IPObjectStruct *PObjs);
void GMAnimSaveIterationsAsImages(GMAnimationStruct *Anim,
				  IPObjectStruct *PObjs);
RealType GMExecuteAnimationEvalMat(IPObjectStruct *AnimationP,
				   RealType Time,
				   MatrixType ObjMat);
void GMAnimDoAnimation(GMAnimationStruct *Anim, IPObjectStruct *PObjs);
int GMAnimSetAnimMatHierarchy(int AnimMatHierarchy);
int GMAnimSetAnimInternalNodes(int AnimInternalNodes);
void GMAnimEvalAnimation(RealType t, IPObjectStruct *PObj);
void GMAnimEvalAnimationList(RealType t, IPObjectStruct *PObjList);
void GMAnimDoSingleStep(GMAnimationStruct *Anim, IPObjectStruct *PObjs);
int GMAnimCheckInterrupt(GMAnimationStruct *Anim);

/* Functions from the bbox package. */

int GMBBSetBBoxInvisibles(int BBoxInvisibles);
GMBBBboxStruct *GMBBComputeBboxObject(IPObjectStruct *PObj);
GMBBBboxStruct *GMBBComputeBboxObjectList(IPObjectStruct *PObj);
IPObjectStruct *GMBBSetGlblBBObjList(IPObjectStruct *BBObjList);
GMBBBboxStruct *GMBBComputeOnePolyBbox(IPPolygonStruct *PPoly);
GMBBBboxStruct *GMBBComputePolyListBbox(IPPolygonStruct *PPoly);
GMBBBboxStruct *GMBBComputePointBbox(RealType *Pt);
GMBBBboxStruct *GMBBMergeBbox(GMBBBboxStruct *Bbox1, GMBBBboxStruct *Bbox2);

/* Functions from the convex polygons package. */

int GMConvexPolyNormals(int HandleNormals);
int GMConvexRaysToVertices(int RaysToVertices);
IPObjectStruct *GMConvexPolyObjectN(IPObjectStruct *PObj);
void GMConvexPolyObject(IPObjectStruct *PObj);
int GMIsConvexPolygon2(IPPolygonStruct *Pl);
int GMIsConvexPolygon(IPPolygonStruct *Pl);

IPPolygonStruct *GMSplitNonConvexPoly(IPPolygonStruct *Pl);
void GMGenRotateMatrix(MatrixType Mat, VectorType Dir);
void GMReverseVrtxList(IPPolygonStruct *Pl);

/* Functions from the polygonal decimation package. */

IPObjectStruct *GMDecimateObject(IPObjectStruct *);
void GMDecimateObjSetDistParam(RealType);
void GMDecimateObjSetPassNumParam(int);
void GMDecimateObjSetDcmRatioParam(int);
void GMDecimateObjSetMinAspRatioParam(RealType);

VoidPtr HDSCnvrtPObj2QTree(IPObjectStruct *PObjects, int Depth);
IPObjectStruct *HDSThreshold(VoidPtr Qt, RealType Threshold);
IPObjectStruct *HDSTriBudget(VoidPtr Qt, int TriBudget);
void HDSFreeQTree(VoidPtr Qt);
int HDSGetActiveListCount(VoidPtr Qt);
int HDSGetTriangleListCount(VoidPtr Qt);
int HDSGetDismissedTrianglesCount(VoidPtr Qt);

/* Functions from the normal/uv/rgb/etc. interpolation package. */

void GMUpdateVerticesByInterp(IPPolygonStruct *PlList,
			      IPPolygonStruct *OriginalPl);
int GMCollinear3Vertices(IPVertexStruct *V1,
			 IPVertexStruct *V2,
			 IPVertexStruct *V3);
void GMInterpVrtxNrmlBetweenTwo(IPVertexStruct *V,
				IPVertexStruct *V1,
				IPVertexStruct *V2);
void GMInterpVrtxNrmlBetweenTwo2(PointType Pt,
				 VectorType Normal,
				 IPVertexStruct *V1,
				 IPVertexStruct *V2);
void GMInterpVrtxNrmlFromPl(IPVertexStruct *V, IPPolygonStruct *Pl);
int GMInterpVrtxRGBBetweenTwo(IPVertexStruct *V,
			      IPVertexStruct *V1,
			      IPVertexStruct *V2);
int GMInterpVrtxRGBFromPl(IPVertexStruct *V, IPPolygonStruct *Pl);
int GMInterpVrtxUVBetweenTwo(IPVertexStruct *V,
			     IPVertexStruct *V1,
			     IPVertexStruct *V2);
int GMInterpVrtxUVFromPl(IPVertexStruct *V, IPPolygonStruct *Pl);
void GMBlendNormalsToVertices(IPPolygonStruct *PlList,
			      RealType MaxAngle);
void GMFixNormalsOfPolyModel(IPPolygonStruct *PlList, int TrustFixedPt);

/* Functions from the line sweep package. */

void GMLineSweep(GMLsLineSegStruct **Lines);

/* Functions from the polygonal cleaning package. */

int GMTwoPolySameGeom(IPPolygonStruct *Pl1, IPPolygonStruct *Pl2, RealType Eps);
void GMCleanUpDupPolys(IPPolygonStruct **PPolygons, RealType Eps);
void GMCleanUpPolygonList(IPPolygonStruct **PPolygons, RealType Eps);
void GMCleanUpPolylineList(IPPolygonStruct **PPolylines, RealType Eps);
void GMVrtxListToCircOrLin(IPPolygonStruct *Pls, int DoCirc);
IPVertexStruct *GMFilterInteriorVertices(IPVertexStruct *VHead,
					 RealType MinTol,
					 int n);
IPPolygonStruct *GMClipPolysAgainstPlane(IPPolygonStruct *PHead,
					 IPPolygonStruct **PClipped,
					 IPPolygonStruct **PInter,
					 PlaneType Plane);

/* Functions from the points on polygonal objects package. */

IPObjectStruct *GMConvertPolysToNGons(IPObjectStruct *PolyObj, int n);
IPObjectStruct *GMConvertPolysToTriangles(IPObjectStruct *PolyObj);
IPObjectStruct *GMConvertPolysToTriangles2(IPObjectStruct *PolyObj);
IPPolygonStruct *GMLimitTrianglesEdgeLen(IPPolygonStruct *Pls,
					 RealType MaxLen);
void GMGenUVValsForPolys(IPObjectStruct *PObj,
			 RealType UTextureRepeat,
			 RealType VTextureRepeat,
			 RealType WTextureRepeat,
			 int HasXYZScale);
typedef int (*GMMergePolyVrtxCmpFuncType)(IPVertexStruct *V1,
					  IPVertexStruct *V2,
					  RealType Eps);
IPPolygonStruct *GMMergePolylines(IPPolygonStruct *Polys,
				  RealType Eps,
				  GMMergePolyVrtxCmpFuncType VrtxCmpFunc);
IPPolygonStruct *GMMatchPointListIntoPolylines(IPObjectStruct *PtsList,
					       RealType MaxTol);
IPObjectStruct *GMPointCoverOfPolyObj(IPObjectStruct *PolyObj,
				      int n,
				      RealType *Dir,
				      char *PlAttr);
IPObjectStruct *GMRegularizePolyModel(IPObjectStruct *PObj);
IPPolygonStruct *GMSplitPolysAtCollinearVertices(IPPolygonStruct *Pls);
IPPolygonStruct *GMSplitPolyInPlaceAtVertex(IPPolygonStruct *Pl,
					    IPVertexStruct *VHead);

/* Functions from the polygonal offsets package. */

RealType GMPolyOffsetAmountDepth(RealType *Coord);
IPPolygonStruct *GMPolyOffset(IPPolygonStruct *Poly,
			      int IsPolygon,
			      RealType Ofst,
			      GMPolyOffsetAmountFuncType AmountFunc);

/* Functions from the primitive constructions' package. */

int PrimSetPolygonalPrimitives(int PolygonalPrimitive);
int PrimSetSurfacePrimitiveRational(int SurfaceRational);

IPObjectStruct *PrimGenBOXObject(VectorType Pt,
				 RealType WidthX,
				 RealType WidthY,
				 RealType WidthZ);
IPObjectStruct *PrimGenGBOXObject(VectorType Pt,
				  VectorType Dir1,
				  VectorType Dir2,
				  VectorType Dir3);
IPObjectStruct *PrimGenCONEObject(VectorType Pt,
				  VectorType Dir,
				  RealType R,
				  int Bases);
IPObjectStruct *PrimGenCONE2Object(VectorType Pt,
				   VectorType Dir,
				   RealType R1,
				   RealType R2,
				   int Bases);
IPObjectStruct *PrimGenCYLINObject(VectorType Pt,
				   VectorType Dir,
				   RealType R,
				   int Bases);
IPObjectStruct *PrimGenSPHEREObject(VectorType Center, RealType R);
IPObjectStruct *PrimGenTORUSObject(VectorType Center,
				   VectorType Normal,
				   RealType Rmajor,
				   RealType Rminor);
IPObjectStruct *PrimGenPOLYDISKObject(VectorType N, VectorType T, RealType R);
IPObjectStruct *PrimGenPOLYGONObject(IPObjectStruct *PObjList, int IsPolyline);
IPObjectStruct *PrimGenObjectFromPolyList(IPObjectStruct *PObjList);
IPObjectStruct *PrimGenCROSSECObject(IPObjectStruct *PObj);
IPObjectStruct *PrimGenSURFREVObject(IPObjectStruct *Cross);
IPObjectStruct *PrimGenSURFREVAxisObject(IPObjectStruct *Cross,
					 VectorType Axis);
IPObjectStruct *PrimGenSURFREV2Object(IPObjectStruct *Cross,
				      RealType StartAngle,
				      RealType EndAngle);
IPObjectStruct *PrimGenSURFREV2AxisObject(IPObjectStruct *Cross,
					  RealType StartAngle,
					  RealType EndAngle,
					  VectorType Axis);
IPObjectStruct *PrimGenEXTRUDEObject(IPObjectStruct *Cross,
				     VectorType Dir,
				     int Bases);
IPObjectStruct *PrimGenRULEDObject(IPObjectStruct *Cross1,
				   IPObjectStruct *Cross2);

IPPolygonStruct *PrimGenPolygon4Vrtx(VectorType V1,
				     VectorType V2,
				     VectorType V3,
				     VectorType V4,
				     VectorType Vin,
				     int *VrtcsRvrsd,
				     IPPolygonStruct *Pnext);
IPPolygonStruct *PrimGenPolygon3Vrtx(VectorType V1,
				     VectorType V2,
				     VectorType V3,
				     VectorType Vin,
				     int *VrtcsRvrsd,
				     IPPolygonStruct *Pnext);

int PrimSetResolution(int Resolution);

/* Functions from the quaternions package. */

void GMQuatToMat(GMQuatType q, MatrixType Mat);
void GMQuatMatToQuat(MatrixType Mat, GMQuatType q);
void GMQuatRotationToQuat(RealType Xangle,
			  RealType Yangle, 
			  RealType Zangle,
			  GMQuatType q);
void GMQuatToRotation(GMQuatType q, VectorType *Angles, int *NumSolutions);
void GMQuatMul(GMQuatType q1, GMQuatType q2, GMQuatType QRes);
void GMQuatAdd(GMQuatType q1, GMQuatType q2, GMQuatType QRes);
int GMQuatIsUnitQuat(GMQuatType q);
void GMQuatNormalize(GMQuatType q);
void GMQuatInverse(GMQuatType SrcQ, GMQuatType DstQ);
void GMQuatRotateVec(VectorType OrigVec, GMQuatType RotQ, VectorType DestVec);
void GMQuatLog(GMQuatType SrcQ, VectorType DstVec);
void GMQuatExp(VectorType SrcVec, GMQuatType DstQ);
void GMQuatPow(GMQuatType MantisQ, RealType Expon, GMQuatType DstQ);
int GMQuatMatrixToAngles(MatrixType Mat, VectorType *Vec);
void GMQuatMatrixToTranslation(MatrixType Mat, VectorType Vec);
RealType GMQuatMatrixToScale(MatrixType Mat);
int GMQuatMatrixToVector(MatrixType Mat, GMQuatTransVecType TransVec);
void GMQuatVectorToMatrix(GMQuatTransVecType TransVec, MatrixType Mat);
void GMQuatVecToScaleMatrix(GMQuatTransVecType TransVec,
			    MatrixType ScaleMatrix);
void GMQuatVecToRotMatrix(GMQuatTransVecType TransVec, MatrixType RotMatrix);
void GMQuatVecToTransMatrix(GMQuatTransVecType TransVec,
			    MatrixType TransMatrix);
void GMMatrixToTransform(MatrixType Mat, 
			 VectorType S,
			 GMQuatType R,
			 VectorType T);

/* Functions from the spherical coverage package. */

IPObjectStruct *GMPointCoverOfUnitHemiSphere(RealType HoneyCombSize);

/* Functions from the software z buffer. */

int GMZBufferInit(int Width, int Height);
void GMZBufferFree(int ZbufferID);
void GMZBufferClear(int ZbufferID);
void GMZBufferClearSet(int ZbufferID, RealType Depth);
GMZTestsType GMZBufferSetZTest(int ZbufferID, GMZTestsType ZTest);
GMZBufferUpdateFuncType GMZBufferSetUpdateFunc(int ZbufferID,
					       GMZBufferUpdateFuncType
					                           UpdateFunc);
int GMZBufferInvert(int ZbufferID);
int GMZBufferRoberts(int ZbufferID);
int GMZBufferLaplacian(int ZbufferID);
RealType GMZBufferQueryZ(int ZbufferID, int x, int y);
VoidPtr GMZBufferQueryInfo(int ZbufferID, int x, int y);
RealType GMZBufferUpdatePt(int ZbufferID, int x, int y, RealType z);
VoidPtr GMZBufferUpdateInfo(int ZbufferID, int x, int y, VoidPtr Info);
void GMZBufferUpdateHLn(int ZbufferID,
			int x1,
			int x2,
			int y,
			RealType z1,
			RealType z2);
void GMZBufferUpdateLine(int ZbufferID,
			 int x1,
			 int y1,
			 int x2,
			 int y2,
			 RealType z1,
			 RealType z2);
void GMZBufferUpdateTri(int ZbufferID,
			int x1,
			int y1,
			RealType z1,
			int x2,
			int y2,
			RealType z2,
			int x3,
			int y3,
			RealType z3);

/* Functions from the z buffer based on Open GL package. */

int GMZBufferOGLInit(int Width,
		     int Height,
		     RealType ZMin,
		     RealType ZMax,
		     int OffScreen);
void GMZBufferOGLClear(void);
void GMZBufferOGLSetColor(int Red, int Green, int Blue);
void GMZBufferOGLMakeActive(int Id);
RealType GMZBufferOGLQueryZ(RealType x, RealType y);
void GMZBufferOGLQueryColor(RealType x,
			    RealType y,
			    int *Red,
			    int *Green,
			    int *Blue);
void GMZBufferOGLFlush(void);

/* Functions to fit analytic functions to point data sets. */

PointType *GMSrfBilinearFit(PointType *ParamDomainPts,
			    PointType *EuclideanPts,
			    int FirstAtOrigin,
			    int NumPts);
PointType *GMSrfQuadricFit(PointType *ParamDomainPts,
			   PointType *EuclideanPts,
			   int FirstAtOrigin,
			   int NumPts);
PointType *GMSrfQuadricQuadOnly(PointType *ParamDomainPts,
				PointType *EuclideanPts,
				int FirstAtOrigin,
				int NumPts);

/* Functions from the distribution of point on a line package. */

RealType *GMDistPoint1DWithEnergy(int N,
				  RealType XMin,
				  RealType XMax,
				  int Resolution,
				  GMDistEnergy1DFuncType EnergyFunc);

/* Metamorphosis of polygonal objects. */

IPPolygonStruct *GMPolygonalMorphosis(IPPolygonStruct *Pl1,
				      IPPolygonStruct *Pl2,
				      RealType t);

/* Scan conversion of polygons. */

void GMScanConvertTriangle(int Pt1[2],
			   int Pt2[2],
			   int Pt3[2],
			   GMScanConvertApplyFuncType ApplyFunc);

/* Text and string data sets. */

int GMLoadTextFont(char *FName);
IPObjectStruct *GMMakeTextGeometry(char *Str,
				   VectorType Spacing,
				   RealType *Scaling);

/* Curvature analysis over polygonal meshes. */

GMPlCrvtrMeshStruct *GMPlCrvtrNewMesh(void);
int GMPlCrvtrInitMesh(GMPlCrvtrMeshStruct *Mesh, IPPolygonStruct *PolyList);
void GMPlCrvtrDeleteMesh(GMPlCrvtrMeshStruct *Mesh);
GMPlCrvtrAlgorithmStruct *GMPlCrvtrNewAlg(void);
void GMPlCrvtrInitAlg(GMPlCrvtrAlgorithmStruct *Alg, 
		      GMPlCrvtrMeshStruct *Mesh, 
		      GMPlCrvtrAlgorithmType AlgType, 
		      int NumberOfRings);
void GMPlCrvtrDeleteAlg(GMPlCrvtrAlgorithmStruct *Alg);
void GMPlCrvtrRunAlg(GMPlCrvtrAlgorithmStruct *Alg);
void GMPlCrvtrGo2NextVertex(GMPlCrvtrAlgorithmStruct *Alg);
void GMPlCrvtrSetCurvatureAttr(IPPolygonStruct *PolyList, int NumOfRings);
void GMPlCrvtrForEachVertex(IPPolygonStruct *PolyList, 
			    void (*ActionNew)(IPVertexStruct *Vertex), 
			    void (*ActionOld)(IPVertexStruct *Prev, 
					      IPVertexStruct *Current));

/* Extraction of properties from polygonal meshes. */

IPPolygonStruct *GMPolyPropFetchAttribute(IPPolygonStruct *Pls,
					  char *PropAttr,
					  RealType Value);
IPPolygonStruct *GMPolyPropFetchIsophotes(IPPolygonStruct *Pls,
					  VectorType ViewDir,
					  RealType InclinationAngle);
IPPolygonStruct *GMPolyPropFetchCurvature(IPPolygonStruct *Pls,
					  int CurvatureProperty,
					  int NumOfRings,
					  RealType CrvtrVal);
IPPolygonStruct *GMPolyPropFetch(IPPolygonStruct *Pls,
				 GMFetchVertexPropertyFuncType VertexProperty,
				 RealType ConstVal);
IPPolygonStruct *GMGenPolyline2Vrtx(VectorType V1,
				    VectorType V2,
				    IPPolygonStruct *Pnext);

/* Function for primitive fitting to point clouds. */

RealType GMFitData(RealType **PointData,
		   unsigned int NumberOfPointsToFit,
		   GMFittingModelType FittingModel,
		   RealType ModelParams[],
		   RealType Tolerance);
RealType GMFitDataWithOutliers(RealType **PointData,
			       unsigned int NumberOfPointsToFit,
			       GMFittingModelType FittingModel,
			       RealType ModelParams[],
			       RealType Tolerance,
			       unsigned int NumOfChecks);
RealType GMFitObjectWithOutliers(IPPolygonStruct *PPoly,
				 GMFittingModelType FittingModel,
				 RealType ModelExtParams[],
				 RealType Tolerance,
				 unsigned int NumOfChecks);	
RealType GMFitEstimateRotationAxis(PointType *PointsOnObject,
				   VectorType *Normals,
				   unsigned int NumberOfPoints, 
				   PointType PointOnRotationAxis,
				   VectorType RotationAxisDirection);

/* Functions to construct an adjacency data structure for polygonal meshes. */

VoidPtr GMPolyAdjacncyGen(IPObjectStruct *PObj, RealType EqlEps);
void GMPolyAdjacncyVertex(IPVertexStruct *V,
			  VoidPtr PolyAdj,
			  GMPolyAdjacncyVertexFuncType AdjVertexFunc);
void GMPolyAdjacncyFree(VoidPtr PolyAdj);

/* Error handling. */

void GeomFatalError(GeomFatalErrorType ErrID);
char *GeomDescribeError(GeomFatalErrorType ErrID);

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

#endif	/* GEOMAT_3D_H */
