/******************************************************************************
* Cagd_lib.h - header file for the CAGD library.			      *
* This header is also the interface header to the world.		      *
*******************************************************************************
* Written by Gershon Elber, Mar. 90.					      *
******************************************************************************/

#ifndef CAGD_LIB_H
#define CAGD_LIB_H

#include <stdio.h>
#include "irit_sm.h"
#include "imalloc.h"
#include "miscattr.h"
#include "genmat.h"

typedef int CagdBType;
typedef RealType CagdRType;
typedef RealType CagdUVType[2];
typedef PointType CagdPType;
typedef VectorType CagdVType;
typedef MatrixType CagdMType;
typedef LineType CagdLType;

typedef enum {
    CAGD_ERR_180_ARC = 1000,
    CAGD_ERR_AFD_NO_SUPPORT,
    CAGD_ERR_ALLOC_ERR,
    CAGD_ERR_BSPLINE_NO_SUPPORT,
    CAGD_ERR_BZR_CRV_EXPECT,
    CAGD_ERR_BZR_SRF_EXPECT,
    CAGD_ERR_CRV_FAIL_CMPT,
    CAGD_ERR_CRVS_INCOMPATIBLE,
    CAGD_ERR_CUBIC_EXPECTED,
    CAGD_ERR_DEGEN_ALPHA,
    CAGD_ERR_DIR_NOT_CONST_UV,
    CAGD_ERR_INDEX_NOT_IN_MESH,
    CAGD_ERR_KNOT_NOT_ORDERED,
    CAGD_ERR_LIN_NO_SUPPORT,
    CAGD_ERR_NO_CROSS_PROD,
    CAGD_ERR_NOT_ENOUGH_MEM,
    CAGD_ERR_NOT_IMPLEMENTED,
    CAGD_ERR_NUM_KNOT_MISMATCH,
    CAGD_ERR_OUT_OF_RANGE,
    CAGD_ERR_PARSER_STACK_OV,
    CAGD_ERR_POWER_NO_SUPPORT,
    CAGD_ERR_PT_OR_LEN_MISMATCH,
    CAGD_ERR_RATIONAL_EXPECTED,
    CAGD_ERR_SCALAR_EXPECTED,
    CAGD_ERR_SRF_FAIL_CMPT,
    CAGD_ERR_SRFS_INCOMPATIBLE,
    CAGD_ERR_T_NOT_IN_CRV,
    CAGD_ERR_U_NOT_IN_SRF,
    CAGD_ERR_UNDEF_CRV,
    CAGD_ERR_UNDEF_SRF,
    CAGD_ERR_UNSUPPORT_PT,
    CAGD_ERR_V_NOT_IN_SRF,
    CAGD_ERR_W_NOT_SAME,
    CAGD_ERR_WRONG_CRV,
    CAGD_ERR_WRONG_INDEX,
    CAGD_ERR_WRONG_ORDER,
    CAGD_ERR_WRONG_SRF,
    CAGD_ERR_WRONG_PT_TYPE,
    CAGD_ERR_CANNOT_COMP_NORMAL,
    CAGD_ERR_REPARAM_NOT_MONOTONE,
    CAGD_ERR_RATIONAL_NO_SUPPORT,
    CAGD_ERR_NO_SOLUTION,
    CAGD_ERR_TOO_COMPLEX,
    CAGD_ERR_REF_LESS_ORIG,
    CAGD_ERR_ONLY_2D_OR_3D,

    CAGD_ERR_UNDEFINE_ERR
} CagdFatalErrorType;

typedef enum {		/* Type of control point. The P-types are rationals. */
    CAGD_PT_BASE = 1100,			  /* Must be an even number. */
    CAGD_PT_E1_TYPE = 1100,
    CAGD_PT_P1_TYPE,
    CAGD_PT_E2_TYPE,
    CAGD_PT_P2_TYPE,
    CAGD_PT_E3_TYPE,
    CAGD_PT_P3_TYPE,
    CAGD_PT_E4_TYPE,
    CAGD_PT_P4_TYPE,
    CAGD_PT_E5_TYPE,
    CAGD_PT_P5_TYPE
} CagdPointType;

#define CAGD_IS_RATIONAL_PT(PType)  (((int) (PType - CAGD_PT_BASE)) & 0x01)
#define CAGD_NUM_OF_PT_COORD(PType) ((((int) (PType - CAGD_PT_BASE)) >> 1) + 1)
#define CAGD_MAKE_PT_TYPE(IsRational, NumCoords) \
				    ((CagdPointType) (CAGD_PT_BASE + \
				         ((((IsRational) ? -1 : -2) \
							+ (NumCoords << 1)))))
#define CAGD_MAX_PT_SIZE		6	/* Rational P5 has 6 coords. */
#define CAGD_MAX_PT_COORD		5		       /* Without w. */

#define CAGD_IS_RATIONAL_CRV(Crv)	CAGD_IS_RATIONAL_PT(Crv -> PType)
#define CAGD_IS_RATIONAL_SRF(Srf)	CAGD_IS_RATIONAL_PT(Srf -> PType)

/* Bezier curves may be evaluated using a predefined cache. The cache must   */
/* be of size (FINENESS) which is power of 2 up to the maximum order below.  */
/* See CrvBzrSetCache routine below.					     */
#define CAGD_MAX_BEZIER_CACHE_ORDER	10
#define CAGD_MAX_BEZIER_CACHE_FINENESS	1024

typedef enum {
    CAGD_UNDEF_TYPE = 1200,
    CAGD_CBEZIER_TYPE,
    CAGD_CBSPLINE_TYPE,
    CAGD_CPOWER_TYPE,
    CAGD_SBEZIER_TYPE,
    CAGD_SBSPLINE_TYPE,
    CAGD_SPOWER_TYPE
} CagdGeomType;

typedef enum {
    CAGD_NO_DIR = 1300,
    CAGD_CONST_U_DIR,
    CAGD_CONST_V_DIR
} CagdSrfDirType;
#define CAGD_OTHER_DIR(Dir) ((Dir) == CAGD_CONST_U_DIR ? CAGD_CONST_V_DIR \
						       : CAGD_CONST_U_DIR)

typedef enum {
    CAGD_REG_POLY_PER_LIN = 1400,
    CAGD_ONE_POLY_PER_LIN,
    CAGD_ONE_POLY_PER_COLIN
} CagdLin2PolyType;

typedef struct CagdGenericStruct {
    struct CagdGenericStruct *Pnext;
} CagdGenericStruct;

typedef struct CagdUVStruct {
    struct CagdPtStruct *Pnext;
    CagdUVType UV;
} CagdUVStruct;

typedef struct CagdPtStruct {
    struct CagdPtStruct *Pnext;
    CagdRType Pt[3];
} CagdPtStruct;

typedef struct CagdCtlPtStruct {
    struct CagdCtlPtStruct *Pnext;
    CagdPointType PtType;
    CagdRType Coords[CAGD_MAX_PT_SIZE];
} CagdCtlPtStruct;

typedef struct CagdVecStruct {
    struct CagdVecStruct *Pnext;
    CagdRType Vec[3];
} CagdVecStruct;

typedef struct CagdPlaneStruct {
    struct CagdPlaneStruct *Pnext;
    CagdRType Plane[4];
} CagdPlaneStruct;

typedef struct CagdBBoxStruct {
    struct CagdBBoxStruct *Pnext;
    CagdRType Min[3];
    CagdRType Max[3];
} CagdBBoxStruct;

typedef struct CagdCrvStruct {
    struct CagdCrvStruct *Pnext;
    struct IPAttributeStruct *Attr;
    CagdGeomType GType;
    CagdPointType PType;
    int Length;            /* Number of control points (== order in Bezier). */
    int Order;	    /* Order of curve (only for Bspline, ignored in Bezier). */
    CagdRType *Points[CAGD_MAX_PT_SIZE];     /* Pointer on each axis vector. */
    CagdRType *KnotVector;
} CagdCrvStruct;

typedef struct CagdSrfStruct {
    struct CagdSrfStruct *Pnext;
    struct IPAttributeStruct *Attr;
    CagdGeomType GType;
    CagdPointType PType;
    int ULength, VLength;	 /* Mesh size in the tensor product surface. */
    int UOrder, VOrder;   /* Order in tensor product surface (Bspline only). */
    CagdRType *Points[CAGD_MAX_PT_SIZE];     /* Pointer on each axis vector. */
    CagdRType *UKnotVector, *VKnotVector;
} CagdSrfStruct;

typedef struct CagdPolygonStruct {
    struct CagdPolygonStruct *Pnext;
    struct IPAttributeStruct *Attr;
    CagdPtStruct Polygon[3];		      /* Polygon is always triangle. */
    CagdVecStruct Normal[3];
    CagdUVStruct UV[3];
} CagdPolygonStruct;

typedef struct CagdPolylineStruct {
    struct CagdPolylineStruct *Pnext;
    struct IPAttributeStruct *Attr;
    CagdPtStruct *Polyline;    	 /* Polyline length is defined using Length. */
    int Length;
} CagdPolylineStruct;

typedef struct BspKnotAlphaCoeffType {
    int Order, Length, RefLength;     /* The dimensions of the alpha matrix. */
    CagdRType *Matrix;
    CagdRType **Rows;		     /* A column of pointers to Matrix rows. */
    int *ColIndex;	 /* A row of indices of first non zero value in col. */
    int *ColLength;	      /* A row of lengths of non zero values in col. */
} BspKnotAlphaCoeffType;

typedef void (*CagdPrintfFuncType)(char *Line);
typedef CagdCrvStruct *(*CagdCrvFuncType)(CagdCrvStruct *Crv, CagdRType R);

#define CAGD_IS_BEZIER_CRV(Crv)		(Crv -> GType == CAGD_CBEZIER_TYPE)
#define CAGD_IS_BEZIER_SRF(Srf)		(Srf -> GType == CAGD_SBEZIER_TYPE)
#define CAGD_IS_BSPLINE_CRV(Crv)	(Crv -> GType == CAGD_CBSPLINE_TYPE)
#define CAGD_IS_BSPLINE_SRF(Srf)	(Srf -> GType == CAGD_SBSPLINE_TYPE)
#define CAGD_IS_POWER_CRV(Crv)		(Crv -> GType == CAGD_CPOWER_TYPE)
#define CAGD_IS_POWER_SRF(Srf)		(Srf -> GType == CAGD_SPOWER_TYPE)

/******************************************************************************
*		U -->			    The mesh is ordered raw after raw *
*       +-----------------------+	or the increments along U are 1 while *
*   V | |P0                 Pi-1|	the increment along V is full raw.    *
*     v	|Pi                P2i-1|	    To encapsulate it, NEXTU/V are    *
*	|			|	defined below.			      *
*	|Pn-i		    Pn-1|					      *
*	+-----------------------+					      *
******************************************************************************/
#define CAGD_NEXT_U(Srf)	(1)
#define CAGD_NEXT_V(Srf)	(Srf -> ULength)
#define CAGD_MESH_UV(Srf, i, j)	((i) + (Srf -> ULength) * (j))

/******************************************************************************
* Routines prototypes. Routines are prefixed as follows:		      *
* Cagd    - General routines such as dynamic memory handlers etc.	      *
* BzrCrv  - Bezier curves routines.					      *
* BzrSrf  - Bezier surface routines.					      *
* BspKnot - Bspline knot vector routines.				      *
* BspCrv  - Bspline curves routines.					      *
* BspSrf  - Bspline surface routines.					      *
* Cnvrt   - Conversion routines such as Bezier to Power basis.		      *
******************************************************************************/

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

/******************************************************************************
* General routines of the Cagd library:					      *
******************************************************************************/
void CagdReadSocket(int ReadSocket);
void CagdWriteSocket(int WriteSocket);
void CagdSetFloatFormat(char *FloatFormat);
CagdCrvStruct *CagdCrvNew(CagdGeomType GType, CagdPointType PType, int Length);
CagdSrfStruct *CagdSrfNew(CagdGeomType GType, CagdPointType PType, int ULength,
								   int VLength);
CagdPolygonStruct *CagdPolygonNew(void);
CagdPolylineStruct *CagdPolylineNew(int Length);
CagdCrvStruct *CagdCrvCopy(CagdCrvStruct *Crv);
CagdSrfStruct *CagdSrfCopy(CagdSrfStruct *Srf);
CagdPolygonStruct *CagdPolygonCopy(CagdPolygonStruct *Poly);
CagdPolylineStruct *CagdPolylineCopy(CagdPolylineStruct *Poly);
void CagdCrvFree(CagdCrvStruct *Crv);
void CagdCrvFreeList(CagdCrvStruct *CrvList);
CagdCrvStruct *CagdCrvCopyList(CagdCrvStruct *CrvList);
void CagdSrfFree(CagdSrfStruct *Srf);
void CagdSrfFreeList(CagdSrfStruct *SrfList);
CagdSrfStruct *CagdSrfCopyList(CagdSrfStruct *SrfList);
void CagdPolylineFree(CagdPolylineStruct *Poly);
void CagdPolylineFreeList(CagdPolylineStruct *PolyList);
CagdPolylineStruct *CagdPolylineCopyList(CagdPolylineStruct *PolyList);
void CagdPolygonFree(CagdPolygonStruct *Poly);
void CagdPolygonFreeList(CagdPolygonStruct *PolyList);
CagdPolygonStruct *CagdPolygonCopyList(CagdPolygonStruct *PolyList);
void CagdPtFreeList(CagdPtStruct *PtList);
void CagdCtlPtFreeList(CagdCtlPtStruct *CtlPtList);
void CagdVecFreeList(CagdVecStruct *VecList);
void CagdPlaneFreeList(CagdPlaneStruct *PlaneList);
void CagdBBoxFreeList(CagdBBoxStruct *BBoxList);
VoidPtr CagdListReverse(VoidPtr List);
void CagdCoerceToE2(CagdRType *E2Point, CagdRType *Points[CAGD_MAX_PT_SIZE],
					     int Index, CagdPointType PType);
void CagdCoerceToE3(CagdRType *E3Point, CagdRType *Points[CAGD_MAX_PT_SIZE],
					     int Index, CagdPointType PType);
void CagdCoerceToP2(CagdRType *P2Point, CagdRType *Points[CAGD_MAX_PT_SIZE],
					     int Index, CagdPointType PType);
void CagdCoerceToP3(CagdRType *P3Point, CagdRType *Points[CAGD_MAX_PT_SIZE],
					     int Index, CagdPointType PType);
void CagdCoercePointTo(CagdRType *NewPoint, CagdPointType NewPType,
		       CagdRType *Points[CAGD_MAX_PT_SIZE], int Index,
		       CagdPointType OldPType);
void CagdCoercePointsTo(CagdRType *Points[], int Len,
			CagdPointType OldPType, CagdPointType NewPType);
CagdCrvStruct *CagdCoerceCrvTo(CagdCrvStruct *Crv, CagdPointType PType);
CagdSrfStruct *CagdCoerceSrfTo(CagdSrfStruct *Srf, CagdPointType PType);
CagdPointType CagdMergePointType(CagdPointType PType1, CagdPointType PType2);
void CagdMeshAddSub(CagdRType **DestPoints, CagdRType **Points1,
		    CagdRType **Points2, CagdPointType PType, int Size,
		    CagdBType OperationAdd);
void CagdFatalError(CagdFatalErrorType ErrID);
char *CagdDescribeError(CagdFatalErrorType ErrID);
void CagdDbg(void *Obj);
void CagdSetCagdFprintf(CagdPrintfFuncType Func);
void CagdSetLinear2Poly(CagdLin2PolyType Lin2Poly);
void CagdMergeBBox(CagdBBoxStruct *DestBBox, CagdBBoxStruct *SrcBBox);
CagdRType CagdIChooseK(int i, int k);

/******************************************************************************
* Matrix/Vector/Plane/Transformation routines:				      *
******************************************************************************/
CagdRType CagdDistanceTwoCtlPts(CagdRType **Points, int Index1, int Index2,
							CagdPointType PType);
CagdRType CagdFitPlaneThruCtlPts(CagdPlaneStruct *Plane, CagdPointType PType,
			         CagdRType **Points,
			         int Index1, int Index2, int Index3, int Index4);
CagdRType CagdDistPtPlane(CagdPlaneStruct *Plane, CagdRType **Points,
						      int Index, int MaxDim);

void CagdCrvMatTransform(CagdCrvStruct *Crv, CagdMType Mat);
void CagdSrfMatTransform(CagdSrfStruct *Srf, CagdMType Mat);
void CagdCrvTransform(CagdCrvStruct *Crv, CagdRType *Translate,
							CagdRType Scale);
void CagdSrfTransform(CagdSrfStruct *Srf, CagdRType *Translate,
							CagdRType Scale);

/******************************************************************************
* Routines to handle curves generically.				      *
******************************************************************************/
CagdRType CagdEstimateCrvColinearity(CagdCrvStruct *Crv);
void CagdCrvDomain(CagdCrvStruct *Crv, CagdRType *TMin, CagdRType *TMax);
CagdRType *CagdCrvEval(CagdCrvStruct *Crv, CagdRType t);
CagdCrvStruct *CagdCrvDerive(CagdCrvStruct *Crv);
CagdCrvStruct *CagdCrvIntegrate(CagdCrvStruct *Crv);
CagdCrvStruct *CagdCrvEnclosedArea(CagdCrvStruct *Crv);
CagdCrvStruct *CagdCrvSubdivAtParam(CagdCrvStruct *Crv, CagdRType t);
CagdCrvStruct *CagdCrvRegionFromCrv(CagdCrvStruct *Crv, CagdRType t1,
							CagdRType t2);
CagdCrvStruct *CagdCrvRefineAtParams(CagdCrvStruct *Crv, CagdBType Replace,
							 CagdRType *t, int n);
CagdVecStruct *CagdCrvTangent(CagdCrvStruct *Crv, CagdRType t);
CagdVecStruct *CagdCrvBiNormal(CagdCrvStruct *Crv, CagdRType t);
CagdVecStruct *CagdCrvNormal(CagdCrvStruct *Crv, CagdRType t);
CagdCrvStruct *CagdCrvOffset(CagdCrvStruct *Crv, CagdRType OffsetDist);
CagdCrvStruct *CagdCrvAdapOffset(CagdCrvStruct *OrigCrv,
				 CagdRType OffsetDist,
				 CagdRType OffsetError,
				 CagdCrvFuncType OffsetAprxFunc);
CagdCrvStruct *CagdCrvAdapOffsetTrim(CagdCrvStruct *OrigCrv,
				     CagdRType OffsetDist,
				     CagdRType OffsetError,
				     CagdCrvFuncType OffsetAprxFunc);
CagdCrvStruct *CagdCrvReverse(CagdCrvStruct *Crv);
CagdCrvStruct *CagdCrvDegreeRaise(CagdCrvStruct *Crv);
CagdCrvStruct *CagdCrvDegreeRaiseN(CagdCrvStruct *Crv, int NewOrder);
CagdCrvStruct *CagdMergeCrvCrv(CagdCrvStruct *Crv1, CagdCrvStruct *Crv2);
CagdCrvStruct *CagdMergeCrvList(CagdCrvStruct *CrvList);
CagdCrvStruct *CagdMergeCrvPt(CagdCrvStruct *Crv, CagdPtStruct *Pt);
CagdCrvStruct *CagdMergePtCrv(CagdPtStruct *Pt, CagdCrvStruct *Crv);
CagdCrvStruct *CagdMergePtPt(CagdPtStruct *Pt1, CagdPtStruct *Pt2);
CagdPolylineStruct *CagdCrv2CtrlPoly(CagdCrvStruct *Crv);
CagdPolylineStruct *CagdCrv2Polyline(CagdCrvStruct *Crv, int SamplesPerCurve);
CagdCrvStruct *CagdEditSingleCrvPt(CagdCrvStruct *Crv, CagdCtlPtStruct *CtlPt,
						   int Index, CagdBType Write);
CagdCrvStruct *CagdCrvReadFromFile(char *FileName, char **ErrStr, int *Line);
CagdCrvStruct *CagdCrvReadFromFile2(FILE *f, char **ErrStr, int *Line);
int CagdCrvWriteToFile(CagdCrvStruct *Crvs, char *FileName, int Indent,
						 char *Comment,	char **ErrStr);
int CagdCrvWriteToFile2(CagdCrvStruct *Crvs, FILE *f, int Indent, char *Comment,
								char **ErrStr);
CagdBType CagdMakeCrvsCompatible(CagdCrvStruct **Crv1, CagdCrvStruct **Crv2,
				 CagdBType SameOrder, CagdBType SameKV);
void CagdCrvBBox(CagdCrvStruct *Crv, CagdBBoxStruct *BBox);
void CagdCrvListBBox(CagdCrvStruct *Crvs, CagdBBoxStruct *BBox);
void CagdCrvMinMax(CagdCrvStruct *Crv, int Axis,
		   CagdRType *Min, CagdRType *Max);
int CagdCrvEvalToPolyline(CagdCrvStruct *Crv, int FineNess,
			  CagdRType *Points[], BspKnotAlphaCoeffType *A);
void CagdCrvSplitScalar(CagdCrvStruct *Crv, CagdCrvStruct **CrvW,
	     CagdCrvStruct **CrvX, CagdCrvStruct **CrvY, CagdCrvStruct **CrvZ);
CagdCrvStruct *CagdCrvMergeScalar(CagdCrvStruct *CrvW,
		CagdCrvStruct *CrvX, CagdCrvStruct *CrvY, CagdCrvStruct *CrvZ);
CagdCrvStruct *CagdCrvAdd(CagdCrvStruct *Crv1, CagdCrvStruct *Crv2);
CagdCrvStruct *CagdCrvSub(CagdCrvStruct *Crv1, CagdCrvStruct *Crv2);
CagdCrvStruct *CagdCrvReciprocal(CagdCrvStruct *Crv);
CagdCrvStruct *CagdCrvMult(CagdCrvStruct *Crv1, CagdCrvStruct *Crv2);
CagdCrvStruct *CagdCrvDotProd(CagdCrvStruct *Crv1, CagdCrvStruct *Crv2);
CagdCrvStruct *CagdCrvCrossProd(CagdCrvStruct *Crv1, CagdCrvStruct *Crv2);
CagdCrvStruct *CagdCrvRtnlMult(CagdCrvStruct *Crv1X, CagdCrvStruct *Crv1W,
			       CagdCrvStruct *Crv2X, CagdCrvStruct *Crv2W,
			       CagdBType OperationAdd);
CagdCrvStruct *CagdCrvCurvatureSqr(CagdCrvStruct *Crv);
CagdCrvStruct *CagdCrvCurvatureNormal(CagdCrvStruct *Crv);
CagdCrvStruct *CagdCrvCurvatureSign(CagdCrvStruct *Crv);
CagdPtStruct *CagdCrvInflectionPts(CagdCrvStruct *Crv, CagdRType Epsilon);
CagdPtStruct *CagdCrvExtremCrvtrPts(CagdCrvStruct *Crv, CagdRType Epsilon);
CagdPtStruct *CagdCrvZeroSet(CagdCrvStruct *Crv, int Axis, CagdRType Epsilon);
CagdPtStruct *CagdCrvExtremSet(CagdCrvStruct *Crv, int Axis, CagdRType Epsilon);
CagdPtStruct *CagdCrvConstSet(CagdCrvStruct *Crv, int Axis, CagdRType Epsilon,
							   CagdRType ConstVal);
CagdBType CagdCrvPosNegWeights(CagdCrvStruct *Crv);
CagdCrvStruct *CagdCrvUnitLenScalar(CagdCrvStruct *OrigCrv, CagdBType Mult,
							   CagdRType Epsilon);
CagdCrvStruct *CagdCrvSqrtScalar(CagdCrvStruct *OrigCrv, CagdRType Epsilon);
CagdCrvStruct *CagdCrvArcLenCrv(CagdCrvStruct *OrigCrv, CagdRType Epsilon);
CagdCrvStruct *CagdMakePosCrvCtlPolyPos(CagdCrvStruct *OrigCrv);
CagdCrvStruct *CagdComposeCrvCrv(CagdCrvStruct *Crv1, CagdCrvStruct *Crv2);
CagdCrvStruct *CagdComposeSrfCrv(CagdSrfStruct *Srf, CagdCrvStruct *Crv);
CagdCrvStruct *CagdLimitCrvArcLen(CagdCrvStruct *Crv, CagdRType MaxLen);
CagdRType CagdCrvArcLenPoly(CagdCrvStruct *Crv);
CagdRType CagdCrvArcLen(CagdCrvStruct *Crv, CagdRType Epsilon);
CagdPtStruct *CagdCrvArcLenSteps(CagdCrvStruct *Crv, CagdRType Length,
							    CagdRType Epsilon);

/******************************************************************************
* Routines to handle surfaces generically.				      *
******************************************************************************/
CagdRType CagdEstimateSrfPlanarity(CagdSrfStruct *Srf);
void CagdSrfDomain(CagdSrfStruct *Srf, CagdRType *UMin, CagdRType *UMax,
				       CagdRType *VMin, CagdRType *VMax);
CagdRType *CagdSrfEval(CagdSrfStruct *Srf, CagdRType u, CagdRType v);
CagdSrfStruct *CagdSrfDerive(CagdSrfStruct *Srf, CagdSrfDirType Dir);
CagdCrvStruct *CagdCrvFromSrf(CagdSrfStruct *Srf, CagdRType t,
							CagdSrfDirType Dir);
CagdCrvStruct *CagdCrvFromMesh(CagdSrfStruct *Srf, int Index,
							CagdSrfDirType Dir);
void CagdCrvToMesh(CagdCrvStruct *Crv, int Index,
				       CagdSrfDirType Dir, CagdSrfStruct *Srf);
CagdSrfStruct *CagdSrfSubdivAtParam(CagdSrfStruct *Srf, CagdRType t,
							   CagdSrfDirType Dir);
CagdSrfStruct *CagdSrfRegionFromSrf(CagdSrfStruct *Srf, CagdRType t1,
					     CagdRType t2, CagdSrfDirType Dir);
CagdSrfStruct *CagdSrfRefineAtParams(CagdSrfStruct *Srf, CagdSrfDirType Dir,
				       CagdBType Replace, CagdRType *t, int n);
CagdVecStruct *CagdSrfTangent(CagdSrfStruct *Srf, CagdRType u, CagdRType v,
							   CagdSrfDirType Dir);
CagdVecStruct *CagdSrfNormal(CagdSrfStruct *Srf, CagdRType u, CagdRType v);
CagdSrfStruct *CagdSrfOffset(CagdSrfStruct *Srf, CagdRType OffsetDist);
CagdSrfStruct *CagdSrfDegreeRaise(CagdSrfStruct *Srf, CagdSrfDirType Dir);
CagdSrfStruct *CagdSrfReverse(CagdSrfStruct *Srf);
CagdSrfStruct *CagdSrfReverse2(CagdSrfStruct *Srf);
CagdPolylineStruct *CagdSrf2CtrlMesh(CagdSrfStruct *Srf);
CagdSrfStruct *CagdMergeSrfSrf(CagdSrfStruct *Srf1, CagdSrfStruct *Srf2,
			       CagdSrfDirType Dir, CagdBType SameEdge);
CagdSrfStruct *CagdMergeSrfList(CagdSrfStruct *SrfList, CagdSrfDirType Dir,
							CagdBType SameEdge);
CagdPolygonStruct *CagdSrf2Polygons(CagdSrfStruct *Srf, int FineNess,
	CagdBType ComputeNormals, CagdBType FourPerFlat, CagdBType ComputeUV);
CagdPolylineStruct *CagdSrf2Polylines(CagdSrfStruct *Srf, int NumOfIsocurves[2],
							  int SamplesPerCurve);
CagdCrvStruct *CagdSrf2Curves(CagdSrfStruct *Srf, int NumOfIsocurves[2]);
CagdSrfStruct *CagdSrfReadFromFile(char *FileName, char **ErrStr, int *Line);
CagdSrfStruct *CagdSrfReadFromFile2(FILE *f, char **ErrStr, int *Line);
int CagdSrfWriteToFile(CagdSrfStruct *Srfs, char *FileName, int Indent,
						 char *Comment,	char **ErrStr);
int CagdSrfWriteToFile2(CagdSrfStruct *Srfs, FILE *f, int Indent, char *Comment,
								char **ErrStr);
CagdSrfStruct *CagdExtrudeSrf(CagdCrvStruct *Crv, CagdVecStruct *Vec);
CagdSrfStruct *CagdSurfaceRev(CagdCrvStruct *Crv);
CagdSrfStruct *CagdSweepSrf(CagdCrvStruct *CrossSection, CagdCrvStruct *Axis,
			    CagdCrvStruct *ScalingCrv, CagdRType Scale,
			    VoidPtr Frame, CagdBType FrameIsCrv);
CagdSrfStruct *CagdBoolSumSrf(CagdCrvStruct *CrvLeft,
			      CagdCrvStruct *CrvRight,
			      CagdCrvStruct *CrvTop,
			      CagdCrvStruct *CrvBottom);
CagdSrfStruct *CagdOneBoolSumSrf(CagdCrvStruct *BndryCrv);
CagdSrfStruct *CagdRuledSrf(CagdCrvStruct *Crv1, CagdCrvStruct *Crv2,
			    int OtherOrder, int OtherLen);
CagdSrfStruct *CagdPromoteCrvToSrf(CagdCrvStruct *Crv, CagdSrfDirType Dir);
CagdSrfStruct *CagdSrfFromCrvs(CagdCrvStruct *CrvList, int OtherOrder);
CagdBType CagdMakeSrfsCompatible(CagdSrfStruct **Srf1, CagdSrfStruct **Srf2,
				 CagdBType SameUOrder, CagdBType SameVOrder,
				 CagdBType SameUKV, CagdBType SameVKV);
CagdSrfStruct *CagdEditSingleSrfPt(CagdSrfStruct *Srf, CagdCtlPtStruct *CtlPt,
				      int UIndex, int VIndex, CagdBType Write);
void CagdSrfBBox(CagdSrfStruct *Srf, CagdBBoxStruct *BBox);
void CagdSrfListBBox(CagdSrfStruct *Srfs, CagdBBoxStruct *BBox);
void CagdSrfMinMax(CagdSrfStruct *Srf, int Axis,
		   CagdRType *Min, CagdRType *Max);
CagdSrfStruct *CagdTwoSrfsMorphing(CagdSrfStruct *Srf1, CagdSrfStruct *Srf2,
							      CagdRType Blend);
void CagdSrfSplitScalar(CagdSrfStruct *Srf, CagdSrfStruct **SrfW,
	     CagdSrfStruct **SrfX, CagdSrfStruct **SrfY, CagdSrfStruct **SrfZ);
CagdSrfStruct *CagdSrfMergeScalar(CagdSrfStruct *SrfW,
		CagdSrfStruct *SrfX, CagdSrfStruct *SrfY, CagdSrfStruct *SrfZ);
CagdSrfStruct *CagdSrfAdd(CagdSrfStruct *Srf1, CagdSrfStruct *Srf2);
CagdSrfStruct *CagdSrfSub(CagdSrfStruct *Srf1, CagdSrfStruct *Srf2);
CagdSrfStruct *CagdSrfReciprocal(CagdSrfStruct *Srf);
CagdSrfStruct *CagdSrfMult(CagdSrfStruct *Srf1, CagdSrfStruct *Srf2);
CagdSrfStruct *CagdSrfDotProd(CagdSrfStruct *Srf1, CagdSrfStruct *Srf2);
CagdSrfStruct *CagdSrfCrossProd(CagdSrfStruct *Srf1, CagdSrfStruct *Srf2);
CagdSrfStruct *CagdSrfNormalSrf(CagdSrfStruct *Srf);
CagdSrfStruct *CagdSrfRtnlMult(CagdSrfStruct *Srf1X, CagdSrfStruct *Srf1W,
			       CagdSrfStruct *Srf2X, CagdSrfStruct *Srf2W,
			       CagdBType OperationAdd);
CagdCrvStruct *CagdPrmtSclrCrvTo2D(CagdCrvStruct *Crv, CagdRType Min,
								CagdRType Max);
CagdSrfStruct *CagdPrmtSclrSrfTo3D(CagdSrfStruct *Srf,
				   CagdRType UMin, CagdRType UMax,
				   CagdRType VMin, CagdRType VMax);
void CagdSetAdapIsoExtractMinLevel(int MinLevel);
CagdCrvStruct *CagdAdapIsoExtract(CagdSrfStruct *Srf, CagdSrfStruct *NSrf,
				  CagdSrfDirType Dir,
				  CagdRType Eps, CagdBType FullIso,
				  CagdBType SinglePath);
CagdSrfStruct *CagdPiecewiseRuledSrfApprox(CagdSrfStruct *Srf,
					   CagdBType ConsistentDir,
					   CagdRType Epsilon,
					   CagdSrfDirType Dir);
CagdSrfStruct *CagdPrisaRuledSrf(CagdSrfStruct *Srf, int SamplesPerCurve,
				 CagdRType Space, CagdVType Offset);
CagdSrfStruct *CagdAllPrisaSrfs(CagdSrfStruct *Srfs, int SamplesPerCurve,
				CagdRType Epsilon, CagdSrfDirType Dir,
				CagdVType Space);
CagdSrfStruct *CagdSrfDistCrvCrv(CagdCrvStruct *Crv1, CagdCrvStruct *Crv2);
CagdPtStruct *CagdSrfDistFindPoints(CagdSrfStruct *Srf, CagdRType Epsilon,
							CagdBType SelfInter);
CagdRType CagdDistCrvPoint(CagdCrvStruct *Crv, CagdPType Pt,
					 CagdBType MinDist, CagdRType Epsilon);
CagdPtStruct *CagdLclDistCrvPoint(CagdCrvStruct *Crv, CagdPType Pt,
							    CagdRType Epsilon);
CagdRType CagdDistCrvLine(CagdCrvStruct *Crv, CagdLType Line,
					 CagdBType MinDist, CagdRType Epsilon);
CagdPtStruct *CagdLclDistCrvLine(CagdCrvStruct *Crv, CagdLType Line,
							    CagdRType Epsilon);

/******************************************************************************
* Routines to handle Bezier curves.					      *
******************************************************************************/
CagdCrvStruct *BzrCrvReadFromFile(char *FileName, char **ErrStr, int *ErrLine);
CagdCrvStruct *BzrCrvReadFromFile2(FILE *f, CagdBType NameWasRead,
						  char **ErrStr, int *ErrLine);
int BzrCrvWriteToFile(CagdCrvStruct *Crvs, char *FileName, int Indent,
						 char *Comment,	char **ErrStr);
int BzrCrvWriteToFile2(CagdCrvStruct *Crvs, FILE *f, int Indent, char *Comment,
								char **ErrStr);
CagdCrvStruct *BzrCrvNew(int Length, CagdPointType PType);
CagdRType BzrCrvEvalVecAtParam(CagdRType *Vec, int VecInc, int Order,
								CagdRType t);
CagdRType *BzrCrvEvalAtParam(CagdCrvStruct *Crv, CagdRType t);
void BzrCrvSetCache(int FineNess, CagdBType EnableCache);
void BzrCrvEvalToPolyline(CagdCrvStruct *Crv, int FineNess,
							CagdRType *Points[]);
CagdCrvStruct *BzrCrvCreateArc(CagdPtStruct *Start, CagdPtStruct *Center,
							    CagdPtStruct *End);
CagdCrvStruct *BzrCrvSubdivAtParam(CagdCrvStruct *Crv, CagdRType t);
CagdCrvStruct *BzrCrvDegreeRaise(CagdCrvStruct *Crv);
CagdCrvStruct *BzrCrvDegreeRaiseN(CagdCrvStruct *Crv, int NewOrder);
CagdCrvStruct *BzrCrvDerive(CagdCrvStruct *Crv);
CagdCrvStruct *BzrCrvIntegrate(CagdCrvStruct *Crv);
CagdCrvStruct *BzrCrvDeriveRational(CagdCrvStruct *Crv);
CagdVecStruct *BzrCrvTangent(CagdCrvStruct *Crv, CagdRType t);
CagdVecStruct *BzrCrvBiNormal(CagdCrvStruct *Crv, CagdRType t);
CagdVecStruct *BzrCrvNormal(CagdCrvStruct *Crv, CagdRType t);
CagdCrvStruct *BzrCrvInterpolate(int Size, CagdRType *XVec, CagdRType *YVec,
							      CagdRType *ZVec);
CagdPolylineStruct *BzrCrv2Polyline(CagdCrvStruct *Crv, int SamplesPerCurve);
CagdCrvStruct *BzrCrvMult(CagdCrvStruct *Crv1, CagdCrvStruct *Crv2);
CagdCrvStruct *BzrCrvMultList(CagdCrvStruct *Crv1Lst, CagdCrvStruct *Crv2Lst);
CagdCrvStruct *BzrApproxBzrCrvAsCubics(CagdCrvStruct *Crv, CagdRType Tol,
				       CagdRType MaxLen, CagdBType NoRational);
CagdCrvStruct *BzrApproxBzrCrvAsCubicPoly(CagdCrvStruct *Crv, CagdRType Tol2);
CagdCrvStruct *BzrComposeCrvCrv(CagdCrvStruct *Crv1, CagdCrvStruct *Crv2);
CagdCrvStruct *BzrComposeSrfCrv(CagdSrfStruct *Srf, CagdCrvStruct *Crv);

/******************************************************************************
* Routines to handle Bezier surfaces.					      *
******************************************************************************/
CagdSrfStruct *BzrSrfReadFromFile(char *FileName, char **ErrStr, int *ErrLine);
CagdSrfStruct *BzrSrfReadFromFile2(FILE *f, CagdBType NameWasRead,
						  char **ErrStr, int *ErrLine);
int BzrSrfWriteToFile(CagdSrfStruct *Srfs, char *FileName, int Indent,
						 char *Comment,	char **ErrStr);
int BzrSrfWriteToFile2(CagdSrfStruct *Srfs, FILE *f, int Indent, char *Comment,
								char **ErrStr);
CagdSrfStruct *BzrSrfNew(int ULength, int VLength, CagdPointType PType);
CagdRType *BzrSrfEvalAtParam(CagdSrfStruct *Srf, CagdRType u, CagdRType v);
CagdCrvStruct *BzrSrfCrvFromSrf(CagdSrfStruct *Srf, CagdRType t,
							CagdSrfDirType Dir);
CagdCrvStruct *BzrSrfCrvFromMesh(CagdSrfStruct *Srf, int Index,
							CagdSrfDirType Dir);
CagdSrfStruct *BzrSrfSubdivAtParam(CagdSrfStruct *Srf, CagdRType t,
							CagdSrfDirType Dir);
CagdSrfStruct *BzrSrfDegreeRaise(CagdSrfStruct *Srf, CagdSrfDirType Dir);
CagdSrfStruct *BzrSrfDerive(CagdSrfStruct *Srf, CagdSrfDirType Dir);
CagdSrfStruct *BzrSrfDeriveRational(CagdSrfStruct *Srf, CagdSrfDirType Dir);
CagdVecStruct *BzrSrfTangent(CagdSrfStruct *Srf, CagdRType u, CagdRType v,
							 CagdSrfDirType Dir);
CagdVecStruct *BzrSrfNormal(CagdSrfStruct *Srf, CagdRType u, CagdRType v);
CagdPolygonStruct *BzrSrf2Polygons(CagdSrfStruct *Srf, int FineNess,
	 CagdBType ComputeNormals, CagdBType FourPerFlat, CagdBType ComputeUV);
CagdPolylineStruct *BzrSrf2Polylines(CagdSrfStruct *Srf, int NumOfIsocurves[2],
							int SamplesPerCurve);
CagdCrvStruct *BzrSrf2Curves(CagdSrfStruct *Srf, int NumOfIsocurves[2]);
CagdSrfStruct *BzrSrfMult(CagdSrfStruct *Srf1, CagdSrfStruct *Srf2);

/******************************************************************************
* Routines to handle Bspline knot vectors.				      *
******************************************************************************/
CagdBType BspKnotHasOpenEC(CagdRType *KnotVector, int Len, int Order);
CagdBType BspKnotParamInDomain(CagdRType *KnotVector, int Len, int Order,
								CagdRType t);
int BspKnotLastIndexLE(CagdRType *KnotVector, int Len, CagdRType t);
int BspKnotLastIndexL(CagdRType *KnotVector, int Len, CagdRType t);
int BspKnotFirstIndexG(CagdRType *KnotVector, int Len, CagdRType t);
CagdRType *BspKnotUniformFloat(int Len, int Order, CagdRType *KnotVector);
CagdRType *BspKnotUniformOpen(int Len, int Order, CagdRType *KnotVector);
CagdRType *BspKnotSubtrTwo(CagdRType *KnotVector1, int Len1,
			   CagdRType *KnotVector2, int Len2,
			   int *NewLen);
CagdRType *BspKnotMergeTwo(CagdRType *KnotVector1, int Len1,
			   CagdRType *KnotVector2, int Len2,
			   int Mult, int *NewLen);
CagdRType *BspKnotNodes(CagdRType *KnotVector, int Len, int Order);
CagdRType *BspKnotPrepEquallySpaced(int n, CagdRType Tmin, CagdRType Tmax);
CagdRType *BspKnotReverse(CagdRType *KnotVector, int Len);
void BspKnotAffineTrans(CagdRType *KnotVector, int Len,
					CagdRType Translate, CagdRType Scale);
CagdRType *BspKnotCopy(CagdRType *KnotVector, int Len);
BspKnotAlphaCoeffType *BspKnotEvalAlphaCoef(int k, CagdRType *KVT,
				int LengthKVT, CagdRType *KVt, int LengthKVt);
BspKnotAlphaCoeffType *BspKnotEvalAlphaCoefMerge(int k, CagdRType *KVT,
			    int LengthKVT, CagdRType *NewKV, int LengthNewKV);
void BspKnotFreeAlphaCoef(BspKnotAlphaCoeffType *A);
CagdRType *BspKnotInsertOne(CagdRType *KnotVector, int Order, int Len,
								 CagdRType t);
CagdRType *BspKnotInsertMult(CagdRType *KnotVector, int Order, int *Len,
						       CagdRType t, int Mult);
int BspKnotFindMult(CagdRType *KnotVector, int Order, int Len, CagdRType t);
CagdBType BspKnotC1Discont(CagdRType *KnotVector, int Order, int Length,
								CagdRType *t);
CagdRType *BspKnotAllC1Discont(CagdRType *KnotVector, int Order, int Length,
								      int *n);
CagdRType *BspKnotParamValues(CagdRType PMin, CagdRType PMax, int NumSamples,
			      CagdRType *C1Disconts, int NumC1Disconts);
void BspKnotMakeRobustKV(CagdRType *KV, int Len);

/******************************************************************************
* Routines to handle Bspline curves.					      *
******************************************************************************/
CagdCrvStruct *BspCrvReadFromFile(char *FileName, char **ErrStr, int *ErrLine);
CagdCrvStruct *BspCrvReadFromFile2(FILE *f, CagdBType NameWasRead,
						  char **ErrStr, int *ErrLine);
int BspCrvWriteToFile(CagdCrvStruct *Crvs, char *FileName, int Indent,
						 char *Comment,	char **ErrStr);
int BspCrvWriteToFile2(CagdCrvStruct *Crvs, FILE *f, int Indent, char *Comment,
								char **ErrStr);
CagdCrvStruct *BspCrvNew(int Length, int Order, CagdPointType PType);
void BspCrvDomain(CagdCrvStruct *Crv, CagdRType *TMin, CagdRType *TMax);

CagdRType *BspCrvCoxDeBoorBasis(CagdRType *KnotVector, int Order, int Len,
						CagdRType t, int *IndexFirst);
CagdRType *BspCrvEvalCoxDeBoor(CagdCrvStruct *Crv, CagdRType t);
CagdRType BspCrvEvalVecAtParam(CagdRType *Vec, int VecInc,
			       CagdRType *KnotVector, int Order, int Len,
			       CagdRType t);
CagdRType *BspCrvEvalAtParam(CagdCrvStruct *Crv, CagdRType t);
CagdCrvStruct *BspCrvCreateCircle(CagdPtStruct *Center, CagdRType Radius);
CagdCrvStruct *BspCrvCreateUnitCircle(void);
CagdCrvStruct *BspCrvKnotInsert(CagdCrvStruct *Crv, CagdRType t);
CagdCrvStruct *BspCrvKnotInsertNSame(CagdCrvStruct *Crv, CagdRType t, int n);
CagdCrvStruct *BspCrvKnotInsertNDiff(CagdCrvStruct *Crv, CagdBType Replace,
							  CagdRType *t, int n);
CagdCrvStruct *BspCrvSubdivAtParam(CagdCrvStruct *Crv, CagdRType t);
CagdCrvStruct *BspCrvDegreeRaise(CagdCrvStruct *Crv);
CagdCrvStruct *BspCrvDegreeRaiseN(CagdCrvStruct *Crv, int NewOrder);
CagdCrvStruct *BspCrvDerive(CagdCrvStruct *Crv);
CagdCrvStruct *BspCrvIntegrate(CagdCrvStruct *Crv);
CagdCrvStruct *BspCrvDeriveRational(CagdCrvStruct *Crv);
CagdVecStruct *BspCrvTangent(CagdCrvStruct *Crv, CagdRType t);
CagdVecStruct *BspCrvBiNormal(CagdCrvStruct *Crv, CagdRType t);
CagdVecStruct *BspCrvNormal(CagdCrvStruct *Crv, CagdRType t);
CagdPolylineStruct *BspCrv2Polyline(CagdCrvStruct *Crv, int SamplesPerCurve,
						     BspKnotAlphaCoeffType *A);
CagdCrvStruct *BspCrvMult(CagdCrvStruct *Crv1, CagdCrvStruct *Crv2);

/******************************************************************************
* Routines to handle Bspline surfaces.					      *
******************************************************************************/
CagdSrfStruct *BspSrfReadFromFile(char *FileName, char **ErrStr, int *ErrLine);
CagdSrfStruct *BspSrfReadFromFile2(FILE *f, CagdBType NameWasRead,
						  char **ErrStr, int *ErrLine);
int BspSrfWriteToFile(CagdSrfStruct *Srfs, char *FileName, int Indent,
						 char *Comment,	char **ErrStr);
int BspSrfWriteToFile2(CagdSrfStruct *Srfs, FILE *f, int Indent, char *Comment,
								char **ErrStr);
CagdSrfStruct *BspSrfNew(int ULength, int VLength,
			 int UOrder, int VOrder, CagdPointType PType);
void BspSrfDomain(CagdSrfStruct *Srf, CagdRType *UMin, CagdRType *UMax,
				      CagdRType *VMin, CagdRType *VMax);
CagdRType *BspSrfEvalAtParam(CagdSrfStruct *Srf, CagdRType u, CagdRType v);
CagdCrvStruct *BspSrfCrvFromSrf(CagdSrfStruct *Srf, CagdRType t,
							CagdSrfDirType Dir);
CagdCrvStruct *BspSrfCrvFromMesh(CagdSrfStruct *Srf, int Index,
							CagdSrfDirType Dir);
CagdSrfStruct *BspSrfKnotInsert(CagdSrfStruct *Srf, CagdSrfDirType Dir,
								  CagdRType t);
CagdSrfStruct *BspSrfKnotInsertNSame(CagdSrfStruct *Srf, CagdSrfDirType Dir,
							   CagdRType t, int n);
CagdSrfStruct *BspSrfKnotInsertNDiff(CagdSrfStruct *Srf, CagdSrfDirType Dir,
					     int Replace, CagdRType *t, int n);
CagdSrfStruct *BspSrfSubdivAtParam(CagdSrfStruct *Srf, CagdRType t,
							CagdSrfDirType Dir);
CagdSrfStruct *BspSrfDegreeRaise(CagdSrfStruct *Srf, CagdSrfDirType Dir);
CagdSrfStruct *BspSrfDerive(CagdSrfStruct *Srf, CagdSrfDirType Dir);
CagdSrfStruct *BspSrfDeriveRational(CagdSrfStruct *Srf, CagdSrfDirType Dir);
CagdVecStruct *BspSrfTangent(CagdSrfStruct *Srf, CagdRType u, CagdRType v,
							 CagdSrfDirType Dir);
CagdVecStruct *BspSrfNormal(CagdSrfStruct *Srf, CagdRType u, CagdRType v);
CagdVecStruct *BspSrfMeshNormals(CagdSrfStruct *Srf, int UFineNess,
								int VFineNess);
CagdPolygonStruct *BspSrf2Polygons(CagdSrfStruct *Srf, int FineNess,
	 CagdBType ComputeNormals, CagdBType FourPerFlat, CagdBType ComputeUV);
CagdPolylineStruct *BspSrf2Polylines(CagdSrfStruct *Srf, int NumOfIsocurves[2],
							int SamplesPerCurve);
CagdCrvStruct *BspSrf2Curves(CagdSrfStruct *Srf, int NumOfIsocurves[2]);
CagdSrfStruct *BspSrfMult(CagdSrfStruct *Srf1, CagdSrfStruct *Srf2);

/******************************************************************************
* Routines to handle basis function conversions.			      *
******************************************************************************/
CagdCrvStruct *CnvrtPower2BezierCrv(CagdCrvStruct *Crv);
CagdCrvStruct *CnvrtBezier2PowerCrv(CagdCrvStruct *Crv);
CagdCrvStruct *CnvrtBspline2BezierCrv(CagdCrvStruct *Crv);
CagdCrvStruct *CnvrtBezier2BsplineCrv(CagdCrvStruct *Crv);

CagdSrfStruct *CnvrtPower2BezierSrf(CagdSrfStruct *Srf);
CagdSrfStruct *CnvrtBezier2PowerSrf(CagdSrfStruct *Srf);
CagdSrfStruct *CnvrtBezier2BsplineSrf(CagdSrfStruct *Srf);
CagdSrfStruct *CnvrtBspline2BezierSrf(CagdSrfStruct *Srf);

CagdCrvStruct *CnvrtPolyline2LinBsplineCrv(CagdPolylineStruct *Poly);

/******************************************************************************
* Routines to handle adaptive forward differencing basis functions.	      *
******************************************************************************/
void AfdCnvrtCubicBzrToAfd(CagdRType Coef[4]);
void AfdApplyLn(CagdRType Coef[4], int n);
void AfdApplyEStep(CagdRType Coef[4]);
void AfdComputePolyline(CagdRType Coef[4], CagdRType *Poly, int Log2Step,
							CagdBType NonAdaptive);
void AfdBzrCrvEvalToPolyline(CagdCrvStruct *Crv, int FineNess,
							CagdRType *Points[]);

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

#endif /* CAGD_LIB_H */
