home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- * CagdBSum.c - Boolean sum surface constructor out of given four curves. *
- *******************************************************************************
- * Written by Gershon Elber, Sep. 91. *
- ******************************************************************************/
-
- #ifdef __MSDOS__
- #include <stdlib.h>
- #include <string.h>
- #include <alloc.h>
- #endif /* __MSDOS__ */
-
- #include "cagd_loc.h"
-
- /******************************************************************************
- * Constructs a boolean sum surface using the four provided boundary curves. *
- * Curve end points must meet at the corners if surface boundary should be the *
- * same as the four curves. *
- ******************************************************************************/
- CagdSrfStruct *CagdBoolSumSrf(CagdCrvStruct *CrvLeft,
- CagdCrvStruct *CrvRight,
- CagdCrvStruct *CrvTop,
- CagdCrvStruct *CrvBottom)
- {
- int i, j;
- CagdCrvStruct *Crv1, *Crv2;
- CagdSrfStruct *Ruled1, *Ruled2, *Ruled3, *Srf;
- CagdPtStruct Pt1, Pt2;
- CagdRType **SrfPoints, **Ruled1Pts, **Ruled2Pts, **Ruled3Pts;
-
- CrvLeft = CagdCrvCopy(CrvLeft);
- CrvRight = CagdCrvCopy(CrvRight);
- CrvTop = CagdCrvCopy(CrvTop);
- CrvBottom = CagdCrvCopy(CrvBottom);
-
- /* The Left-Right and Top-Bottom curves should share same point/curve */
- /* type as well as same order and knot vector (if Bspline representation).*/
- CagdMakeCrvsCompatible(&CrvLeft, &CrvRight, TRUE, TRUE);
- CagdMakeCrvsCompatible(&CrvTop, &CrvBottom, TRUE, TRUE);
-
- /* The Left-Right and Top-Bottom pairs must share same point/curve type. */
- CagdMakeCrvsCompatible(&CrvLeft, &CrvTop, FALSE, FALSE);
- CagdMakeCrvsCompatible(&CrvLeft, &CrvBottom, FALSE, FALSE);
- CagdMakeCrvsCompatible(&CrvRight, &CrvTop, FALSE, FALSE);
- CagdMakeCrvsCompatible(&CrvRight, &CrvBottom, FALSE, FALSE);
-
- /* Now that the curves are in the right representation, form surface(s). */
- /* The two ruled surface between the respective curves, in right orders: */
- Ruled1 = CagdRuledSrf(CrvLeft, CrvRight,
- CrvTop -> Order, CrvTop -> Length);
- Ruled2 = CagdRuledSrf(CrvTop, CrvBottom,
- CrvRight -> Order, CrvRight -> Length);
- Srf = CagdSrfReverse2(Ruled2);
- CagdSrfFree(Ruled2);
- Ruled2 = Srf;
-
- /* The ruled surface between the four corner points in the right orders. */
- CagdCoerceToE3(Pt1.Pt, CrvLeft -> Points, 0, CrvLeft -> PType);
- CagdCoerceToE3(Pt2.Pt, CrvLeft -> Points, CrvLeft -> Length - 1,
- CrvLeft -> PType);
- Crv1 = CagdMergePtPt(&Pt1, &Pt2);
-
- CagdCoerceToE3(Pt1.Pt, CrvRight -> Points, 0, CrvRight -> PType);
- CagdCoerceToE3(Pt2.Pt, CrvRight -> Points, CrvRight -> Length - 1,
- CrvRight -> PType);
- Crv2 = CagdMergePtPt(&Pt1, &Pt2);
-
- /* Should not change CrvLeft/Right only Crv1/2: */
- CagdMakeCrvsCompatible(&Crv1, &CrvLeft, TRUE, TRUE);
- CagdMakeCrvsCompatible(&Crv2, &CrvRight, TRUE, TRUE);
-
- Ruled3 = CagdRuledSrf(Crv1, Crv2, CrvTop -> Order, CrvTop -> Length);
- CagdCrvFree(Crv1);
- CagdCrvFree(Crv2);
-
- /* The boolean sum is equal to Ruled1 + Ruled2 - Ruled3. This boolean */
- /* sum as computed is not exactly as defined in the literature for non */
- /* uniform Bsplines since the ruled surfaces are computed with uniform */
- /* distribution along the other axis even if it is non uniform. */
- if (CrvRight -> GType == CAGD_CBSPLINE_TYPE) {
- Srf = BspSrfNew(Ruled1 -> ULength, Ruled1 -> VLength,
- Ruled1 -> UOrder, Ruled1 -> VOrder, Ruled1 -> PType);
- CagdFree((VoidPtr) Srf -> UKnotVector);
- Srf -> UKnotVector = BspKnotCopy(CrvLeft -> KnotVector,
- CrvLeft -> Length + CrvLeft -> Order);
- CagdFree((VoidPtr) Srf -> VKnotVector);
- Srf -> VKnotVector = BspKnotCopy(CrvTop -> KnotVector,
- CrvTop -> Length + CrvTop -> Order);
- }
- else if (CrvRight -> GType == CAGD_CBEZIER_TYPE)
- Srf = BzrSrfNew(Ruled1 -> ULength, Ruled1 -> VLength, Ruled1 -> PType);
- else
- FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
- SrfPoints = Srf -> Points;
-
- Ruled1Pts = Ruled1 -> Points;
- Ruled2Pts = Ruled2 -> Points;
- Ruled3Pts = Ruled3 -> Points;
-
- for (i = !CAGD_IS_RATIONAL_SRF(Srf);
- i <= CAGD_NUM_OF_PT_COORD(Srf -> PType);
- i++) {
- CagdRType
- *Ruled1PtsPtr = Ruled1Pts[i],
- *Ruled2PtsPtr = Ruled2Pts[i],
- *Ruled3PtsPtr = Ruled3Pts[i],
- *SrfPointsPtr = SrfPoints[i];
-
- for (j = Srf -> ULength * Srf -> VLength; j > 0; j--)
- *SrfPointsPtr++ =
- *Ruled1PtsPtr++ + *Ruled2PtsPtr++ - *Ruled3PtsPtr++;
- }
-
- CagdSrfFree(Ruled1);
- CagdSrfFree(Ruled2);
- CagdSrfFree(Ruled3);
-
- return Srf;
- }
-