home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- * CagdCmpt.c - Make objects compatible. *
- *******************************************************************************
- * Written by Gershon Elber, Sep. 91. *
- ******************************************************************************/
-
- #ifdef __MSDOS__
- #include <stdlib.h>
- #include <string.h>
- #include <alloc.h>
- #endif /* __MSDOS__ */
-
- #include "cagd_loc.h"
-
- /******************************************************************************
- * Given two curves, make the compatible by: *
- * 1. Coercing their point type to be the same. *
- * 2. Make them have the same curve type. *
- * 3. Raising the degree of the lower one to be the same. *
- * 4. Refine them to a common knot vector (If Bspline). *
- * Note 3 is preformed if SameOrder TRUE, 4 if SameKV TRUE. *
- * Returns TRUE if succesfull. Both Curves are modified IN PLACE. *
- ******************************************************************************/
- CagdBType CagdMakeCrvsCompatible(CagdCrvStruct **Crv1, CagdCrvStruct **Crv2,
- CagdBType SameOrder, CagdBType SameKV)
- {
- int i, KV1Len, KV2Len, RefLen;
- CagdRType *KV1, *KV2, *RefKV;
- CagdCrvStruct *TCrv;
- CagdPointType
- CommonPType = CagdMergePointType((*Crv1) -> PType, (*Crv2) -> PType);
-
- /* Make the point types compatible. */
- if (CommonPType != (*Crv1) -> PType) {
- TCrv = CagdCoerceCrvTo(*Crv1, CommonPType);
- CagdCrvFree(*Crv1);
- *Crv1 = TCrv;
- }
- if (CommonPType != (*Crv2) -> PType) {
- TCrv = CagdCoerceCrvTo(*Crv2, CommonPType);
- CagdCrvFree(*Crv2);
- *Crv2 = TCrv;
- }
-
- /* If incompatible curve type - make it the same as well. */
- if ((*Crv1) -> GType != (*Crv2) -> GType) {
- /* If power basis - promote to bezier: */
- if ((*Crv1) -> GType == CAGD_CPOWER_TYPE) {
- TCrv = CnvrtPower2BezierCrv(*Crv1);
- CagdCrvFree(*Crv1);
- *Crv1 = TCrv;
- }
- if ((*Crv2) -> GType == CAGD_CPOWER_TYPE) {
- TCrv = CnvrtPower2BezierCrv(*Crv2);
- CagdCrvFree(*Crv2);
- *Crv2 = TCrv;
- }
-
- /* Now both curves may be either bezier or bspline curves. */
- if ((*Crv1) -> GType != (*Crv2) -> GType) {
- /* If bezier basis - promote to bspline: */
- if ((*Crv1) -> GType == CAGD_CBEZIER_TYPE) {
- TCrv = CnvrtBezier2BsplineCrv(*Crv1);
- CagdCrvFree(*Crv1);
- *Crv1 = TCrv;
- }
- if ((*Crv2) -> GType == CAGD_CBEZIER_TYPE) {
- TCrv = CnvrtBezier2BsplineCrv(*Crv2);
- CagdCrvFree(*Crv2);
- *Crv2 = TCrv;
- }
-
- }
- }
-
- if (SameOrder) {
- /* Raise the degree of the lower one. */
- for (i = (*Crv1) -> Order; i < (*Crv2) -> Order; i++) {
- TCrv = CagdCrvDegreeRaise(*Crv1);
- CagdCrvFree(*Crv1);
- *Crv1 = TCrv;
- }
- for (i = (*Crv2) -> Order; i < (*Crv1) -> Order; i++) {
- TCrv = CagdCrvDegreeRaise(*Crv2);
- CagdCrvFree(*Crv2);
- *Crv2 = TCrv;
- }
- }
-
- if (SameKV) {
- /* If bspline curve - make sure knot vectors are the same. */
- if ((*Crv1) -> GType == CAGD_CBSPLINE_TYPE) {
- KV1 = (*Crv1) -> KnotVector;
- KV2 = (*Crv2) -> KnotVector;
- KV1Len = (*Crv1) -> Length + (*Crv1) -> Order;
- KV2Len = (*Crv2) -> Length + (*Crv2) -> Order;
-
- /* Affine map second knot vector to span same parametric domain. */
- BspKnotAffineTrans(KV2, KV2Len, KV1[0] - KV2[0],
- (KV1[KV1Len - 1] - KV1[0]) /
- (KV2[KV2Len - 1] - KV2[0]));
-
- /* Find knots in KV2 which are not in KV1 and refine Crv1 there. */
- RefKV = BspKnotSubtrTwo(KV2, KV2Len, KV1, KV1Len, &RefLen);
- if (RefLen > 0) {
- TCrv = CagdCrvRefineAtParams(*Crv1, FALSE, RefKV, RefLen);
- CagdCrvFree(*Crv1);
- *Crv1 = TCrv;
- KV1 = (*Crv1) -> KnotVector;
- KV1Len = (*Crv1) -> Length + (*Crv1) -> Order;
- }
- CagdFree((VoidPtr) RefKV);
-
- /* Find knots in KV1 which are not in KV2 and refine Crv2 there. */
- RefKV = BspKnotSubtrTwo(KV1, KV1Len, KV2, KV2Len, &RefLen);
- if (RefLen > 0) {
- TCrv = CagdCrvRefineAtParams(*Crv2, FALSE, RefKV, RefLen);
- CagdCrvFree(*Crv2);
- *Crv2 = TCrv;
- }
- CagdFree((VoidPtr) RefKV);
- }
- }
-
- return TRUE;
- }
-