/****************************************************************************** * CagdRuld.c - Ruled srf operator out of given two profiles. * ******************************************************************************* * Written by Gershon Elber, May. 91. * ******************************************************************************/ #ifdef __MSDOS__ #include #include #include #endif /* __MSDOS__ */ #include "cagd_loc.h" /****************************************************************************** * Constructs a ruled surface between the two provided curves. The two curves * * must have the same number of points, same curve type and same point type. * * OtherOrder and OtherLen (equal for Bezier) specifies teh desired order and * * refineness level (if Bspline) of the other ruled direction. * ******************************************************************************/ CagdSrfStruct *CagdRuledSrf(CagdCrvStruct *Crv1, CagdCrvStruct *Crv2, int OtherOrder, int OtherLen) { CagdSrfStruct *Srf; int i, j, k, MaxCoord, Len; CagdPointType PType; CagdBType IsNotRational; CagdRType **SrfPoints, *Crv1SrcPt, *Crv2SrcPt, *SrfDestPt, t, t1, **Crv1Points, **Crv2Points; Crv1 = CagdCrvCopy( Crv1 ); Crv2 = CagdCrvCopy( Crv2 ); CagdMakeCrvsCompatible(&Crv1, &Crv2, TRUE, TRUE ); MaxCoord = CAGD_NUM_OF_PT_COORD(Crv1 -> PType), Len = Crv1 -> Length; PType = Crv1 -> PType; IsNotRational = !CAGD_IS_RATIONAL_CRV(Crv1); Crv1Points = Crv1 -> Points, Crv2Points = Crv2 -> Points; switch (Crv1 -> GType) { case CAGD_CBEZIER_TYPE: Srf = BzrSrfNew(Len, OtherLen, PType); break; case CAGD_CBSPLINE_TYPE: Srf = BspSrfNew(Len, OtherLen, Crv1 -> Order, OtherOrder, PType); GEN_COPY(Srf -> UKnotVector, Crv1 -> KnotVector, sizeof(CagdRType) * (Len + Crv1 -> Order)); BspKnotUniformOpen(OtherLen, OtherOrder, Srf -> VKnotVector); break; case CAGD_CPOWER_TYPE: FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT); return NULL; default: FATAL_ERROR(CAGD_ERR_UNDEF_CRV); return NULL; } /* Copy the control mesh - first row is exactly the same as the first */ /* curve while last row is the same as second curve. */ /* The middle rows are convex blend of the first/last rows. */ SrfPoints = Srf -> Points; for (i = IsNotRational; i <= MaxCoord; i++) /* First row. */ GEN_COPY(SrfPoints[i], Crv1Points[i], sizeof(CagdRType) * Len); /* Make a copy of the last row. */ for (i = IsNotRational; i <= MaxCoord; i++) /* Last row. */ GEN_COPY(&SrfPoints[i][Len * (OtherLen - 1)], Crv2Points[i], sizeof(CagdRType) * Len); /* And compute the internal rows, if any: */ for (j = 1; j < OtherLen - 1; j++) { t = ((CagdRType) j) / (OtherLen - 1); t1 = 1.0 - t; for (i = IsNotRational; i <= MaxCoord; i++) { SrfDestPt = &SrfPoints[i][Len * j]; Crv1SrcPt = Crv1Points[i]; Crv2SrcPt = Crv2Points[i]; for (k = 0; k < Len; k++) SrfDestPt[k] = t1 * Crv1SrcPt[k] + t * Crv2SrcPt[k]; } } CagdCrvFree( Crv1 ); CagdCrvFree( Crv2 ); return Srf; }