/******************************************************************************
* CagdMorp.c - A simple too to morph between two compatible surfaces.	      *
*******************************************************************************
* Written by Gershon Elber, Jul. 92.					      *
******************************************************************************/

#include "cagd_loc.h"

/******************************************************************************
* Given two compatible surfaces (See CagdmakeSrfsCompatible), computes a      *
* convex blend between them according Blend which must be between 0 and 1.    *
* Returned in the new blended surfaces.					      *
******************************************************************************/
CagdSrfStruct *CagdTwoSrfsMorphing(CagdSrfStruct *Srf1, CagdSrfStruct *Srf2,
								CagdRType Blend)
{
    int i, j,
	MaxAxis = CAGD_NUM_OF_PT_COORD(Srf1 -> PType),
	ULength = Srf1 -> ULength,
	VLength = Srf1 -> VLength,
	UOrder = Srf1 -> UOrder,
	VOrder = Srf1 -> VOrder;
    CagdRType **NewPoints,
	**Points1 = Srf1 -> Points,
	**Points2 = Srf2 -> Points,
	Blend1 = 1.0 - Blend;
    CagdSrfStruct *NewSrf;

    if (Srf1 -> PType != Srf2 -> PType ||
	Srf1 -> GType != Srf2 -> GType ||
	UOrder != Srf2 -> UOrder ||
	VOrder != Srf2 -> VOrder ||
	ULength != Srf2 -> ULength ||
	VLength != Srf2 -> VLength) {
	FATAL_ERROR(CAGD_ERR_SRFS_INCOMPATIBLE);
	return NULL;
    }
	
    NewSrf = CagdSrfNew(Srf1 -> GType, Srf1 -> PType, ULength, VLength);
    NewSrf -> UOrder = UOrder;
    NewSrf -> VOrder = VOrder;
    NewPoints = NewSrf -> Points;
    if (Srf1 -> UKnotVector != NULL)
	NewSrf -> UKnotVector = BspKnotCopy(Srf1 -> UKnotVector,
					    ULength + UOrder);
    if (Srf1 -> VKnotVector != NULL)
	NewSrf -> VKnotVector = BspKnotCopy(Srf1 -> VKnotVector,
					    VLength + VOrder);

    for (i = !CAGD_IS_RATIONAL_PT(Srf1 -> PType); i <= MaxAxis; i++) {
	CagdRType
	    *Pts1 = &Points1[i][0],
	    *Pts2 = &Points2[i][0],
	    *NewPts = &NewPoints[i][0];

	for (j = ULength * VLength - 1; j >= 0; j--)
	    *NewPts++ = *Pts1++ * Blend1 + *Pts2++ * Blend;
    }

    return NewSrf;

}
