home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- * CagdCoer.c - Handle point coercesions/conversions. *
- *******************************************************************************
- * Written by Gershon Elber, Aug. 90. *
- ******************************************************************************/
-
- #include "cagd_loc.h"
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Coerce Srf/Crv Point from index Index of Points array of Type PType to a M
- * point type E2. M
- * If however Index < 0 Points is considered single point. M
- * *
- * PARAMETERS: M
- * E2Point: Where the coerced information is to besaved. M
- * Points: Array of vectors if Index >= 0, a single point if Index < 0. M
- * Index: Index into the vectors of Points. M
- * PType: Point type to be expected from Points. M
- * *
- * RETURN VALUE: M
- * void M
- * *
- * KEYWORDS: M
- * CagdCoerceToE2, coercion M
- *****************************************************************************/
- void CagdCoerceToE2(CagdRType *E2Point,
- CagdRType *Points[CAGD_MAX_PT_SIZE],
- int Index,
- CagdPointType PType)
- {
- CagdBType
- IsRational = CAGD_IS_RATIONAL_PT(PType);
- int i,
- MaxCoord = CAGD_NUM_OF_PT_COORD(PType);
- CagdRType *Point;
-
- if (MaxCoord > 2)
- MaxCoord = 2;
-
- if (Index < 0) { /* Points is one single point. */
- Point = *Points;
- for (i = 1; i <= MaxCoord; i++)
- *E2Point++ = IsRational ? Point[i] / Point[W] : Point[i];
- }
- else /* Points is a full arrays from Srf or Crv. */
- for (i = 1; i <= MaxCoord; i++)
- *E2Point++ = IsRational ? Points[i][Index] / Points[W][Index] :
- Points[i][Index];
-
- for (i = MaxCoord + 1; i <= 2; i++)
- *E2Point++ = 0.0;
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Coerce Srf/Crv Point from index Index of Points array of Type PType to a M
- * point type E3. M
- * If however Index < 0 Points is considered single point. M
- * *
- * PARAMETERS: M
- * E3Point: Where the coerced information is to besaved. M
- * Points: Array of vectors if Index >= 0, a single point if Index < 0. M
- * Index: Index into the vectors of Points. M
- * PType: Point type to be expected from Points. M
- * *
- * RETURN VALUE: M
- * void M
- * *
- * KEYWORDS: M
- * CagdCoerceToE3 coercion M
- *****************************************************************************/
- void CagdCoerceToE3(CagdRType *E3Point,
- CagdRType *Points[CAGD_MAX_PT_SIZE],
- int Index,
- CagdPointType PType)
- {
- CagdBType
- IsRational = CAGD_IS_RATIONAL_PT(PType);
- int i,
- MaxCoord = CAGD_NUM_OF_PT_COORD(PType);
- CagdRType *Point;
-
- if (MaxCoord > 3)
- MaxCoord = 3;
-
- if (Index < 0) { /* Points is one single point. */
- Point = *Points;
- for (i = 1; i <= MaxCoord; i++)
- *E3Point++ = IsRational ? Point[i] / Point[W] : Point[i];
- }
- else /* Points is a full arrays from Srf or Crv. */
- for (i = 1; i <= MaxCoord; i++)
- *E3Point++ = IsRational ? Points[i][Index] / Points[W][Index] :
- Points[i][Index];
-
- for (i = MaxCoord + 1; i <= 3; i++)
- *E3Point++ = 0.0;
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Coerce Srf/Crv Point from index Index of Points array of Type PType to a M
- * point type P2. M
- * If however Index < 0 Points is considered single point. M
- * *
- * PARAMETERS: M
- * P2Point: Where the coerced information is to besaved. M
- * Points: Array of vectors if Index >= 0, a single point if Index < 0. M
- * Index: Index into the vectors of Points. M
- * PType: Point type to be expected from Points. M
- * *
- * RETURN VALUE: M
- * void M
- * *
- * KEYWORDS: M
- * CagdCoerceToP2, coercion M
- *****************************************************************************/
- void CagdCoerceToP2(CagdRType *P2Point,
- CagdRType *Points[CAGD_MAX_PT_SIZE],
- int Index,
- CagdPointType PType)
- {
- CagdBType
- IsRational = CAGD_IS_RATIONAL_PT(PType);
- int i,
- MaxCoord = CAGD_NUM_OF_PT_COORD(PType);
- CagdRType *Point;
-
- if (MaxCoord > 2)
- MaxCoord = 2;
-
- if (Index < 0) { /* Points is one single point. */
- Point = *Points;
- *P2Point++ = IsRational ? Point[W] : 1.0;
- for (i = 1; i <= MaxCoord; i++)
- *P2Point++ = Point[i];
- }
- else { /* Points is a full arrays from Srf or Crv. */
- *P2Point++ = IsRational ? Points[W][Index] : 1.0;
- for (i = 1; i <= MaxCoord; i++)
- *P2Point++ = Points[i][Index];
- }
-
- for (i = MaxCoord + 1; i <= 2; i++)
- *P2Point++ = 0.0;
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Coerce Srf/Crv Point from index Index of Points array of Type PType to a M
- * point type P3. M
- * If however Index < 0 Points is considered single point. M
- * *
- * PARAMETERS: M
- * P3Point: Where the coerced information is to besaved. M
- * Points: Array of vectors if Index >= 0, a single point if Index < 0. M
- * Index: Index into the vectors of Points. M
- * PType: Point type to be expected from Points. M
- * *
- * RETURN VALUE: M
- * void M
- * *
- * KEYWORDS: M
- * CagdCoerceToP3, coercion M
- *****************************************************************************/
- void CagdCoerceToP3(CagdRType *P3Point,
- CagdRType *Points[CAGD_MAX_PT_SIZE],
- int Index,
- CagdPointType PType)
- {
- CagdBType
- IsRational = CAGD_IS_RATIONAL_PT(PType);
- int i,
- MaxCoord = CAGD_NUM_OF_PT_COORD(PType);
- CagdRType *Point;
-
- if (MaxCoord > 3)
- MaxCoord = 3;
-
- if (Index < 0) { /* Points is one single point. */
- Point = *Points;
- *P3Point++ = IsRational ? Point[W] : 1.0;
- for (i = 1; i <= MaxCoord; i++)
- *P3Point++ = Point[i];
- }
- else { /* Points is a full arrays from Srf or Crv. */
- *P3Point++ = IsRational ? Points[W][Index] : 1.0;
- for (i = 1; i <= MaxCoord; i++)
- *P3Point++ = Points[i][Index];
- }
-
- for (i = MaxCoord + 1; i <= 3; i++)
- *P3Point++ = 0.0;
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Coerces Srf/Crv Point from index Index of Points array of Type PType to a M
- * new type NewPType. If however Index < 0 Points is considered single point. M
- * *
- * PARAMETERS: M
- * NewPoint: Where the coerced information is to besaved. M
- * NewPType: Point type of the coerced new point. M
- * Points: Array of vectors if Index >= 0, a single point if Index < 0. M
- * Index: Index into the vectors of Points. M
- * OldPType: Point type to be expected from Points. M
- * *
- * RETURN VALUE: M
- * void M
- * *
- * KEYWORDS: M
- * CagdCoercePointTo, coercion M
- *****************************************************************************/
- void CagdCoercePointTo(CagdRType *NewPoint,
- CagdPointType NewPType,
- CagdRType *Points[CAGD_MAX_PT_SIZE],
- int Index,
- CagdPointType OldPType)
- {
- CagdBType
- IsRational = CAGD_IS_RATIONAL_PT(OldPType),
- NewIsRational = CAGD_IS_RATIONAL_PT(NewPType);
- int i,
- MaxCoord = CAGD_NUM_OF_PT_COORD(OldPType),
- NewMaxCoord = CAGD_NUM_OF_PT_COORD(NewPType);
- CagdRType *Point, Weight;
-
- if (MaxCoord > NewMaxCoord)
- MaxCoord = NewMaxCoord;
-
- if (Index < 0) { /* Points is one single point. */
- Point = *Points;
- Weight = IsRational ? Point[W] : 1.0;
- if (NewIsRational) {
- *NewPoint++ = Weight;
- Weight = 1.0;
- }
- for (i = 1; i <= MaxCoord; i++)
- *NewPoint++ = Point[i] / Weight;
- }
- else { /* Points is a full arrays from Srf or Crv. */
- Weight = IsRational ? Points[W][Index] : 1.0;
- if (NewIsRational) {
- *NewPoint++ = Weight;
- Weight = 1.0;
- }
- for (i = 1; i <= MaxCoord; i++)
- *NewPoint++ = Points[i][Index] / Weight;
- }
-
- for (i = MaxCoord + 1; i <= NewMaxCoord; i++)
- *NewPoint++ = 0.0;
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Coerces an array of vectors, Points. of point type OldPType to point type M
- * NewPType, in place. M
- * *
- * PARAMETERS: M
- * Points: Where the old and new points are placed. M
- * Len: Length of vectors in the array of vectors, Points. M
- * OldPType: Point type to be expected from Points. M
- * NewPType: Point type of the coerced new point. M
- * *
- * RETURN VALUE: M
- * void M
- * M
- * KEYWORDS: M
- * CagdCoercePointsTo, coercion M
- *****************************************************************************/
- void CagdCoercePointsTo(CagdRType *Points[],
- int Len,
- CagdPointType OldPType,
- CagdPointType NewPType)
- {
- int i, j,
- OldIsRational = CAGD_IS_RATIONAL_PT(OldPType),
- OldNumOfCoords = CAGD_NUM_OF_PT_COORD(OldPType),
- NewIsRational = CAGD_IS_RATIONAL_PT(NewPType),
- NewNumOfCoords = CAGD_NUM_OF_PT_COORD(NewPType);
- CagdRType *NewPoints[CAGD_MAX_PT_SIZE], Pt[CAGD_MAX_PT_SIZE];
-
- for (i = !NewIsRational; i <= NewNumOfCoords; i++)
- NewPoints[i] = (CagdRType *) IritMalloc(sizeof(CagdRType) * Len);
-
- for (i = 0; i < Len; i++) {
- CagdCoercePointTo(Pt, NewPType, Points, i, OldPType);
-
- if (NewIsRational)
- for (j = 0; j <= NewNumOfCoords; j++)
- NewPoints[j][i] = Pt[j];
- else
- for (j = 1; j <= NewNumOfCoords; j++)
- NewPoints[j][i] = Pt[j - 1];
- }
-
- /* Replace old rep. with new. */
- for (i = !OldIsRational; i <= OldNumOfCoords; i++)
- IritFree((VoidPtr) Points[i]);
- Points[0] = NULL;
- for (i = !NewIsRational; i <= NewNumOfCoords; i++)
- Points[i] = NewPoints[i];
- for (; i <= CAGD_MAX_PT_COORD; i++)
- Points[i] = NULL;
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Coerces a curve to a new point type PType. If given curve is E1 or P1 M
- * and requested new type is E2 or P2 the Y coefficients are updated to M
- * hold the parametric domain of the curve. M
- * *
- * PARAMETERS: M
- * Crv: To be coerced to a new point type PType. M
- * PType: New point type for Crv. M
- * *
- * RETURN VALUE: M
- * CagdCrvStruct *: The new, coerced to PType, curve. M
- * *
- * KEYWORDS: M
- * CagdCoerceCrvTo, coercion M
- *****************************************************************************/
- CagdCrvStruct *CagdCoerceCrvTo(CagdCrvStruct *Crv, CagdPointType PType)
- {
- Crv = CagdCrvCopy(Crv);
- CagdCoercePointsTo(Crv -> Points, Crv -> Length, Crv -> PType, PType);
-
- if (CAGD_NUM_OF_PT_COORD(Crv -> PType) == 1 &&
- CAGD_NUM_OF_PT_COORD(PType) == 2) {
- /* Update the parameter space to be the second axis. */
- CagdRType
- *WPts = Crv -> Points[0],
- *Pts = Crv -> Points[2],
- *Nodes = CagdCrvNodes(Crv);
-
- CAGD_GEN_COPY(Pts, Nodes, sizeof(CagdRType) * Crv -> Length);
- if (WPts != NULL) {
- int i;
-
- for (i = 0; i < Crv -> Length; i++)
- *Pts++ *= *WPts++;
- }
-
- IritFree((VoidPtr) Nodes);
- }
-
- Crv -> PType = PType;
-
- return Crv;
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Coerces a surface to a new point type PType. If given surface is E1 or P1 M
- * and requested new type is E3 or P3 the Y and Z coefficients are updated to M
- * hold the parametric domain of the surface. M
- * *
- * PARAMETERS: M
- * Srf: To be coerced to a new point type PType. M
- * PType: New point type for Srf. M
- * *
- * RETURN VALUE: M
- * CagdSrfStruct *: The new, coerced to PType, surface. M
- * *
- * KEYWORDS: M
- * CagdCoerceSrfTo, coercion M
- *****************************************************************************/
- CagdSrfStruct *CagdCoerceSrfTo(CagdSrfStruct *Srf, CagdPointType PType)
- {
- Srf = CagdSrfCopy(Srf);
- CagdCoercePointsTo(Srf -> Points, Srf -> ULength * Srf -> VLength,
- Srf -> PType, PType);
-
- if (CAGD_NUM_OF_PT_COORD(Srf -> PType) == 1 &&
- CAGD_NUM_OF_PT_COORD(PType) == 3) {
- /* Update the parameter space to be the second and third axis. */
- int i;
- CagdRType *PtsY, *PtsZ,
- *WPts = Srf -> Points[0],
- *UNodes = CagdSrfNodes(Srf, CAGD_CONST_U_DIR),
- *VNodes = CagdSrfNodes(Srf, CAGD_CONST_V_DIR);
-
- for (i = 0, PtsY = Srf -> Points[2];
- i < Srf -> VLength;
- i++, PtsY += Srf -> ULength)
- CAGD_GEN_COPY(PtsY, UNodes, sizeof(CagdRType) * Srf -> ULength);
-
- for (i = 0, PtsZ = Srf -> Points[3]; i < Srf -> VLength; i++) {
- int j;
-
- for (j = 0; j < Srf -> ULength; j++)
- *PtsZ++ = VNodes[i];
- }
-
- if (WPts != NULL) {
- PtsY = Srf -> Points[2];
- PtsZ = Srf -> Points[3];
- for (i = 0; i < Srf -> ULength * Srf -> VLength; i++) {
- *PtsY++ *= *WPts;
- *PtsZ++ *= *WPts++;
-
- }
- }
-
- IritFree((VoidPtr) UNodes);
- IritFree((VoidPtr) VNodes);
- }
-
- Srf -> PType = PType;
- return Srf;
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Returns a point type which spans the spaces of both two given point types. M
- * *
- * PARAMETERS: M
- * PType1, PType2: To point types to find the point type of their union. M
- * *
- * RETURN VALUE: M
- * CagdPointType: A point type of the union of the spaces of PType1 and M
- * PType2. M
- * *
- * KEYWORDS: M
- * CagdMergePointType, coercion M
- *****************************************************************************/
- CagdPointType CagdMergePointType(CagdPointType PType1, CagdPointType PType2)
- {
- CagdBType
- IsRational = CAGD_IS_RATIONAL_PT(PType1) || CAGD_IS_RATIONAL_PT(PType2);
- int NumCoords = MAX(CAGD_NUM_OF_PT_COORD(PType1),
- CAGD_NUM_OF_PT_COORD(PType2));
-
- return CAGD_MAKE_PT_TYPE(IsRational, NumCoords);
- }
-