home *** CD-ROM | disk | FTP | other *** search
/ 3D GFX / 3D GFX.iso / amiutils / i_l / irit5 / cagd_lib / cagdcmpt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-12-31  |  12.7 KB  |  355 lines

  1. /******************************************************************************
  2. * CagdCmpt.c - Make objects compatible.                          *
  3. *******************************************************************************
  4. * Written by Gershon Elber, Sep. 91.                          *
  5. ******************************************************************************/
  6.  
  7. #include "cagd_loc.h"
  8.  
  9. /*****************************************************************************
  10. * DESCRIPTION:                                                               M
  11. * Given two curves, makes them compatible by:                     M
  12. * 1. Coercing their point type to be the same.                     M
  13. * 2. Making them have the same curve type.                     M
  14. * 3. Raising the degree of the lower one to be the same as the higher.         M
  15. * 4. Refining them to a common knot vector (If Bspline and SameOrder).         M
  16. *                                         M
  17. * Note 3 is performed if SameOrder TRUE, 4 if SameKV TRUE.             M
  18. * Both curves are modified IN PLACE.                         M
  19. *                                                                            *
  20. * PARAMETERS:                                                                M
  21. *   Crv1, Crv2:  Two curves to be made compatible, in place.                 M
  22. *   SameOrder:   If TRUE, this routine make sure they share the same order.  M
  23. *   SameKV:      If TRUE, this routine make sure they share the same         M
  24. *                knot vector and hence continuity.                           *
  25. *                                                                            *
  26. * RETURN VALUE:                                                              M
  27. *   CagdBType:   TRUE if successful, FALSE otherwise.                        M
  28. *                                                                            *
  29. * KEYWORDS:                                                                  M
  30. *   CagdMakeCrvsCompatible, compatibility                                    M
  31. *****************************************************************************/
  32. CagdBType CagdMakeCrvsCompatible(CagdCrvStruct **Crv1,
  33.                  CagdCrvStruct **Crv2,
  34.                  CagdBType SameOrder,
  35.                  CagdBType SameKV)
  36. {
  37.     int KV1Len, KV2Len, RefLen;
  38.     CagdRType *KV1, *KV2, *RefKV;
  39.     CagdCrvStruct *TCrv;
  40.     CagdPointType CommonPType;
  41.  
  42.     if ((*Crv1 == NULL) || (*Crv2 == NULL))
  43.     return TRUE;
  44.  
  45.     CommonPType = CagdMergePointType((*Crv1) -> PType, (*Crv2) -> PType);
  46.  
  47.     if (CAGD_IS_PERIODIC_CRV(*Crv1) != CAGD_IS_PERIODIC_CRV(*Crv2))
  48.     return FALSE;
  49.  
  50.     /* Make the point types compatible. */
  51.     if (CommonPType != (*Crv1) -> PType) {
  52.     TCrv = CagdCoerceCrvTo(*Crv1, CommonPType);
  53.     CagdCrvFree(*Crv1);
  54.     *Crv1 = TCrv;
  55.     }
  56.     if (CommonPType != (*Crv2) -> PType) {
  57.     TCrv = CagdCoerceCrvTo(*Crv2, CommonPType);
  58.     CagdCrvFree(*Crv2);
  59.     *Crv2 = TCrv;
  60.     }
  61.  
  62.     if (SameOrder) {
  63.     /* Raise the degree of the lower one. */
  64.     if ((*Crv1) -> Order < (*Crv2) -> Order) {
  65.         TCrv = CagdCrvDegreeRaiseN(*Crv1, (*Crv2) -> Order);
  66.         CagdCrvFree(*Crv1);
  67.         *Crv1 = TCrv;
  68.     }
  69.     else if ((*Crv2) -> Order < (*Crv1) -> Order) {
  70.         TCrv = CagdCrvDegreeRaiseN(*Crv2, (*Crv1) -> Order);
  71.         CagdCrvFree(*Crv2);
  72.         *Crv2 = TCrv;
  73.     }
  74.     }
  75.  
  76.     /* If incompatible curve type - make it the same as well. */
  77.     if ((*Crv1) -> GType != (*Crv2) -> GType) {
  78.     /* If power basis - promote to bezier: */
  79.     if ((*Crv1) -> GType == CAGD_CPOWER_TYPE) {
  80.         TCrv = CnvrtPower2BezierCrv(*Crv1);
  81.         CagdCrvFree(*Crv1);
  82.         *Crv1 = TCrv;
  83.     }
  84.     if ((*Crv2) -> GType == CAGD_CPOWER_TYPE) {
  85.         TCrv = CnvrtPower2BezierCrv(*Crv2);
  86.         CagdCrvFree(*Crv2);
  87.         *Crv2 = TCrv;
  88.     }
  89.  
  90.     /* Now both curves may be either bezier or bspline curves. */
  91.     if ((*Crv1) -> GType != (*Crv2) -> GType) {
  92.         /* If bezier basis - promote to bspline: */
  93.         if ((*Crv1) -> GType == CAGD_CBEZIER_TYPE) {
  94.         TCrv = CnvrtBezier2BsplineCrv(*Crv1);
  95.         CagdCrvFree(*Crv1);
  96.         *Crv1 = TCrv;
  97.         }
  98.         if ((*Crv2) -> GType == CAGD_CBEZIER_TYPE) {
  99.         TCrv = CnvrtBezier2BsplineCrv(*Crv2);
  100.         CagdCrvFree(*Crv2);
  101.         *Crv2 = TCrv;
  102.         }
  103.     }
  104.     }
  105.  
  106.     if (SameKV && SameOrder) {
  107.     /* If bspline curve - make sure knot vectors are the same. */
  108.     if ((*Crv1) -> GType == CAGD_CBSPLINE_TYPE) {
  109.         int Order = (*Crv1) -> Order;
  110.  
  111.         KV1 = (*Crv1) -> KnotVector;
  112.         KV2 = (*Crv2) -> KnotVector;
  113.         KV1Len = CAGD_CRV_PT_LST_LEN(*Crv1) + Order;
  114.         KV2Len = CAGD_CRV_PT_LST_LEN(*Crv2) + Order;
  115.  
  116.         /* Affine map second knot vector to span same parametric domain. */
  117.         BspKnotAffineTrans(KV2, KV2Len, KV1[Order - 1] - KV2[Order - 1],
  118.                    (KV1[KV1Len - Order] - KV1[Order - 1]) /
  119.                    (KV2[KV2Len - Order] - KV2[Order - 1]));
  120.  
  121.         /* Find knots in KV2 which are not in KV1 and refine Crv1 there. */
  122.         RefKV  = BspKnotSubtrTwo(&KV2[Order - 1], KV2Len - Order * 2 + 2,
  123.                      &KV1[Order - 1], KV1Len - Order * 2 + 2,
  124.                      &RefLen);
  125.         if (RefLen > 0) {
  126.         TCrv = CagdCrvRefineAtParams(*Crv1, FALSE, RefKV, RefLen);
  127.         CagdCrvFree(*Crv1);
  128.         *Crv1 = TCrv;
  129.         KV1 = (*Crv1) -> KnotVector;
  130.         KV1Len = (*Crv1) -> Length + (*Crv1) -> Order;
  131.         }
  132.         IritFree((VoidPtr) RefKV);
  133.  
  134.         /* Find knots in KV1 which are not in KV2 and refine Crv2 there. */
  135.         RefKV  = BspKnotSubtrTwo(&KV1[Order - 1], KV1Len - Order * 2 + 2,
  136.                      &KV2[Order - 1], KV2Len - Order * 2 + 2,
  137.                      &RefLen);
  138.         if (RefLen > 0) {
  139.         TCrv = CagdCrvRefineAtParams(*Crv2, FALSE, RefKV, RefLen);
  140.         CagdCrvFree(*Crv2);
  141.         *Crv2 = TCrv;
  142.         }
  143.         IritFree((VoidPtr) RefKV);
  144.     }
  145.     }
  146.  
  147.     return TRUE;
  148. }
  149.  
  150. /*****************************************************************************
  151. * DESCRIPTION:                                                               M
  152. * Given two surfaces, makes them compatible by:                     M
  153. * 1. Coercing their point type to be the same.                     M
  154. * 2. Making them have the same curve type.                     M
  155. * 3. Raising the degree of the lower one to be the same as the higher.         M
  156. * 4. Refining them to a common knot vector (If Bspline and SameOrder).         M
  157. *                                                                            M
  158. * Note 3 is performed if SameOrder TRUE, 4 if SameKV TRUE.             M
  159. * Both surface are modified IN PLACE.                         M
  160. *                                                                            *
  161. * PARAMETERS:                                                                M
  162. *   Srf1, Srf2:  Two surfaces to be made compatible, in place.               M
  163. *   SameUOrder:  If TRUE, this routine make sure they share the same U       M
  164. *                order.                                 M
  165. *   SameVOrder:  If TRUE, this routine make sure they share the same V       M
  166. *                order.                                 M
  167. *   SameUKV:     If TRUE, this routine make sure they share the same U       M
  168. *                knot vector and hence continuity.                           *
  169. *   SameVKV:     If TRUE, this routine make sure they share the same V       M
  170. *                knot vector and hence continuity.                           M
  171. *                                                                            *
  172. * RETURN VALUE:                                                              M
  173. *   CagdBType:   TRUE if successful, FALSE otherwise.                        M
  174. *                                                                            *
  175. * KEYWORDS:                                                                  M
  176. *   CagdMakeSrfsCompatible, compatibility                                    M
  177. *****************************************************************************/
  178. CagdBType CagdMakeSrfsCompatible(CagdSrfStruct **Srf1,
  179.                  CagdSrfStruct **Srf2,
  180.                  CagdBType SameUOrder,
  181.                  CagdBType SameVOrder,
  182.                  CagdBType SameUKV,
  183.                  CagdBType SameVKV)
  184. {
  185.     int i, KV1Len, KV2Len, RefLen;
  186.     CagdRType *KV1, *KV2, *RefKV;
  187.     CagdSrfStruct *TSrf;
  188.     CagdPointType CommonPType;
  189.  
  190.     if ((*Srf1 == NULL) || (*Srf2 == NULL))
  191.     return TRUE;
  192.  
  193.     if (CAGD_IS_UPERIODIC_SRF(*Srf1) != CAGD_IS_UPERIODIC_SRF(*Srf2) ||
  194.     CAGD_IS_VPERIODIC_SRF(*Srf1) != CAGD_IS_VPERIODIC_SRF(*Srf2))
  195.     return FALSE;
  196.  
  197.     CommonPType = CagdMergePointType((*Srf1) -> PType, (*Srf2) -> PType);
  198.  
  199.     /* Make the point types compatible. */
  200.     if (CommonPType != (*Srf1) -> PType) {
  201.     TSrf = CagdCoerceSrfTo(*Srf1, CommonPType);
  202.     CagdSrfFree(*Srf1);
  203.     *Srf1 = TSrf;
  204.     }
  205.     if (CommonPType != (*Srf2) -> PType) {
  206.     TSrf = CagdCoerceSrfTo(*Srf2, CommonPType);
  207.     CagdSrfFree(*Srf2);
  208.     *Srf2 = TSrf;
  209.     }
  210.  
  211.     if (SameUOrder) {
  212.     /* Raise the degree of the lower one. */
  213.     for (i = (*Srf1) -> UOrder; i < (*Srf2) -> UOrder; i++) {
  214.         TSrf = CagdSrfDegreeRaise(*Srf1, CAGD_CONST_V_DIR);
  215.         CagdSrfFree(*Srf1);
  216.         *Srf1 = TSrf;
  217.     }
  218.     for (i = (*Srf2) -> UOrder; i < (*Srf1) -> UOrder; i++) {
  219.         TSrf = CagdSrfDegreeRaise(*Srf2, CAGD_CONST_V_DIR);
  220.         CagdSrfFree(*Srf2);
  221.         *Srf2 = TSrf;
  222.     }
  223.     }
  224.     if (SameVOrder) {
  225.     for (i = (*Srf1) -> VOrder; i < (*Srf2) -> VOrder; i++) {
  226.         TSrf = CagdSrfDegreeRaise(*Srf1, CAGD_CONST_U_DIR);
  227.         CagdSrfFree(*Srf1);
  228.         *Srf1 = TSrf;
  229.     }
  230.     for (i = (*Srf2) -> VOrder; i < (*Srf1) -> VOrder; i++) {
  231.         TSrf = CagdSrfDegreeRaise(*Srf2, CAGD_CONST_U_DIR);
  232.         CagdSrfFree(*Srf2);
  233.         *Srf2 = TSrf;
  234.     }
  235.     }
  236.  
  237.     /* If incompatible surface type - make it the same as well. */
  238.     if ((*Srf1) -> GType != (*Srf2) -> GType) {
  239.     /* If power basis - promote to bezier: */
  240.     if ((*Srf1) -> GType == CAGD_SPOWER_TYPE) {
  241.         TSrf = CnvrtPower2BezierSrf(*Srf1);
  242.         CagdSrfFree(*Srf1);
  243.         *Srf1 = TSrf;
  244.     }
  245.     if ((*Srf2) -> GType == CAGD_SPOWER_TYPE) {
  246.         TSrf = CnvrtPower2BezierSrf(*Srf2);
  247.         CagdSrfFree(*Srf2);
  248.         *Srf2 = TSrf;
  249.     }
  250.  
  251.     /* Now both surfaces may be either bezier or bspline surfaces. */
  252.     if ((*Srf1) -> GType != (*Srf2) -> GType) {
  253.         /* If bezier basis - promote to bspline: */
  254.         if ((*Srf1) -> GType == CAGD_SBEZIER_TYPE) {
  255.         TSrf = CnvrtBezier2BsplineSrf(*Srf1);
  256.         CagdSrfFree(*Srf1);
  257.         *Srf1 = TSrf;
  258.         }
  259.         if ((*Srf2) -> GType == CAGD_SBEZIER_TYPE) {
  260.         TSrf = CnvrtBezier2BsplineSrf(*Srf2);
  261.         CagdSrfFree(*Srf2);
  262.         *Srf2 = TSrf;
  263.         }
  264.     }
  265.     }
  266.  
  267.     if ((*Srf1) -> GType == CAGD_SBSPLINE_TYPE) {
  268.     /* If bspline surface - make sure knot vectors are the same. */
  269.  
  270.     if (SameUKV && SameUOrder) {
  271.         /* Handle the U Direction. */
  272.         int Order = (*Srf1) -> UOrder;
  273.         KV1 = (*Srf1) -> UKnotVector;
  274.         KV2 = (*Srf2) -> UKnotVector;
  275.         KV1Len = CAGD_SRF_UPT_LST_LEN(*Srf1) + Order;
  276.         KV2Len = CAGD_SRF_UPT_LST_LEN(*Srf2) + Order;
  277.  
  278.         /* Affine map second knot vector to span same parametric domain. */
  279.         BspKnotAffineTrans(KV2, KV2Len, KV1[Order - 1] - KV2[Order - 1],
  280.                    (KV1[KV1Len - Order] - KV1[Order - 1]) /
  281.                    (KV2[KV2Len - Order] - KV2[Order - 1]));
  282.  
  283.         /* Find knots in KV2 which are not in KV1 and refine Srf1 there. */
  284.         RefKV  = BspKnotSubtrTwo(&KV2[Order - 1], KV2Len - Order * 2 + 2,
  285.                      &KV1[Order - 1], KV1Len - Order * 2 + 2,
  286.                      &RefLen);
  287.         if (RefLen > 0) {
  288.         TSrf = CagdSrfRefineAtParams(*Srf1, CAGD_CONST_U_DIR,
  289.                          FALSE, RefKV, RefLen);
  290.         CagdSrfFree(*Srf1);
  291.         *Srf1 = TSrf;
  292.         KV1 = (*Srf1) -> UKnotVector;
  293.         KV1Len = (*Srf1) -> ULength + (*Srf1) -> UOrder;
  294.         }
  295.         IritFree((VoidPtr) RefKV);
  296.  
  297.         /* Find knots in KV1 which are not in KV2 and refine Srf2 there. */
  298.         RefKV  = BspKnotSubtrTwo(&KV1[Order - 1], KV1Len - Order * 2 + 2,
  299.                      &KV2[Order - 1], KV2Len - Order * 2 + 2,
  300.                      &RefLen);
  301.         if (RefLen > 0) {
  302.         TSrf = CagdSrfRefineAtParams(*Srf2, CAGD_CONST_U_DIR,
  303.                          FALSE, RefKV, RefLen);
  304.         CagdSrfFree(*Srf2);
  305.         *Srf2 = TSrf;
  306.         }
  307.         IritFree((VoidPtr) RefKV);
  308.     }
  309.  
  310.     if (SameVKV && SameVOrder) {
  311.         /* Handle the V Direction. */
  312.         int Order = (*Srf1) -> VOrder;
  313.  
  314.         KV1 = (*Srf1) -> VKnotVector;
  315.         KV2 = (*Srf2) -> VKnotVector;
  316.         KV1Len = CAGD_SRF_VPT_LST_LEN(*Srf1) + Order;
  317.         KV2Len = CAGD_SRF_VPT_LST_LEN(*Srf2) + Order;
  318.  
  319.         /* Affine map second knot vector to span same parametric domain. */
  320.         BspKnotAffineTrans(KV2, KV2Len, KV1[Order - 1] - KV2[Order - 1],
  321.                    (KV1[KV1Len - Order] - KV1[Order - 1]) /
  322.                    (KV2[KV2Len - Order] - KV2[Order - 1]));
  323.  
  324.         /* Find knots in KV2 which are not in KV1 and refine Srf1 there. */
  325.         RefKV  = BspKnotSubtrTwo(&KV2[Order - 1], KV2Len - Order * 2 + 2,
  326.                      &KV1[Order - 1], KV1Len - Order * 2 + 2,
  327.                      &RefLen);
  328.         if (RefLen > 0) {
  329.         TSrf = CagdSrfRefineAtParams(*Srf1, CAGD_CONST_V_DIR,
  330.                          FALSE, RefKV, RefLen);
  331.         CagdSrfFree(*Srf1);
  332.         *Srf1 = TSrf;
  333.         KV1 = (*Srf1) -> VKnotVector;
  334.         KV1Len = (*Srf1) -> VLength + (*Srf1) -> VOrder;
  335.         }
  336.         IritFree((VoidPtr) RefKV);
  337.  
  338.         /* Find knots in KV1 which are not in KV2 and refine Srf2 there. */
  339.         RefKV  = BspKnotSubtrTwo(&KV1[Order - 1], KV1Len - Order * 2 + 2,
  340.                      &KV2[Order - 1], KV2Len - Order * 2 + 2,
  341.                      &RefLen);
  342.         if (RefLen > 0) {
  343.         TSrf = CagdSrfRefineAtParams(*Srf2, CAGD_CONST_V_DIR,
  344.                          FALSE, RefKV, RefLen);
  345.         CagdSrfFree(*Srf2);
  346.         *Srf2 = TSrf;
  347.         }
  348.         IritFree((VoidPtr) RefKV);
  349.     }
  350.     }
  351.  
  352.     return TRUE;
  353. }
  354.  
  355.