home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- * Cagd_aux.c - auxiliary routine to interface to different free from types. *
- *******************************************************************************
- * Written by Gershon Elber, July. 90. *
- ******************************************************************************/
-
- #include "cagd_loc.h"
-
- /******************************************************************************
- * Given a crv and parameter value t, evaluate the curve at t. *
- ******************************************************************************/
- CagdRType *CagdCrvEval(CagdCrvStruct *Crv, CagdRType t)
- {
- switch (Crv -> GType) {
- case CAGD_CBEZIER_TYPE:
- return BzrCrvEvalAtParam(Crv, t);
- case CAGD_CBSPLINE_TYPE:
- return BspCrvEvalAtParam(Crv, t);
- case CAGD_CPOWER_TYPE:
- FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
- return NULL;
- default:
- FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
- return NULL;
- }
- }
-
- /******************************************************************************
- * Given a srf and parameter values u,v, evaluate the surface at u,v. *
- ******************************************************************************/
- CagdRType *CagdSrfEval(CagdSrfStruct *Srf, CagdRType u, CagdRType v)
- {
- switch (Srf -> GType) {
- case CAGD_SBEZIER_TYPE:
- return BzrSrfEvalAtParam(Srf, u, v);
- case CAGD_SBSPLINE_TYPE:
- return BspSrfEvalAtParam(Srf, u, v);
- case CAGD_SPOWER_TYPE:
- FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
- return NULL;
- default:
- FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
- return NULL;
- }
- }
-
- /******************************************************************************
- * Given a curve - subdivide it into two at the given parametric value. *
- * Returns pointer to first curve in a list of two curves (subdivided ones). *
- ******************************************************************************/
- CagdCrvStruct *CagdCrvSubdivAtParam(CagdCrvStruct *Crv, CagdRType t)
- {
- switch (Crv -> GType) {
- case CAGD_CBEZIER_TYPE:
- return BzrCrvSubdivAtParam(Crv, t);
- case CAGD_CBSPLINE_TYPE:
- return BspCrvSubdivAtParam(Crv, t);
- case CAGD_CPOWER_TYPE:
- FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
- return NULL;
- default:
- FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
- return NULL;
- }
- }
-
- /******************************************************************************
- * Given a curve - returns a sub region within the specified domain. *
- ******************************************************************************/
- CagdCrvStruct *CagdCrvRegionFromCrv(CagdCrvStruct *Crv, CagdRType t1,
- CagdRType t2)
- {
- CagdRType TMin, TMax;
- CagdCrvStruct *Crvs;
- CagdBType
- NewCrv = FALSE;
-
- switch (Crv -> GType) {
- case CAGD_CBEZIER_TYPE:
- TMin = 0.0;
- TMax = 1.0;
- break;
- case CAGD_CBSPLINE_TYPE:
- BspCrvDomain(Crv, &TMin, &TMax);
- break;
- case CAGD_CPOWER_TYPE:
- FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
- return NULL;
- default:
- FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
- return NULL;
- }
-
- if (t1 > t2) SWAP(CagdRType, t1, t2);
-
- if (!APX_EQ(t1, TMin)) {
- Crvs = CagdCrvSubdivAtParam(Crv, t1);
- Crv = Crvs -> Pnext;
- Crvs -> Pnext = NULL;
- CagdCrvFree(Crvs); /* Free the first region. */
- NewCrv = TRUE;
- }
-
- if (APX_EQ(t2, TMax))
- return NewCrv ? Crv : CagdCrvCopy(Crv);
- else {
- Crvs = CagdCrvSubdivAtParam(Crv, t2);
-
- if (NewCrv) CagdCrvFree(Crv);
-
- CagdCrvFree(Crvs -> Pnext); /* Free the second region. */
- Crvs -> Pnext = NULL;
- return Crvs; /* Returns the first region. */
- }
- }
-
- /******************************************************************************
- * Given a curve - refine it at the given n knots as defined by vector t. *
- * If Replace is TRUE, the values replaces current vector instead. *
- * Returns pointer to refined crv (Note Bezier will be converted into spline). *
- ******************************************************************************/
- CagdCrvStruct *CagdCrvRefineAtParams(CagdCrvStruct *Crv, CagdBType Replace,
- CagdRType *t, int n)
- {
- CagdCrvStruct *BspCrv, *TCrv;
-
- switch (Crv -> GType) {
- case CAGD_CBEZIER_TYPE:
- BspCrv = CnvrtBezier2BsplineCrv(Crv);
- TCrv = BspCrvKnotInsertNDiff(BspCrv, Replace, t, n);
- CagdCrvFree(BspCrv);
- return TCrv;
- case CAGD_CBSPLINE_TYPE:
- return BspCrvKnotInsertNDiff(Crv, Replace, t, n);
- case CAGD_CPOWER_TYPE:
- FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
- return NULL;
- default:
- FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
- return NULL;
- }
- }
-
- /******************************************************************************
- * Return a new curve reversed by reversing the ctl polygon. *
- ******************************************************************************/
- CagdCrvStruct *CagdCrvReverse(CagdCrvStruct *Crv)
- {
- CagdBType
- IsNotRational = !CAGD_IS_RATIONAL_CRV(Crv);
- int i, Len, Col,
- Length = Crv -> Length,
- MaxCoord = CAGD_NUM_OF_PT_COORD(Crv -> PType);
- CagdCrvStruct
- *ReversedCrv = CagdCrvCopy(Crv);
- CagdRType *KV,
- **Points = ReversedCrv -> Points;
-
- switch (Crv -> GType) {
- case CAGD_CBEZIER_TYPE:
- case CAGD_CBSPLINE_TYPE:
- break;
- case CAGD_CPOWER_TYPE:
- FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
- return NULL;
- default:
- FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
- return NULL;
- }
-
- /* Reverse the Ctl Polygon: */
- Len = Length / 2;
- for (Col = 0; Col < Len; Col++)
- for (i = IsNotRational; i <= MaxCoord; i++)
- SWAP(CagdRType,
- Points[i][Col],
- Points[i][Length - Col - 1]);
-
- /* Reverse the knot vector if it exists: */
- if (Crv -> GType == CAGD_CBSPLINE_TYPE &&
- Crv -> KnotVector != NULL) {
- KV = BspKnotReverse(Crv -> KnotVector, Crv -> Order + Length);
- CagdFree((VoidPtr) ReversedCrv -> KnotVector);
- ReversedCrv -> KnotVector = KV;
- }
-
- return ReversedCrv;
- }
-
- /******************************************************************************
- * Return a new curve representing the same curve but with degree raised. *
- ******************************************************************************/
- CagdCrvStruct *CagdCrvDegreeRaise(CagdCrvStruct *Crv)
- {
- switch (Crv -> GType) {
- case CAGD_CBEZIER_TYPE:
- return BzrCrvDegreeRaise(Crv);
- case CAGD_CBSPLINE_TYPE:
- return BspCrvDegreeRaise(Crv);
- case CAGD_CPOWER_TYPE:
- FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
- return NULL;
- default:
- FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
- return NULL;
- }
- }
-
- /******************************************************************************
- * Return a new surface representing the same surface but with degree raised. *
- ******************************************************************************/
- CagdSrfStruct *CagdSrfDegreeRaise(CagdSrfStruct *Srf, CagdSrfDirType Dir)
- {
- switch (Srf -> GType) {
- case CAGD_SBEZIER_TYPE:
- return BzrSrfDegreeRaise(Srf, Dir);
- case CAGD_SBSPLINE_TYPE:
- return BspSrfDegreeRaise(Srf, Dir);
- case CAGD_SPOWER_TYPE:
- FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
- return NULL;
- default:
- FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
- return NULL;
- }
- }
-
- /******************************************************************************
- * Extracts an iso curve from the surface as spcified by Dir and t. *
- ******************************************************************************/
- CagdCrvStruct *CagdCrvFromSrf(CagdSrfStruct *Srf, CagdRType t,
- CagdSrfDirType Dir)
- {
- switch (Srf -> GType) {
- case CAGD_SBEZIER_TYPE:
- return BzrSrfCrvFromSrf(Srf, t, Dir);
- case CAGD_SBSPLINE_TYPE:
- return BspSrfCrvFromSrf(Srf, t, Dir);
- case CAGD_SPOWER_TYPE:
- FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
- return NULL;
- default:
- FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
- return NULL;
- }
- }
-
- /******************************************************************************
- * Extracts a curve from the surface as spcified by Dir and Index. *
- * The curve is constructed as a single ROW/COL of the original surface. *
- * Note this curve may be not on the surface! *
- ******************************************************************************/
- CagdCrvStruct *CagdCrvFromMesh(CagdSrfStruct *Srf, int Index,
- CagdSrfDirType Dir)
- {
- switch (Srf -> GType) {
- case CAGD_SBEZIER_TYPE:
- return BzrSrfCrvFromMesh(Srf, Index, Dir);
- case CAGD_SBSPLINE_TYPE:
- return BspSrfCrvFromMesh(Srf, Index, Dir);
- case CAGD_SPOWER_TYPE:
- FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
- return NULL;
- default:
- FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
- return NULL;
- }
- }
-
- /******************************************************************************
- * Substitue a row/col from the given curve into the surface as spcified by *
- * Dir and Index. Curve must have same PtType/Length and the surface row/col. *
- ******************************************************************************/
- void CagdCrvToMesh(CagdCrvStruct *Crv, int Index,
- CagdSrfDirType Dir, CagdSrfStruct *Srf)
- {
- CagdBType
- IsNotRational = !CAGD_IS_RATIONAL_SRF(Srf);
- int i, j,
- Length = Crv -> Length,
- ULength = Srf -> ULength,
- VLength = Srf -> VLength,
- MaxCoord = CAGD_NUM_OF_PT_COORD(Srf -> PType);
- CagdRType *CrvP, *SrfP;
-
- if (Crv -> PType != Srf -> PType ||
- Length != (Dir == CAGD_CONST_U_DIR ? VLength : ULength))
- FATAL_ERROR(CAGD_ERR_PT_OR_LEN_MISMATCH);
-
- switch (Dir) {
- case CAGD_CONST_U_DIR:
- if (Index + 1 > ULength)
- FATAL_ERROR(CAGD_ERR_INDEX_NOT_IN_MESH);
-
- for (i = IsNotRational; i <= MaxCoord; i++) {
- CrvP = Crv -> Points[i];
- SrfP = Srf -> Points[i] + Index * CAGD_NEXT_U(Srf);
- for (j = 0; j < Length; j++) {
- *SrfP = *CrvP++;
- SrfP += CAGD_NEXT_V(Srf);
- }
- }
- break;
- case CAGD_CONST_V_DIR:
- if (Index + 1 > VLength)
- FATAL_ERROR(CAGD_ERR_INDEX_NOT_IN_MESH);
-
- for (i = IsNotRational; i <= MaxCoord; i++) {
- CrvP = Crv -> Points[i];
- SrfP = Srf -> Points[i] + Index * CAGD_NEXT_V(Srf);;
- for (j = 0; j < Length; j++) {
- *SrfP = *CrvP++;
- SrfP += CAGD_NEXT_U(Srf);
- }
- }
- break;
- default:
- FATAL_ERROR(CAGD_ERR_DIR_NOT_CONST_UV);
- break;
- }
- }
-
- /******************************************************************************
- * Given a srf - subdivide it into two at given parametric value in given dir. *
- * Returns pointer to first srf in a list of two srfs (subdivided ones). *
- ******************************************************************************/
- CagdSrfStruct *CagdSrfSubdivAtParam(CagdSrfStruct *Srf, CagdRType t,
- CagdSrfDirType Dir)
- {
- switch (Srf -> GType) {
- case CAGD_SBEZIER_TYPE:
- return BzrSrfSubdivAtParam(Srf, t, Dir);
- case CAGD_SBSPLINE_TYPE:
- return BspSrfSubdivAtParam(Srf, t, Dir);
- case CAGD_SPOWER_TYPE:
- FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
- return NULL;
- default:
- FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
- return NULL;
- }
- }
-
- /******************************************************************************
- * Given a surface - returns a sub region within the specified domain, dir. *
- ******************************************************************************/
- CagdSrfStruct *CagdSrfRegionFromSrf(CagdSrfStruct *Srf, CagdRType t1,
- CagdRType t2, CagdSrfDirType Dir)
- {
- CagdRType TMin, TMax, R1, R2;
- CagdSrfStruct *Srfs;
- CagdBType
- NewSrf = FALSE;
-
- switch (Srf -> GType) {
- case CAGD_SBEZIER_TYPE:
- TMin = 0.0;
- TMax = 1.0;
- break;
- case CAGD_SBSPLINE_TYPE:
- if (Dir == CAGD_CONST_U_DIR)
- BspSrfDomain(Srf, &TMin, &TMax, &R1, &R2);
- else
- BspSrfDomain(Srf, &R1, &R2, &TMin, &TMax);
- break;
- case CAGD_SPOWER_TYPE:
- FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
- return NULL;
- default:
- FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
- return NULL;
- }
-
- if (t1 > t2) SWAP(CagdRType, t1, t2);
-
- if (!APX_EQ(t1, TMin)) {
- Srfs = CagdSrfSubdivAtParam(Srf, t1, Dir);
- Srf = Srfs -> Pnext;
- Srfs -> Pnext = NULL;
- CagdSrfFree(Srfs); /* Free the first region. */
- NewSrf = TRUE;
- }
-
- if (APX_EQ(t2, TMax))
- return NewSrf ? Srf : CagdSrfCopy(Srf);
- else {
- Srfs = CagdSrfSubdivAtParam(Srf, t2, Dir);
-
- if (NewSrf) CagdSrfFree(Srf);
-
- CagdSrfFree(Srfs -> Pnext); /* Free the second region. */
- Srfs -> Pnext = NULL;
- return Srfs; /* Returns the first region. */
- }
- }
-
- /******************************************************************************
- * Given a surface - refine it at the given n knots as defined by vector t. *
- * If Replace is TRUE, the values replaces current vector instead. *
- * Returns pointer to refined srf (Note Bezier will be converted into spline). *
- ******************************************************************************/
- CagdSrfStruct *CagdSrfRefineAtParams(CagdSrfStruct *Srf, CagdSrfDirType Dir,
- CagdBType Replace, CagdRType *t, int n)
- {
- CagdSrfStruct *BspSrf, *TSrf;
-
- switch (Srf -> GType) {
- case CAGD_SBEZIER_TYPE:
- BspSrf = CnvrtBezier2BsplineSrf(Srf);
- TSrf = BspSrfKnotInsertNDiff(BspSrf, Dir, Replace, t, n);
- CagdSrfFree(BspSrf);
- return TSrf;
- case CAGD_SBSPLINE_TYPE:
- return BspSrfKnotInsertNDiff(Srf, Dir, Replace, t, n);
- case CAGD_SPOWER_TYPE:
- FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
- return NULL;
- default:
- FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
- return NULL;
- }
- }
-
- /******************************************************************************
- * Given a curve and a parameter value t, returns the tangent direction at t. *
- ******************************************************************************/
- CagdVecStruct *CagdCrvTangent(CagdCrvStruct *Crv, CagdRType t)
- {
- switch (Crv -> GType) {
- case CAGD_CBEZIER_TYPE:
- return BzrCrvTangent(Crv, t);
- case CAGD_CBSPLINE_TYPE:
- return BspCrvTangent(Crv, t);
- case CAGD_CPOWER_TYPE:
- FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
- return NULL;
- default:
- FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
- return NULL;
- }
- }
-
- /******************************************************************************
- * Given a curve and a parameter value t, returns the binormal direction at t. *
- ******************************************************************************/
- CagdVecStruct *CagdCrvBiNormal(CagdCrvStruct *Crv, CagdRType t)
- {
- switch (Crv -> GType) {
- case CAGD_CBEZIER_TYPE:
- return BzrCrvBiNormal(Crv, t);
- case CAGD_CBSPLINE_TYPE:
- return BspCrvBiNormal(Crv, t);
- case CAGD_CPOWER_TYPE:
- FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
- return NULL;
- default:
- FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
- return NULL;
- }
- }
-
- /******************************************************************************
- * Given a curve and a parameter value t, returns the normal direction at t. *
- ******************************************************************************/
- CagdVecStruct *CagdCrvNormal(CagdCrvStruct *Crv, CagdRType t)
- {
- switch (Crv -> GType) {
- case CAGD_CBEZIER_TYPE:
- return BzrCrvNormal(Crv, t);
- case CAGD_CBSPLINE_TYPE:
- return BspCrvNormal(Crv, t);
- case CAGD_CPOWER_TYPE:
- FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
- return NULL;
- default:
- FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
- return NULL;
- }
- }
-
- /******************************************************************************
- * Given a curve and an offset amount Offset, returns an approximation to the *
- * offset curve by offseting the control polygon in the normal direction. *
- ******************************************************************************/
- CagdCrvStruct *CagdCrvOffset(CagdCrvStruct *Crv, CagdRType OffsetDist)
- {
- CagdBType
- IsNotRational = !CAGD_IS_RATIONAL_CRV(Crv);
- int i, j,
- MaxCoord = CAGD_NUM_OF_PT_COORD(Crv -> PType),
- Order = Crv -> Order,
- Length = Crv -> Length;
- CagdBType
- HasNewKV = FALSE;
- CagdVecStruct *N;
- CagdCrvStruct
- *OffsetCrv = CagdCrvCopy(Crv);
- CagdRType *Nodes, *NodePtr,
- **Points = OffsetCrv -> Points,
- *KV = NULL;
-
- switch (Crv -> GType) {
- case CAGD_CBEZIER_TYPE:
- HasNewKV = TRUE;
- KV = BspKnotUniformOpen(Length, Order, NULL);
- break;
- case CAGD_CBSPLINE_TYPE:
- KV = Crv -> KnotVector;
- break;
- case CAGD_CPOWER_TYPE:
- FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
- return NULL;
- default:
- FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
- return NULL;
- }
-
- Nodes = BspKnotNodes(KV, Length + Order, Order);
- NodePtr = Nodes;
-
- if (IsNotRational)
- for (j = 0; j < Length; j++) {
- N = CagdCrvNormal(Crv, *NodePtr++);
- for (i = 1; i <= MaxCoord; i++)
- Points[i][j] += N -> Vec[i - 1] * OffsetDist;
- }
- else
- for (j = 0; j < Length; j++) {
- N = CagdCrvNormal(Crv, *NodePtr++);
- for (i = 1; i <= MaxCoord; i++)
- Points[i][j] = Points[i][j] +
- N -> Vec[i - 1] * OffsetDist * Points[W][j];
- }
-
- if (HasNewKV)
- CagdFree((VoidPtr) KV);
- CagdFree((VoidPtr) Nodes);
-
- return OffsetCrv;
- }
-
- /******************************************************************************
- * Given a srf and parameter value u,v, returns the tangent direction in Dir. *
- ******************************************************************************/
- CagdVecStruct *CagdSrfTangent(CagdSrfStruct *Srf, CagdRType u, CagdRType v,
- CagdSrfDirType Dir)
- {
- switch (Srf -> GType) {
- case CAGD_SBEZIER_TYPE:
- return BzrSrfTangent(Srf, u, v, Dir);
- case CAGD_SBSPLINE_TYPE:
- return BspSrfTangent(Srf, u, v, Dir);
- case CAGD_SPOWER_TYPE:
- FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
- return NULL;
- default:
- FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
- return NULL;
- }
- }
-
- /******************************************************************************
- * Given a srf and parameter values u,v, returns the surface normal at u,v. *
- ******************************************************************************/
- CagdVecStruct *CagdSrfNormal(CagdSrfStruct *Srf, CagdRType u, CagdRType v)
- {
- switch (Srf -> GType) {
- case CAGD_SBEZIER_TYPE:
- return BzrSrfNormal(Srf, u, v);
- case CAGD_SBSPLINE_TYPE:
- return BspSrfNormal(Srf, u, v);
- case CAGD_SPOWER_TYPE:
- FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
- return NULL;
- default:
- FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
- return NULL;
- }
- }
-
- /******************************************************************************
- * Given a surface and an offset amount Offset, returns an approximation to *
- * the offset surface by offseting the control mesh in the normal direction. *
- ******************************************************************************/
- CagdSrfStruct *CagdSrfOffset(CagdSrfStruct *Srf, CagdRType OffsetDist)
- {
- CagdBType
- IsNotRational = !CAGD_IS_RATIONAL_SRF(Srf);
- int i, Row, Col,
- MaxCoord = CAGD_NUM_OF_PT_COORD(Srf -> PType),
- UOrder = Srf -> UOrder,
- VOrder = Srf -> VOrder,
- ULength = Srf -> ULength,
- VLength = Srf -> VLength;
- CagdBType
- HasNewKV = FALSE;
- CagdVecStruct *N;
- CagdSrfStruct
- *OffsetSrf = CagdSrfCopy(Srf);
- CagdRType *UNodes, *VNodes, *UNodePtr, *VNodePtr,
- **Points = OffsetSrf -> Points,
- *UKV = NULL,
- *VKV = NULL;
-
- switch (Srf -> GType) {
- case CAGD_SBEZIER_TYPE:
- HasNewKV = TRUE;
- UKV = BspKnotUniformOpen(ULength, UOrder, NULL);
- VKV = BspKnotUniformOpen(VLength, VOrder, NULL);
- break;
- case CAGD_SBSPLINE_TYPE:
- UKV = Srf -> UKnotVector;
- VKV = Srf -> VKnotVector;
- break;
- case CAGD_SPOWER_TYPE:
- FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
- return NULL;
- default:
- FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
- return NULL;
- }
-
- UNodes = BspKnotNodes(UKV, ULength + UOrder, UOrder);
- VNodes = BspKnotNodes(VKV, VLength + VOrder, VOrder);
-
- if (IsNotRational)
- for (Row = 0, VNodePtr = VNodes; Row < VLength; Row++, VNodePtr++)
- for (Col = 0, UNodePtr = UNodes; Col < ULength; Col++, UNodePtr++) {
- N = CagdSrfNormal(Srf, *UNodePtr, *VNodePtr);
- for (i = 1; i <= MaxCoord; i++)
- Points[i][CAGD_MESH_UV(OffsetSrf, Col, Row)] +=
- N -> Vec[i - 1] * OffsetDist;
- }
- else
- for (Row = 0, VNodePtr = VNodes; Row < VLength; Row++, VNodePtr++)
- for (Col = 0, UNodePtr = UNodes; Col < ULength; Col++, UNodePtr++) {
- N = CagdSrfNormal(Srf, *UNodePtr, *VNodePtr);
- for (i = 1; i <= MaxCoord; i++)
- Points[i][CAGD_MESH_UV(OffsetSrf, Col, Row)] +=
- N -> Vec[i - 1] * OffsetDist *
- Points[W][CAGD_MESH_UV(OffsetSrf, Col, Row)];
- }
-
- if (HasNewKV) {
- CagdFree((VoidPtr) UKV);
- CagdFree((VoidPtr) VKV);
- }
-
- CagdFree((VoidPtr) UNodes);
- CagdFree((VoidPtr) VNodes);
-
- return OffsetSrf;
- }
-
- /******************************************************************************
- * Return a new reversed surface by reversing in U direction the control mesh. *
- ******************************************************************************/
- CagdSrfStruct *CagdSrfReverse(CagdSrfStruct *Srf)
- {
- CagdBType
- IsNotRational = !CAGD_IS_RATIONAL_SRF(Srf);
- int i, Len, Row, Col,
- ULength = Srf -> ULength,
- VLength = Srf -> VLength,
- MaxCoord = CAGD_NUM_OF_PT_COORD(Srf -> PType);
- CagdSrfStruct
- *ReversedSrf = CagdSrfCopy(Srf);
- CagdRType *KV,
- **Points = ReversedSrf -> Points;
-
- switch (Srf -> GType) {
- case CAGD_SBEZIER_TYPE:
- case CAGD_SBSPLINE_TYPE:
- break;
- case CAGD_SPOWER_TYPE:
- FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
- return NULL;
- default:
- FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
- return NULL;
- }
-
- /* Reverse the Mesh: */
- Len = ULength / 2;
- for (Row = 0; Row < VLength; Row++)
- for (Col = 0; Col < Len; Col++)
- for (i = IsNotRational; i <= MaxCoord; i++)
- SWAP(CagdRType,
- Points[i][Row * ULength + Col],
- Points[i][Row * ULength + ULength - Col - 1]);
-
- /* Reverse the U knot vector if it exists: */
- if (Srf -> GType == CAGD_SBSPLINE_TYPE &&
- Srf -> UKnotVector != NULL) {
- KV = BspKnotReverse(Srf -> UKnotVector, Srf -> UOrder + ULength);
- CagdFree((VoidPtr) ReversedSrf -> UKnotVector);
- ReversedSrf -> UKnotVector = KV;
- }
-
- return ReversedSrf;
- }
-
- /******************************************************************************
- * Return a new reversed surface by flipping the U and V directions. *
- ******************************************************************************/
- CagdSrfStruct *CagdSrfReverse2(CagdSrfStruct *Srf)
- {
- CagdBType
- IsNotRational = !CAGD_IS_RATIONAL_SRF(Srf);
- int i, Row, Col,
- ULength = Srf -> ULength,
- VLength = Srf -> VLength,
- MaxCoord = CAGD_NUM_OF_PT_COORD(Srf -> PType);
- CagdSrfStruct
- *ReversedSrf = CagdSrfCopy(Srf);
- CagdRType
- **Points = Srf -> Points,
- **RevPoints = ReversedSrf -> Points;
-
- switch (Srf -> GType) {
- case CAGD_SBEZIER_TYPE:
- case CAGD_SBSPLINE_TYPE:
- break;
- case CAGD_SPOWER_TYPE:
- FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
- return NULL;
- default:
- FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
- return NULL;
- }
-
- /* Reverse the Mesh: */
- for (Row = 0; Row < VLength; Row++)
- for (Col = 0; Col < ULength; Col++)
- for (i = IsNotRational; i <= MaxCoord; i++)
- RevPoints[i][Col * VLength + Row] =
- Points[i][Row * ULength + Col];
-
- /* Swap the U and the V knot vectors if the exists: */
- if (Srf -> GType == CAGD_SBSPLINE_TYPE) {
- SWAP(CagdRType *,
- ReversedSrf -> UKnotVector, ReversedSrf -> VKnotVector);
- }
-
- /* And swap the orders and lengths. */
- SWAP(int, ReversedSrf -> UOrder, ReversedSrf -> VOrder);
- SWAP(int, ReversedSrf -> ULength, ReversedSrf -> VLength);
-
- return ReversedSrf;
- }
-