/******************************************************************************
* Symb_lib.h - header file for the SYMBolic library.			      *
* This header is also the interface header to the world.		      *
* This library is closely related to symb_lib and should be linked with it.   *
*******************************************************************************
* Written by Gershon Elber, Mar. 90.					      *
******************************************************************************/

#ifndef SYMB_LIB_H
#define SYMB_LIB_H

#include <stdio.h>
#include "irit_sm.h"
#include "cagd_lib.h"

typedef enum {
    SYMB_ERR_WRONG_SRF,
    SYMB_ERR_BZR_CRV_EXPECT,
    SYMB_ERR_BZR_SRF_EXPECT,
    SYMB_ERR_BSP_CRV_EXPECT,
    SYMB_ERR_BSP_SRF_EXPECT,
    SYMB_ERR_RATIONAL_EXPECTED,
    SYMB_ERR_NO_CROSS_PROD,
    SYMB_ERR_POWER_NO_SUPPORT,
    SYMB_ERR_CRV_FAIL_CMPT,
    SYMB_ERR_SRF_FAIL_CMPT,
    SYMB_ERR_UNDEF_CRV,
    SYMB_ERR_UNDEF_SRF,
    SYMB_ERR_UNDEF_GEOM,
    SYMB_ERR_OUT_OF_RANGE,
    SYMB_ERR_DIR_NOT_CONST_UV,
    SYMB_ERR_REPARAM_NOT_MONOTONE,
    SYMB_ERR_BSPLINE_NO_SUPPORT,
    SYMB_ERR_WRONG_PT_TYPE,
    SYMB_ERR_ONLY_2D_OR_3D,
    SYMB_ERR_RATIONAL_NO_SUPPORT,
    SYMB_ERR_SRFS_INCOMPATIBLE,
    SYMB_ERR_CRVS_INCOMPATIBLE,
    SYMB_ERR_CANNOT_COMP_NORMAL,
    SYMB_ERR_TOO_COMPLEX,
    SYMB_ERR_UNSUPPORT_PT,
    SYMB_ERR_W_NOT_SAME,
    SYMB_ERR_SCALAR_EXPECTED,
    SYMB_ERR_POLY_CONST_SRF,

    SYMB_ERR_UNDEFINE_ERR
} SymbFatalErrorType;

typedef enum {
    SYMB_SUBDIV_STRAT_ALTERNATE = 1,
    SYMB_SUBDIV_STRAT_MIN_MAX,
    SYMB_SUBDIV_STRAT_MIN_MIN
} SymbPlSubdivStrategyType;

typedef struct SymbMultiResCrvStruct {
    struct SymbMultiResCrvStruct *Pnext;
    CagdCrvStruct **HieCrv;
    int RefineLevel, Levels, Periodic;
} SymbMultiResCrvStruct;

typedef CagdCrvStruct *(*SymbAdapIsoDistSqrFuncType)(int,
						     CagdCrvStruct *,
						     CagdCrvStruct *,
						     CagdCrvStruct *,
						     CagdCrvStruct *);
typedef CagdRType (*SymbPlErrorFuncType)(CagdSrfStruct *Srf,
					 CagdSrfDirType Dir);
typedef CagdCrvStruct *(*SymbOffCrvFuncType)(CagdCrvStruct *Crv,
					     CagdRType R,
					     CagdBType B);

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

/******************************************************************************
* Routines to handle curves generically.				      *
******************************************************************************/
CagdPolylineStruct *SymbCrv2Polyline(CagdCrvStruct *Crv,
				     int SamplesPerCurve,
				     CagdBType Optimal,
				     CagdBType OptiLin);
CagdCrvStruct *SymbCrvAdd(CagdCrvStruct *Crv1, CagdCrvStruct *Crv2);
CagdCrvStruct *SymbCrvSub(CagdCrvStruct *Crv1, CagdCrvStruct *Crv2);
CagdCrvStruct *SymbCrvMult(CagdCrvStruct *Crv1, CagdCrvStruct *Crv2);
CagdCrvStruct *SymbCrvInvert(CagdCrvStruct *Crv);
CagdCrvStruct *SymbCrvScalarScale(CagdCrvStruct *Crv, CagdRType Scale);
CagdCrvStruct *SymbCrvDotProd(CagdCrvStruct *Crv1, CagdCrvStruct *Crv2);
CagdCrvStruct *SymbCrvMultScalar(CagdCrvStruct *Crv1, CagdCrvStruct *Crv2);
CagdCrvStruct *SymbCrvCrossProd(CagdCrvStruct *Crv1, CagdCrvStruct *Crv2);
CagdCrvStruct *SymbCrvRtnlMult(CagdCrvStruct *Crv1X,
			       CagdCrvStruct *Crv1W,
			       CagdCrvStruct *Crv2X,
			       CagdCrvStruct *Crv2W,
			       CagdBType OperationAdd);
CagdCrvStruct *SymbCrvEnclosedArea(CagdCrvStruct *Crv);
CagdCrvStruct *SymbCrv2DCurvatureSqr(CagdCrvStruct *Crv);
CagdCrvStruct *SymbCrv3DCurvatureSqr(CagdCrvStruct *Crv);
CagdCrvStruct *SymbCrv3DRadiusNormal(CagdCrvStruct *Crv);
CagdCrvStruct *SymbCrv3DCurvatureNormal(CagdCrvStruct *Crv);
CagdCrvStruct *SymbCrv2DCurvatureSign(CagdCrvStruct *Crv);
CagdCrvStruct *SymbMakePosCrvCtlPolyPos(CagdCrvStruct *OrigCrv);
CagdPtStruct *SymbCrv2DInflectionPts(CagdCrvStruct *Crv, CagdRType Epsilon);
CagdPtStruct *SymbCrv2DExtremCrvtrPts(CagdCrvStruct *Crv, CagdRType Epsilon);
void SymbCrvSplitScalar(CagdCrvStruct *Crv,
			CagdCrvStruct **CrvW,
			CagdCrvStruct **CrvX,
			CagdCrvStruct **CrvY,
			CagdCrvStruct **CrvZ);
CagdCrvStruct *SymbCrvMergeScalar(CagdCrvStruct *CrvW,
				  CagdCrvStruct *CrvX,
				  CagdCrvStruct *CrvY,
				  CagdCrvStruct *CrvZ);
CagdCrvStruct *SymbLimitCrvArcLen(CagdCrvStruct *Crv, CagdRType MaxLen);
CagdRType SymbCrvArcLenPoly(CagdCrvStruct *Crv);
CagdCrvStruct *SymbCrvUnitLenScalar(CagdCrvStruct *OrigCrv,
				    CagdBType Mult,
				    CagdRType Epsilon);
CagdCrvStruct *SymbCrvSqrtScalar(CagdCrvStruct *OrigCrv, CagdRType Epsilon);
CagdCrvStruct *SymbCrvArcLenCrv(CagdCrvStruct *OrigCrv, CagdRType Epsilon);
CagdRType SymbCrvArcLen(CagdCrvStruct *Crv, CagdRType Epsilon);
CagdPtStruct *SymbCrvArcLenSteps(CagdCrvStruct *Crv,
				 CagdRType Length,
				 CagdRType Epsilon);
CagdCrvStruct *SymbComposeCrvCrv(CagdCrvStruct *Crv1, CagdCrvStruct *Crv2);
CagdCrvStruct *SymbComposeSrfCrv(CagdSrfStruct *Srf, CagdCrvStruct *Crv);
CagdRType SymbDistCrvPoint(CagdCrvStruct *Crv,
			   CagdPType Pt,
			   CagdBType MinDist,
			   CagdRType Epsilon);
CagdPtStruct *SymbLclDistCrvPoint(CagdCrvStruct *Crv,
				  CagdPType Pt,
				  CagdRType Epsilon);
CagdRType SymbDistCrvLine(CagdCrvStruct *Crv,
			  CagdLType Line,
			  CagdBType MinDist,
			  CagdRType Epsilon);
CagdPtStruct *SymbLclDistCrvLine(CagdCrvStruct *Crv,
				 CagdLType Line,
				 CagdRType Epsilon);
CagdPtStruct *SymbCrvZeroSet(CagdCrvStruct *Crv, int Axis, CagdRType Epsilon);
CagdPtStruct *SymbCrvExtremSet(CagdCrvStruct *Crv,
			       int Axis,
			       CagdRType Epsilon);
CagdPtStruct *SymbCrvConstSet(CagdCrvStruct *Crv,
			      int Axis,
			      CagdRType Epsilon,
			      CagdRType ConstVal);
CagdBType SymbCrvPosNegWeights(CagdCrvStruct *Crv);
CagdCrvStruct *SymbCrvOffset(CagdCrvStruct *Crv,
			     CagdRType OffsetDist,
			     CagdBType BezInterp);
CagdCrvStruct *SymbCrvSubdivOffset(CagdCrvStruct *Crv,
				   CagdRType OffsetDist,
				   CagdRType Tolerance,
				   CagdBType BezInterp);
CagdCrvStruct *SymbCrvAdapOffset(CagdCrvStruct *OrigCrv,
				 CagdRType OffsetDist,
				 CagdRType OffsetError,
				 SymbOffCrvFuncType OffsetAprxFunc,
				 CagdBType BezInterp);
CagdCrvStruct *SymbCrvAdapOffsetTrim(CagdCrvStruct *OrigCrv,
				     CagdRType OffsetDist,
				     CagdRType OffsetError,
				     SymbOffCrvFuncType OffsetAprxFunc,
				     CagdBType BezInterp);
CagdCrvStruct *SymbCrvLeastSquarOffset(CagdCrvStruct *Crv,
				       CagdRType OffsetDist,
				       int NumOfSamples,
				       int NumOfDOF,
				       int Order,
				       CagdRType *Tolerance);

/******************************************************************************
* Routines to handle surfaces generically.				      *
******************************************************************************/
CagdPolygonStruct *SymbSrf2Polygons(CagdSrfStruct *Srf,
				    int FineNess,
				    CagdBType ComputeNormals,
				    CagdBType FourPerFlat,
				    CagdBType ComputeUV);
CagdPolylineStruct *SymbSrf2Polylines(CagdSrfStruct *Srf,
				      int NumOfIsocurves[2],
				      int SamplesPerCurve,
				      int Optimal);
CagdCrvStruct *SymbSrf2Curves(CagdSrfStruct *Srf, int NumOfIsocurves[2]);
CagdSrfStruct *SymbSrfAdd(CagdSrfStruct *Srf1, CagdSrfStruct *Srf2);
CagdSrfStruct *SymbSrfSub(CagdSrfStruct *Srf1, CagdSrfStruct *Srf2);
CagdSrfStruct *SymbSrfMult(CagdSrfStruct *Srf1, CagdSrfStruct *Srf2);
CagdSrfStruct *SymbSrfInvert(CagdSrfStruct *Srf);
CagdSrfStruct *SymbSrfScalarScale(CagdSrfStruct *Srf, CagdRType Scale);
CagdSrfStruct *SymbSrfDotProd(CagdSrfStruct *Srf1, CagdSrfStruct *Srf2);
CagdSrfStruct *SymbSrfCrossProd(CagdSrfStruct *Srf1, CagdSrfStruct *Srf2);
CagdSrfStruct *SymbSrfRtnlMult(CagdSrfStruct *Srf1X,
			       CagdSrfStruct *Srf1W,
			       CagdSrfStruct *Srf2X,
			       CagdSrfStruct *Srf2W,
			       CagdBType OperationAdd);
CagdSrfStruct *SymbSrfNormalSrf(CagdSrfStruct *Srf);
void SymbMeshAddSub(CagdRType **DestPoints,
		    CagdRType **Points1,
		    CagdRType **Points2,
		    CagdPointType PType,
		    int Size,
		    CagdBType OperationAdd);
void SymbSrfSplitScalar(CagdSrfStruct *Srf,
			CagdSrfStruct **SrfW,
			CagdSrfStruct **SrfX,
			CagdSrfStruct **SrfY,
			CagdSrfStruct **SrfZ);
CagdSrfStruct *SymbSrfMergeScalar(CagdSrfStruct *SrfW,
				  CagdSrfStruct *SrfX,
				  CagdSrfStruct *SrfY,
				  CagdSrfStruct *SrfZ);
CagdCrvStruct *SymbPrmtSclrCrvTo2D(CagdCrvStruct *Crv,
				   CagdRType Min,
				   CagdRType Max);
CagdSrfStruct *SymbPrmtSclrSrfTo3D(CagdSrfStruct *Srf,
				   CagdRType UMin, CagdRType UMax,
				   CagdRType VMin, CagdRType VMax);
CagdRType *SymbExtremumCntPtVals(CagdRType **Points,
				 int Length,
				 CagdBType FindMinimum);
void SymbSetAdapIsoExtractMinLevel(int MinLevel);
CagdCrvStruct *SymbAdapIsoExtract(CagdSrfStruct *Srf,
				  CagdSrfStruct *NSrf,
				  SymbAdapIsoDistSqrFuncType AdapIsoDistFunc,
				  CagdSrfDirType Dir,
				  CagdRType Eps,
				  CagdBType FullIso,
				  CagdBType SinglePath);
CagdSrfStruct *SymbAllPrisaSrfs(CagdSrfStruct *Srfs,
				int SamplesPerCurve,
				CagdRType Epsilon,
				CagdSrfDirType Dir,
				CagdVType Space);
CagdSrfStruct *SymbPiecewiseRuledSrfApprox(CagdSrfStruct *Srf,
					   CagdBType ConsistentDir,
					   CagdRType Epsilon,
					   CagdSrfDirType Dir);
CagdSrfStruct *SymbPrisaRuledSrf(CagdSrfStruct *Srf,
				 int SamplesPerCurve,
				 CagdRType Space,
				 CagdVType Offset);
void SymbSrfFff(CagdSrfStruct *Srf,
		CagdSrfStruct **DuSrf,
		CagdSrfStruct **DvSrf,
		CagdSrfStruct **FffG11,
		CagdSrfStruct **FffG12,
		CagdSrfStruct **FffG22);
void SymbSrfSff(CagdSrfStruct *DuSrf,
		CagdSrfStruct *DvSrf,
		CagdSrfStruct **SffL11,
		CagdSrfStruct **SffL12,
		CagdSrfStruct **SffL22,
		CagdSrfStruct **SNormal);
CagdSrfStruct *SymbSrf2DDeterminant(CagdSrfStruct *Srf11,
				    CagdSrfStruct *Srf12,
				    CagdSrfStruct *Srf21,
				    CagdSrfStruct *Srf22);
CagdSrfStruct *SymbSrfCurvatureUpperBound(CagdSrfStruct *Srf);
CagdSrfStruct *SymbSrfIsoDirNormalCurvatureBound(CagdSrfStruct *Srf,
						 CagdSrfDirType Dir);
CagdSrfStruct *SymbSrfDistCrvCrv(CagdCrvStruct *Crv1, CagdCrvStruct *Crv2);
CagdPtStruct *SymbSrfDistFindPoints(CagdSrfStruct *Srf,
				    CagdRType Epsilon,
				    CagdBType SelfInter);
CagdCrvStruct *SymbTwoCrvsMorphing(CagdCrvStruct *Crv1,
				   CagdCrvStruct *Crv2,
				   CagdRType Blend);
CagdCrvStruct *SymbTwoCrvsMorphingCornerCut(CagdCrvStruct *Crv1,
					    CagdCrvStruct *Crv2,
					    CagdRType MinDist,
					    CagdBType SameLength,
					    CagdBType FilterTangencies);
CagdCrvStruct *SymbTwoCrvsMorphingMultiRes(CagdCrvStruct *Crv1,
					   CagdCrvStruct *Crv2,
					   CagdRType BlendStep);
CagdSrfStruct *SymbTwoSrfsMorphing(CagdSrfStruct *Srf1,
				   CagdSrfStruct *Srf2,
				   CagdRType Blend);
void SymbSrf2OptPolysCurvatureErrorPrep(CagdSrfStruct *Srf);
void SymbSrf2OptPolysIsoDirCurvatureErrorPrep(CagdSrfStruct *Srf);
CagdRType SymbSrf2OptPolysCurvatureError(CagdSrfStruct *Srf,
					 CagdSrfDirType Dir);
CagdRType SymbSrf2OptPolysBilinPolyError(CagdSrfStruct *Srf,
					 CagdSrfDirType Dir);
CagdPolygonStruct *SymbSrf2OptimalPolygons(CagdSrfStruct *Srf,
				CagdRType Tolerance,
				SymbPlSubdivStrategyType SubdivDirStrategy,
				SymbPlErrorFuncType SrfPolyApproxErr,
				CagdBType ComputeNormals,
				CagdBType FourPerFlat,
				CagdBType ComputeUV);
CagdSrfStruct *SymbSrfOffset(CagdSrfStruct *Srf, CagdRType OffsetDist);
CagdSrfStruct *SymbSrfSubdivOffset(CagdSrfStruct *Srf,
				   CagdRType OffsetDist,
				   CagdRType Tolerance);

/******************************************************************************
* Routines to handle Bezier curves.					      *
******************************************************************************/
CagdCrvStruct *BzrCrvMult(CagdCrvStruct *Crv1, CagdCrvStruct *Crv2);
CagdCrvStruct *BzrCrvMultList(CagdCrvStruct *Crv1Lst, CagdCrvStruct *Crv2Lst);
CagdCrvStruct *BzrCrvDeriveRational(CagdCrvStruct *Crv);
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 *BzrSrfMult(CagdSrfStruct *Srf1, CagdSrfStruct *Srf2);
CagdSrfStruct *BzrSrfDeriveRational(CagdSrfStruct *Srf, CagdSrfDirType Dir);

/******************************************************************************
* Routines to handle Bspline curves.					      *
******************************************************************************/
int BspMultInterpFlag(int BspMultUsingInter);
CagdCrvStruct *BspCrvMult(CagdCrvStruct *Crv1, CagdCrvStruct *Crv2);
CagdCrvStruct *BspCrvDeriveRational(CagdCrvStruct *Crv);

/******************************************************************************
* Routines to handle Multi Resolution Bspline curves.                         *
******************************************************************************/
SymbMultiResCrvStruct *SymbCrvMultiResDecomp(CagdCrvStruct *Crv, int Discont);
CagdCrvStruct *SymbCrvMultiResCompos(SymbMultiResCrvStruct *MRCrv);
CagdCrvStruct *SymbCrvMultiResComposAtT(SymbMultiResCrvStruct *MRCrv,
					CagdRType T);
void SymbCrvMultiResEdit(SymbMultiResCrvStruct *MRCrv,
			 CagdRType t,
			 CagdVType TransDir,
			 CagdRType Level,
			 CagdRType FracLevel);
CagdRType *SymbCrvMultiResRefineLevel(SymbMultiResCrvStruct *MRCrv,
				      CagdRType T,
				      int SpanDiscont);
void SymbCrvMultiResFree(SymbMultiResCrvStruct *MRCrv);
SymbMultiResCrvStruct *SymbCrvMultiResNew(int Levels, CagdBType Periodic);
SymbMultiResCrvStruct *SymbCrvMultiResCopy(SymbMultiResCrvStruct *MRCrvOrig);

/******************************************************************************
* Routines to handle Bspline surfaces.					      *
******************************************************************************/
CagdSrfStruct *BspSrfMult(CagdSrfStruct *Srf1, CagdSrfStruct *Srf2);
CagdSrfStruct *BspSrfDeriveRational(CagdSrfStruct *Srf, CagdSrfDirType Dir);

/******************************************************************************
* Error handling.							      *
******************************************************************************/
char *SymbDescribeError(SymbFatalErrorType ErrorNum);
void SymbFatalError(SymbFatalErrorType ErrID);

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

#endif /* SYMB_LIB_H */
