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 / cagd_gen.c < prev    next >
C/C++ Source or Header  |  1991-09-26  |  20KB  |  612 lines

  1. /******************************************************************************
  2. * Cagd_gen.c - General routines used by all modules of CAGD_lib.          *
  3. *******************************************************************************
  4. * Written by Gershon Elber, Mar. 90.                          *
  5. ******************************************************************************/
  6.  
  7. #ifdef __MSDOS__
  8. #include <stdlib.h>
  9. #include <alloc.h>
  10. #endif /* __MSDOS__ */
  11.  
  12. #include <string.h>
  13. #include "cagd_loc.h"
  14.  
  15. #ifdef __TURBOC__                 /* Only for TC++ 1.0 and above. */
  16. #define __DEBUG_MALLOC__
  17. #endif /* __TURBOC__ */
  18.  
  19. #ifdef __DEBUG_FREE_BOGUS__          /* Detected freeing of bogus pointers. */
  20. #define FREE_TABLE_SIZE 10000
  21. static VoidPtr AllocPtrTable[FREE_TABLE_SIZE];
  22. static int AllocNumPtrs = 0;
  23. #endif /* __DEBUG_FREE_BOGUS__ */
  24.  
  25. /* Control of the linear order surface convertion to polygon: */
  26. CagdLin2PolyType _CagdLin2Poly = CAGD_ONE_POLY_PER_COLIN;
  27.  
  28. static void CagdTransform(CagdRType **Points, int Len, int MaxCoord,
  29.          CagdBType IsNotRational, CagdRType Translate[3], CagdRType Scale);
  30. static void CagdMatTransform(CagdRType **Points, int Len, int MaxCoord,
  31.                   CagdBType IsNotRational, CagdMatStruct *Mat);
  32.  
  33. /******************************************************************************
  34. * Allocate and reset all slots of a curve structure:                  *
  35. ******************************************************************************/
  36. CagdCrvStruct *CagdCrvNew(CagdGeomType GType, CagdPointType PType, int Length)
  37. {
  38.     int i, MaxAxis = CAGD_NUM_OF_PT_COORD(PType);
  39.     CagdCrvStruct *NewCrv = (CagdCrvStruct *) CagdMalloc(sizeof(CagdCrvStruct));
  40.  
  41.     NewCrv -> GType = GType;
  42.     NewCrv -> PType = PType;
  43.     NewCrv -> Length = Length;
  44.     NewCrv -> Order = 0;
  45.     NewCrv -> KnotVector = NULL;
  46.     NewCrv -> Pnext = NULL;
  47.     NewCrv -> Points[0] = NULL;                /* The rational element. */
  48.  
  49.     for (i = !CAGD_IS_RATIONAL_PT(PType); i <= MaxAxis; i++)
  50.     NewCrv -> Points[i] = (CagdRType *) CagdMalloc(sizeof(CagdRType) *
  51.                                  Length);
  52.  
  53.     for (i = MaxAxis + 1; i <= CAGD_MAX_PT_COORD; i++)
  54.     NewCrv -> Points[i] = NULL;
  55.  
  56.     return NewCrv;
  57. }
  58.  
  59. /******************************************************************************
  60. * Allocate and reset all slots of a surface structure:                  *
  61. ******************************************************************************/
  62. CagdSrfStruct *CagdSrfNew(CagdGeomType GType, CagdPointType PType, int ULength,
  63.                                    int VLength)
  64. {
  65.     int i, MaxAxis = CAGD_NUM_OF_PT_COORD(PType);
  66.     CagdSrfStruct *NewSrf = (CagdSrfStruct *) CagdMalloc(sizeof(CagdSrfStruct));
  67.  
  68.     NewSrf -> GType = GType;
  69.     NewSrf -> PType = PType;
  70.     NewSrf -> ULength = ULength;
  71.     NewSrf -> VLength = VLength;
  72.     NewSrf -> UOrder = 0;
  73.     NewSrf -> VOrder = 0;
  74.     NewSrf -> UKnotVector = NULL;
  75.     NewSrf -> VKnotVector = NULL;
  76.     NewSrf -> Pnext = NULL;
  77.     NewSrf -> Points[0] = NULL;                /* The rational element. */
  78.  
  79.     for (i = !CAGD_IS_RATIONAL_PT(PType); i <= MaxAxis; i++)
  80.     NewSrf -> Points[i] = (CagdRType *) CagdMalloc(sizeof(CagdRType) *
  81.                             ULength * VLength);
  82.  
  83.     for (i = MaxAxis + 1; i <= CAGD_MAX_PT_COORD; i++)
  84.     NewSrf -> Points[i] = NULL;
  85.  
  86.     return NewSrf;
  87. }
  88.  
  89. /******************************************************************************
  90. * Allocate and reset all slots of a polygon structure:                  *
  91. ******************************************************************************/
  92. CagdPolygonStruct *CagdPolygonNew(void)
  93. {
  94.     CagdPolygonStruct *NewPoly = (CagdPolygonStruct *)
  95.                         CagdMalloc(sizeof(CagdPolygonStruct));
  96.  
  97.     NewPoly -> Pnext = NULL;
  98.  
  99.     return NewPoly;
  100. }
  101.  
  102.  
  103. /******************************************************************************
  104. * Allocate and reset all slots of a polyline structure:                  *
  105. ******************************************************************************/
  106. CagdPolylineStruct *CagdPolylineNew(int Length)
  107. {
  108.     CagdPolylineStruct *NewPoly = (CagdPolylineStruct *)
  109.                     CagdMalloc(sizeof(CagdPolylineStruct));
  110.  
  111.     NewPoly -> Pnext = NULL;
  112.     NewPoly -> Polyline = (CagdPtStruct *) CagdMalloc(sizeof(CagdPtStruct) *
  113.                                        Length);
  114.     NewPoly -> Length = Length;
  115.  
  116.     return NewPoly;
  117. }
  118.  
  119. /******************************************************************************
  120. * Allocate and copy all slots of a curve structure:                  *
  121. ******************************************************************************/
  122. CagdCrvStruct *CagdCrvCopy(CagdCrvStruct *Crv)
  123. {
  124.     int i, MaxAxis = CAGD_NUM_OF_PT_COORD(Crv -> PType);
  125.     CagdCrvStruct *NewCrv = (CagdCrvStruct *) CagdMalloc(sizeof(CagdCrvStruct));
  126.  
  127.     NewCrv -> GType = Crv -> GType;
  128.     NewCrv -> PType = Crv -> PType;
  129.     NewCrv -> Length = Crv -> Length;
  130.     NewCrv -> Order = Crv -> Order;
  131.     if (Crv -> KnotVector != NULL)
  132.     NewCrv -> KnotVector = BspKnotCopy(Crv -> KnotVector,
  133.                        Crv -> Length + Crv -> Order);
  134.     else
  135.     NewCrv -> KnotVector = NULL;
  136.     NewCrv -> Pnext = NULL;
  137.     NewCrv -> Points[0] = NULL;                /* The rational element. */
  138.  
  139.     for (i = !CAGD_IS_RATIONAL_PT(Crv -> PType); i <= MaxAxis; i++) {
  140.     NewCrv -> Points[i] = (CagdRType *) CagdMalloc(sizeof(CagdRType) *
  141.                                    Crv -> Length);
  142.     GEN_COPY(NewCrv -> Points[i], Crv -> Points[i],
  143.          sizeof(CagdRType) * Crv -> Length);
  144.     }
  145.  
  146.     for (i = MaxAxis + 1; i <= CAGD_MAX_PT_COORD; i++)
  147.     NewCrv -> Points[i] = NULL;
  148.  
  149.     return NewCrv;
  150. }
  151.  
  152. /******************************************************************************
  153. * Allocate and copy all slots of a surface structure:                  *
  154. ******************************************************************************/
  155. CagdSrfStruct *CagdSrfCopy(CagdSrfStruct *Srf)
  156. {
  157.     int i, MaxAxis = CAGD_NUM_OF_PT_COORD(Srf -> PType);
  158.     CagdSrfStruct *NewSrf = (CagdSrfStruct *) CagdMalloc(sizeof(CagdSrfStruct));
  159.  
  160.     NewSrf -> GType = Srf -> GType;
  161.     NewSrf -> PType = Srf -> PType;
  162.     NewSrf -> ULength = Srf -> ULength;
  163.     NewSrf -> VLength = Srf -> VLength;
  164.     NewSrf -> UOrder = Srf -> UOrder;
  165.     NewSrf -> VOrder = Srf -> VOrder;
  166.     if (Srf -> UKnotVector != NULL)
  167.     NewSrf -> UKnotVector = BspKnotCopy(Srf -> UKnotVector,
  168.                         Srf -> ULength + Srf -> UOrder);
  169.     else
  170.     NewSrf -> UKnotVector = NULL;
  171.     if (Srf -> VKnotVector != NULL)
  172.     NewSrf -> VKnotVector = BspKnotCopy(Srf -> VKnotVector,
  173.                         Srf -> VLength + Srf -> VOrder);
  174.     else
  175.     NewSrf -> VKnotVector = NULL;
  176.     NewSrf -> Pnext = NULL;
  177.     NewSrf -> Points[0] = NULL;                /* The rational element. */
  178.  
  179.     for (i = !CAGD_IS_RATIONAL_PT(Srf -> PType); i <= MaxAxis; i++) {
  180.     NewSrf -> Points[i] = (CagdRType *) CagdMalloc(sizeof(CagdRType) *
  181.                      Srf -> ULength * Srf -> VLength);
  182.     GEN_COPY(NewSrf -> Points[i], Srf -> Points[i],
  183.          sizeof(CagdRType) * Srf -> ULength * Srf -> VLength);
  184.     }
  185.  
  186.     for (i = MaxAxis + 1; i <= CAGD_MAX_PT_COORD; i++)
  187.     NewSrf -> Points[i] = NULL;
  188.  
  189.     return NewSrf;
  190. }
  191.  
  192. /******************************************************************************
  193. * Allocate and copy all slots of a polygon structure:                  *
  194. ******************************************************************************/
  195. CagdPolygonStruct *CagdPolygonCopy(CagdPolygonStruct *Poly)
  196. {
  197.     CagdPolygonStruct *NewPoly = (CagdPolygonStruct *)
  198.                         CagdMalloc(sizeof(CagdPolygonStruct));
  199.  
  200.     GEN_COPY(NewPoly, Poly, sizeof(CagdPolygonStruct));
  201.     NewPoly -> Pnext = NULL;
  202.  
  203.     return NewPoly;
  204. }
  205.  
  206.  
  207. /******************************************************************************
  208. * Allocate and copy all slots of a polyline structure:                  *
  209. ******************************************************************************/
  210. CagdPolylineStruct *CagdPolylineCopy(CagdPolylineStruct *Poly)
  211. {
  212.     CagdPolylineStruct *NewPoly = (CagdPolylineStruct *)
  213.                         CagdMalloc(sizeof(CagdPolylineStruct));
  214.  
  215.     NewPoly -> Polyline = (CagdPtStruct *) CagdMalloc(sizeof(CagdPtStruct) *
  216.                             Poly -> Length);
  217.     GEN_COPY(NewPoly -> Polyline, Poly -> Polyline,
  218.                     sizeof(CagdPtStruct) * Poly -> Length);
  219.     NewPoly -> Pnext = NULL;
  220.     NewPoly -> Length = Poly -> Length;
  221.  
  222.     return NewPoly;
  223. }
  224.  
  225. /******************************************************************************
  226. * Deallocate and free all slots of a curve structure:                  *
  227. ******************************************************************************/
  228. void CagdCrvFree(CagdCrvStruct *Crv)
  229. {
  230.     int i, MaxAxis = CAGD_NUM_OF_PT_COORD(Crv -> PType);
  231.  
  232.     for (i = !CAGD_IS_RATIONAL_SRF(Crv); i <= MaxAxis; i++)
  233.     CagdFree((VoidPtr) Crv -> Points[i]);
  234.  
  235.     if (Crv -> KnotVector != NULL)
  236.     CagdFree((VoidPtr) Crv -> KnotVector);
  237.  
  238.     CagdFree((VoidPtr) Crv);
  239. }
  240.  
  241. /******************************************************************************
  242. * Deallocate and free a curve structure list:                      *
  243. ******************************************************************************/
  244. void CagdCrvFreeList(CagdCrvStruct *CrvList)
  245. {
  246.     CagdCrvStruct *CrvTemp;
  247.  
  248.     while (CrvList) {
  249.     CrvTemp = CrvList -> Pnext;
  250.     CagdCrvFree(CrvList);
  251.     CrvList = CrvTemp;
  252.     }
  253. }
  254.  
  255. /******************************************************************************
  256. * Deallocate and free all slots of a surface structure:                  *
  257. ******************************************************************************/
  258. void CagdSrfFree(CagdSrfStruct *Srf)
  259. {
  260.     int i, MaxAxis = CAGD_NUM_OF_PT_COORD(Srf -> PType);
  261.  
  262.     for (i = !CAGD_IS_RATIONAL_SRF(Srf); i <= MaxAxis; i++)
  263.     CagdFree((VoidPtr) Srf -> Points[i]);
  264.  
  265.     if (Srf -> UKnotVector != NULL)
  266.     CagdFree((VoidPtr) Srf -> UKnotVector);
  267.     if (Srf -> VKnotVector != NULL)
  268.     CagdFree((VoidPtr) Srf -> VKnotVector);
  269.  
  270.     CagdFree((VoidPtr) Srf);
  271. }
  272.  
  273. /******************************************************************************
  274. * Deallocate and free a curve structure list:                      *
  275. ******************************************************************************/
  276. void CagdSrfFreeList(CagdSrfStruct *SrfList)
  277. {
  278.     CagdSrfStruct *SrfTemp;
  279.  
  280.     while (SrfList) {
  281.     SrfTemp = SrfList -> Pnext;
  282.     CagdSrfFree(SrfList);
  283.     SrfList = SrfTemp;
  284.     }
  285. }
  286.  
  287. /******************************************************************************
  288. * Deallocate and free a curve structure list:                      *
  289. ******************************************************************************/
  290. void CagdPolylineFree(CagdPolylineStruct *Poly)
  291. {
  292.     CagdFree((VoidPtr) Poly -> Polyline);
  293.     CagdFree((VoidPtr) Poly);
  294. }
  295.  
  296. /******************************************************************************
  297. * Deallocate and free a curve structure list:                      *
  298. ******************************************************************************/
  299. void CagdPolylineFreeList(CagdPolylineStruct *PolyList)
  300. {
  301.     CagdPolylineStruct *PolyTemp;
  302.  
  303.     while (PolyList) {
  304.     PolyTemp = PolyList -> Pnext;
  305.     CagdPolylineFree(PolyList);
  306.     PolyList = PolyTemp;
  307.     }
  308. }
  309.  
  310. /******************************************************************************
  311. * Deallocate and free a curve structure list:                      *
  312. ******************************************************************************/
  313. void CagdPolygonFree(CagdPolygonStruct *Poly)
  314. {
  315.     CagdFree((VoidPtr) Poly);
  316. }
  317.  
  318. /******************************************************************************
  319. * Deallocate and free a curve structure list:                      *
  320. ******************************************************************************/
  321. void CagdPolygonFreeList(CagdPolygonStruct *PolyList)
  322. {
  323.     CagdPolygonStruct *PolyTemp;
  324.  
  325.     while (PolyList) {
  326.     PolyTemp = PolyList -> Pnext;
  327.     CagdPolygonFree(PolyList);
  328.     PolyList = PolyTemp;
  329.     }
  330. }
  331.  
  332. #if defined(__DEBUG_MALLOC__) || defined(__DEBUG_FREE_BOGUS__)
  333. /*****************************************************************************
  334. * My Routine to    allocate dynamic memory. All program requests must call this *
  335. * routine (no direct call to malloc). Dies if no memory.             *
  336. *****************************************************************************/
  337. static void AllocError(const char *Msg, VoidPtr *p)
  338. {
  339.     char s[128];
  340.  
  341.     /* Note s is practically ignored, but you may want to print it. */
  342. #ifdef __MSDOS__
  343.     sprintf(s, "%s, Ptr = %p\n", Msg, p);
  344. #else
  345.     sprintf(s, "%s, Ptr = %lx\n", Msg, p);
  346. #endif /* __MSDOS__ */
  347.  
  348.     FATAL_ERROR(CAGD_ERR_ALLOC_ERR);
  349. }
  350. #endif /* __DEBUG_MALLOC__ || __DEBUG_FREE_BOGUS__ */
  351.  
  352. /*****************************************************************************
  353. * My Routine to    allocate dynamic memory. All program requests must call this *
  354. * routine (no direct call to malloc). Dies if no memory.             *
  355. *****************************************************************************/
  356. VoidPtr CagdMalloc(unsigned size)
  357. {
  358.     VoidPtr p;
  359.  
  360.     if ((p = malloc(size)) != NULL) {
  361. #    ifdef __DEBUG_FREE_BOGUS__
  362.         int i;
  363.  
  364.         /* Save the allocated pointer so we can search for it when freed. */
  365.         for (i = 0; i < AllocNumPtrs; i++)
  366.             if (AllocPtrTable[i] == NULL) {
  367.             AllocPtrTable[i] = p;
  368.             break;
  369.         }
  370.  
  371.         if (i >= AllocNumPtrs) AllocPtrTable[AllocNumPtrs++] = p;
  372. #    endif /* __DEBUG_FREE_BOGUS__ */
  373.  
  374.     return p;
  375.     }
  376.  
  377.     CagdFatalError(CAGD_ERR_NOT_ENOUGH_MEM);
  378.  
  379.     return NULL;                    /* Make warnings silent. */
  380. }
  381.  
  382. /*****************************************************************************
  383. * My Routine to    free dynamic memory. All program requests must call this     *
  384. * routine (no direct call to free).                         *
  385. *****************************************************************************/
  386. void CagdFree(VoidPtr p)
  387. {
  388. #ifdef __DEBUG_FREE_BOGUS__
  389.     int i;
  390.  
  391.     /* Compare the freed pointer with the list of allocated ones. */
  392.     for (i = 0; i < AllocNumPtrs; i++) if (AllocPtrTable[i] == p) break;
  393.     if (i >= AllocNumPtrs) AllocError("Free unallocated pointer", p);
  394. #endif /* __DEBUG_FREE_BOGUS__ */
  395.  
  396. #ifdef __DEBUG_MALLOC__
  397.     switch (heapcheck()) {
  398.     case _HEAPCORRUPT:
  399.         AllocError("Heap is corrupted", p);
  400.         break;
  401.     case _BADNODE:
  402.         AllocError("Attempt to free a bogus pointer", p);
  403.         break;
  404.     case _FREEENTRY:
  405.         AllocError("Attempt to free an already freed pointer", p);
  406.         break;
  407.     case _HEAPOK:
  408.     case _HEAPEMPTY:
  409.     case _USEDENTRY:
  410.         break;
  411.     default:
  412.         AllocError("Allocation error", p);
  413.         break;
  414.  
  415.     }
  416. #endif /* __DEBUG_MALLOC__ */
  417.  
  418.     free(p);
  419. }
  420.  
  421. /******************************************************************************
  422. * Linear transform in place given Crv as specified by Translate and Scale.    *
  423. ******************************************************************************/
  424. void CagdCrvTransform(CagdCrvStruct *Crv, CagdRType Translate[3],
  425.                                  CagdRType Scale)
  426. {
  427.     switch (Crv -> GType) {
  428.     case CAGD_CBEZIER_TYPE:
  429.     case CAGD_CBSPLINE_TYPE:
  430.             CagdTransform(Crv -> Points,
  431.               Crv -> Length,
  432.                   CAGD_NUM_OF_PT_COORD(Crv -> PType),
  433.                   !CAGD_IS_RATIONAL_CRV(Crv),
  434.               Translate,
  435.               Scale);
  436.  
  437.         break;
  438.     case CAGD_CPOWER_TYPE:
  439.         FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  440.         break;
  441.     default:
  442.         FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
  443.         break;
  444.     }
  445. }
  446.  
  447. /******************************************************************************
  448. * Linear transform in place given Srf as specified by Translate and Scale.    *
  449. ******************************************************************************/
  450. void CagdSrfTransform(CagdSrfStruct *Srf, CagdRType Translate[3],
  451.                                  CagdRType Scale)
  452. {
  453.     switch (Srf -> GType) {
  454.     case CAGD_SBEZIER_TYPE:
  455.     case CAGD_SBSPLINE_TYPE:
  456.         CagdTransform(Srf -> Points,
  457.                   Srf -> ULength * Srf -> VLength,
  458.                       CAGD_NUM_OF_PT_COORD(Srf -> PType),
  459.               !CAGD_IS_RATIONAL_SRF(Srf),
  460.                   Translate,
  461.                       Scale);
  462.         break;
  463.     case CAGD_SPOWER_TYPE:
  464.         FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  465.         break;
  466.     default:
  467.         FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
  468.         break;
  469.     }
  470. }
  471.  
  472. /******************************************************************************
  473. * Linear transform in place given Data as specified by Translate and Scale.   *
  474. ******************************************************************************/
  475. static void CagdTransform(CagdRType **Points, int Len, int MaxCoord,
  476.          CagdBType IsNotRational, CagdRType Translate[3], CagdRType Scale)
  477. {
  478.     int i, j;
  479.  
  480.     if (IsNotRational)
  481.     for (i = 1; i <= MaxCoord; i++)
  482.         for (j = 0; j < Len; j++)
  483.         Points[i][j] = (Points[i][j] + Translate[i - 1]) * Scale;
  484.     else
  485.     for (i = 1; i <= MaxCoord; i++)
  486.         for (j = 0; j < Len; j++)
  487.         Points[i][j] = (Points[i][j] +
  488.                 Translate[i - 1] * Points[W][j]) * Scale;
  489. }
  490.  
  491. /******************************************************************************
  492. * Linear transform in place the given Crv as specified by Mat.              *
  493. ******************************************************************************/
  494. void CagdCrvMatTransform(CagdCrvStruct *Crv, CagdMatStruct *Mat)
  495. {
  496.     switch (Crv -> GType) {
  497.     case CAGD_CBEZIER_TYPE:
  498.     case CAGD_CBSPLINE_TYPE:
  499.         CagdMatTransform(Crv -> Points,
  500.                      Crv -> Length,
  501.                          CAGD_NUM_OF_PT_COORD(Crv -> PType),
  502.                  !CAGD_IS_RATIONAL_CRV(Crv),
  503.                      Mat);
  504.         break;
  505.     case CAGD_CPOWER_TYPE:
  506.         FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  507.         break;
  508.     default:
  509.         FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
  510.         break;
  511.     }
  512. }
  513.  
  514. /******************************************************************************
  515. * Linear transform in place the given Srf as specified by Mat.              *
  516. ******************************************************************************/
  517. void CagdSrfMatTransform(CagdSrfStruct *Srf, CagdMatStruct *Mat)
  518. {
  519.     switch (Srf -> GType) {
  520.     case CAGD_SBEZIER_TYPE:
  521.     case CAGD_SBSPLINE_TYPE:
  522.         CagdMatTransform(Srf -> Points,
  523.                      Srf -> ULength * Srf -> VLength,
  524.                          CAGD_NUM_OF_PT_COORD(Srf -> PType),
  525.                  !CAGD_IS_RATIONAL_SRF(Srf),
  526.                      Mat);
  527.         break;
  528.     case CAGD_SPOWER_TYPE:
  529.         FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  530.         break;
  531.     default:
  532.         FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
  533.         break;
  534.     }
  535. }
  536.  
  537. /******************************************************************************
  538. * Linear transform in place the given Data as specified by Mat.              *
  539. ******************************************************************************/
  540. static void CagdMatTransform(CagdRType **Points, int Len, int MaxCoord,
  541.                   CagdBType IsNotRational, CagdMatStruct *Mat)
  542. {
  543.     int i, j;
  544.     CagdRType P[4], Q[4];
  545.  
  546.     if (IsNotRational)
  547.     for (i = 0; i < Len; i++) {
  548.         for (j = 1; j <= MaxCoord; j++) P[j - 1] = Points[j][i];
  549.         P[3] = 1.0;
  550.  
  551.         /* Zero unused coords. */
  552.         for (j = MaxCoord + 1; j < 3; i++) P[j - 1] = 0.0;
  553.  
  554.             CagdMultMatVec(Mat, P, Q);
  555.  
  556.         for (j = 1; j <= MaxCoord; j++) Points[j][i] = Q[j - 1];
  557.         }
  558.     else
  559.     for (i = 0; i < Len; i++) {
  560.         for (j = 1; j <= MaxCoord; j++) P[j - 1] = Points[j][i];
  561.             P[3] = Points[W][i];
  562.  
  563.         /* Zero unused coords. */
  564.         for (j = MaxCoord + 1; j < 3; i++) P[j - 1] = 0.0;
  565.  
  566.             CagdMultMatVec(Mat, P, Q);
  567.  
  568.         for (j = 1; j <= MaxCoord; j++) Points[j][i] = Q[j - 1];
  569.         Points[W][i] = Q[3];
  570.         }
  571. }
  572.  
  573. /*****************************************************************************
  574. * Routine to create one polygon given its vertices.                 *
  575. *****************************************************************************/
  576. CagdPolygonStruct *_CagdMakePolygon(CagdBType ComputeNormals,
  577.                     CagdPtStruct *Pt1,
  578.                     CagdPtStruct *Pt2,
  579.                     CagdPtStruct *Pt3,
  580.                     CagdVecStruct *Nl1,
  581.                     CagdVecStruct *Nl2,
  582.                     CagdVecStruct *Nl3)
  583. {
  584.     CagdPolygonStruct *Poly = CagdPolygonNew();
  585.  
  586.     CAGD_COPY_POINT(Poly -> Polygon[0], *Pt1);
  587.     CAGD_COPY_POINT(Poly -> Polygon[1], *Pt2);
  588.     CAGD_COPY_POINT(Poly -> Polygon[2], *Pt3);
  589.  
  590.     if (ComputeNormals) {
  591.     CAGD_COPY_VECTOR(Poly -> Normal[0], *Nl1);
  592.     CAGD_COPY_VECTOR(Poly -> Normal[1], *Nl2);
  593.     CAGD_COPY_VECTOR(Poly -> Normal[2], *Nl3);
  594.     }
  595.     else {
  596.     CAGD_RESET_VECTOR(Poly -> Normal[0]);
  597.     CAGD_RESET_VECTOR(Poly -> Normal[1]);
  598.     CAGD_RESET_VECTOR(Poly -> Normal[2]);
  599.     }
  600.  
  601.     return Poly;
  602. }
  603.  
  604. /*****************************************************************************
  605. * Set the way (co)linear surfaces are converted into polygons.             *
  606. *****************************************************************************/
  607. void CagdSetLinear2Poly(CagdLin2PolyType Lin2Poly)
  608. {
  609.     _CagdLin2Poly = Lin2Poly;
  610. }
  611.  
  612.