/****************************************************************************** * CagdCSrf.c - Constructa surface using a set of curves. * ******************************************************************************* * Written by Gershon Elber, Sep. 91. * ******************************************************************************/ #ifdef __MSDOS__ #include #include #include #endif /* __MSDOS__ */ #include "cagd_loc.h" /****************************************************************************** * Constructs a surface using a set of curves. Curves are made to be * * compatible and then each is substituted in the resulting surface as a row. * * Other direction order is at most the compatible curves order. If order is * * less than number of curves a knot vector is formed uniformly (open end). * ******************************************************************************/ CagdSrfStruct *CagdSrfFromCrvs(CagdCrvStruct *CrvList) { CagdBType IsNotRational; int i, j, NumCrvs, UOrder, VOrder, MaxCoord, Length; CagdRType **SrfPoints; CagdCrvStruct *Crv, **CrvVec; CagdSrfStruct *Srf; /* Find out how many curves we have and put them in a linear vector. */ /* Note the vector have a COPY of the curves so we can modify them. */ for (NumCrvs = 0, Crv = CrvList; Crv != NULL; NumCrvs++, Crv = Crv -> Pnext); CrvVec = (CagdCrvStruct **) CagdMalloc(sizeof(CagdCrvStruct *) * NumCrvs); for (i = 0, Crv = CrvList; i < NumCrvs; i++, Crv = Crv -> Pnext) CrvVec[i] = CagdCrvCopy(Crv); /* Traverse vector in a O(n^2) fashion and make all curves compatible. */ for (i = 0; i < NumCrvs - 1; i++) for (j = i + 1; j < NumCrvs; j++) CagdMakeCrvsCompatible(&CrvVec[i], &CrvVec[j], TRUE, TRUE); /* Construct the surface. All required information is now available. */ UOrder = CrvVec[0] -> Order; VOrder = MIN(NumCrvs, UOrder); if (NumCrvs == VOrder && CrvVec[0] -> GType == CAGD_CBEZIER_TYPE) { /* Allocate a bezier surface. */ Srf = BzrSrfNew(CrvVec[0] -> Length, NumCrvs, CrvVec[0] -> PType); } else { /* Allocate a bspline surface. */ Srf = BspSrfNew(CrvVec[0] -> Length, NumCrvs, UOrder, VOrder, CrvVec[0] -> PType); CagdFree((VoidPtr) Srf -> UKnotVector); Srf -> UKnotVector = BspKnotCopy(CrvVec[0] -> KnotVector, CrvVec[0] -> Length + CrvVec[0] -> Order); BspKnotUniformOpen(NumCrvs, VOrder, Srf -> VKnotVector); } /* Substitute each curve as a row into the surface mesh and delete it. */ SrfPoints = Srf -> Points; i = 0; MaxCoord = CAGD_NUM_OF_PT_COORD(CrvVec[0] -> PType), IsNotRational = !CAGD_IS_RATIONAL_CRV(CrvVec[0]); Length = CrvVec[0] -> Length; for (j = 0; j < NumCrvs; j++) { int k; CagdRType **CrvPoints = CrvVec[j] -> Points; for (k = IsNotRational; k <= MaxCoord; k++) GEN_COPY(&SrfPoints[k][i], CrvPoints[k], sizeof(CagdRType) * Length); CagdCrvFree(CrvVec[j]); i += Length; } CagdFree((VoidPtr) CrvVec); return Srf; }