home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / i / iritsm3s.zip / cagd_lib / cagdbsum.c < prev    next >
C/C++ Source or Header  |  1991-10-08  |  5KB  |  120 lines

  1. /******************************************************************************
  2. * CagdBSum.c - Boolean sum surface constructor out of given four curves.      *
  3. *******************************************************************************
  4. * Written by Gershon Elber, Sep. 91.                          *
  5. ******************************************************************************/
  6.  
  7. #ifdef __MSDOS__
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <alloc.h>
  11. #endif /* __MSDOS__ */
  12.  
  13. #include "cagd_loc.h"
  14.  
  15. /******************************************************************************
  16. * Constructs a boolean sum surface using the four provided boundary curves.   *
  17. * Curve end points must meet at the corners if surface boundary should be the *
  18. * same as the four curves.                              *
  19. ******************************************************************************/
  20. CagdSrfStruct *CagdBoolSumSrf(CagdCrvStruct *CrvLeft,
  21.                   CagdCrvStruct *CrvRight,
  22.                   CagdCrvStruct *CrvTop,
  23.                   CagdCrvStruct *CrvBottom)
  24. {
  25.     int i, j;
  26.     CagdCrvStruct *Crv1, *Crv2;
  27.     CagdSrfStruct *Ruled1, *Ruled2, *Ruled3, *Srf;
  28.     CagdPtStruct Pt1, Pt2;
  29.     CagdRType **SrfPoints, **Ruled1Pts, **Ruled2Pts, **Ruled3Pts;
  30.  
  31.     CrvLeft = CagdCrvCopy(CrvLeft);
  32.     CrvRight = CagdCrvCopy(CrvRight);
  33.     CrvTop = CagdCrvCopy(CrvTop);
  34.     CrvBottom = CagdCrvCopy(CrvBottom);
  35.  
  36.     /* The Left-Right and Top-Bottom curves should share same point/curve     */
  37.     /* type as well as same order and knot vector (if Bspline representation).*/
  38.     CagdMakeCrvsCompatible(&CrvLeft, &CrvRight, TRUE, TRUE);
  39.     CagdMakeCrvsCompatible(&CrvTop, &CrvBottom, TRUE, TRUE);
  40.  
  41.     /* The Left-Right and Top-Bottom pairs must share same point/curve type.  */
  42.     CagdMakeCrvsCompatible(&CrvLeft, &CrvTop, FALSE, FALSE);
  43.     CagdMakeCrvsCompatible(&CrvLeft, &CrvBottom, FALSE, FALSE);
  44.     CagdMakeCrvsCompatible(&CrvRight, &CrvTop, FALSE, FALSE);
  45.     CagdMakeCrvsCompatible(&CrvRight, &CrvBottom, FALSE, FALSE);
  46.  
  47.     /* Now that the curves are in the right representation, form surface(s).  */
  48.     /* The two ruled surface between the respective curves, in right orders:  */
  49.     Ruled1 = CagdRuledSrf(CrvLeft, CrvRight,
  50.               CrvTop -> Order, CrvTop -> Length);
  51.     Ruled2 = CagdRuledSrf(CrvTop, CrvBottom,
  52.               CrvRight -> Order, CrvRight -> Length);
  53.     Srf = CagdSrfReverse2(Ruled2);
  54.     CagdSrfFree(Ruled2);
  55.     Ruled2 = Srf;
  56.  
  57.     /* The ruled surface between the four corner points in the right orders.  */
  58.     CagdCoerceToE3(Pt1.Pt, CrvLeft -> Points, 0, CrvLeft -> PType);
  59.     CagdCoerceToE3(Pt2.Pt, CrvLeft -> Points, CrvLeft -> Length - 1,
  60.                             CrvLeft -> PType);
  61.     Crv1 = CagdMergePtPt(&Pt1, &Pt2);
  62.  
  63.     CagdCoerceToE3(Pt1.Pt, CrvRight -> Points, 0, CrvRight -> PType);
  64.     CagdCoerceToE3(Pt2.Pt, CrvRight -> Points, CrvRight -> Length - 1,
  65.                             CrvRight -> PType);
  66.     Crv2 = CagdMergePtPt(&Pt1, &Pt2);
  67.  
  68.     /* Should not change CrvLeft/Right only Crv1/2: */
  69.     CagdMakeCrvsCompatible(&Crv1, &CrvLeft, TRUE, TRUE);
  70.     CagdMakeCrvsCompatible(&Crv2, &CrvRight, TRUE, TRUE);
  71.  
  72.     Ruled3 = CagdRuledSrf(Crv1, Crv2, CrvTop -> Order, CrvTop -> Length);
  73.     CagdCrvFree(Crv1);
  74.     CagdCrvFree(Crv2);
  75.  
  76.     /* The boolean sum is equal to Ruled1 + Ruled2 - Ruled3. This boolean     */
  77.     /* sum as computed is not exactly as defined in the literature for non    */
  78.     /* uniform Bsplines since the ruled surfaces are computed with uniform    */
  79.     /* distribution along the other axis even if it is non uniform.          */
  80.     if (CrvRight -> GType == CAGD_CBSPLINE_TYPE) {
  81.     Srf = BspSrfNew(Ruled1 -> ULength, Ruled1 -> VLength,
  82.             Ruled1 -> UOrder, Ruled1 -> VOrder, Ruled1 -> PType);
  83.     CagdFree((VoidPtr) Srf -> UKnotVector);
  84.     Srf -> UKnotVector = BspKnotCopy(CrvLeft -> KnotVector,
  85.                      CrvLeft -> Length + CrvLeft -> Order);
  86.     CagdFree((VoidPtr) Srf -> VKnotVector);
  87.     Srf -> VKnotVector = BspKnotCopy(CrvTop -> KnotVector,
  88.                      CrvTop -> Length + CrvTop -> Order);
  89.     }
  90.     else if (CrvRight -> GType == CAGD_CBEZIER_TYPE)
  91.     Srf = BzrSrfNew(Ruled1 -> ULength, Ruled1 -> VLength, Ruled1 -> PType);
  92.     else
  93.     FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  94.     SrfPoints = Srf -> Points;
  95.  
  96.     Ruled1Pts = Ruled1 -> Points;
  97.     Ruled2Pts = Ruled2 -> Points;
  98.     Ruled3Pts = Ruled3 -> Points;
  99.  
  100.     for (i = !CAGD_IS_RATIONAL_SRF(Srf);
  101.      i <= CAGD_NUM_OF_PT_COORD(Srf -> PType);
  102.      i++) {
  103.     CagdRType
  104.         *Ruled1PtsPtr = Ruled1Pts[i],
  105.         *Ruled2PtsPtr = Ruled2Pts[i],
  106.         *Ruled3PtsPtr = Ruled3Pts[i],
  107.         *SrfPointsPtr = SrfPoints[i];
  108.  
  109.      for (j = Srf -> ULength * Srf -> VLength; j > 0; j--)
  110.          *SrfPointsPtr++ =
  111.          *Ruled1PtsPtr++ + *Ruled2PtsPtr++ - *Ruled3PtsPtr++;
  112.     }
  113.  
  114.     CagdSrfFree(Ruled1);
  115.     CagdSrfFree(Ruled2);
  116.     CagdSrfFree(Ruled3);
  117.  
  118.     return Srf;
  119. }
  120.