home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / modelers / geomview / source.lha / Geomview / src / lib / geomutil / bdy / bdy.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-23  |  3.6 KB  |  156 lines

  1. /*
  2.  * bdy.c
  3.  * author:  Celeste Fowler
  4.  * date:  June 12, 1992
  5.  */
  6.  
  7. #include <stdlib.h>
  8. #include "geom.h"
  9. #include "polylistP.h"
  10. #include "ooglutil.h"
  11. #include "plutil.h"
  12. #include "bdy.h"
  13.  
  14.  
  15. #define min(a, b) ((a < b) ? a : b)
  16. #define max(a, b) ((a > b) ? a : b)
  17.  
  18. static char msg[] = "bdy.c";
  19.  
  20. /* Precision.  The global declaration is a hack to get the value out 
  21.  * of Bdy and into EdgeCmp where it is needed (EdgeCmp must be called by 
  22.  * qsort. */
  23. static float precision;
  24.  
  25. int EdgeCmp(HPoint3 **a, HPoint3 **b)
  26. {
  27.   int i;
  28.   char *chara, *charb;
  29.   float dist00, dist01, dist11, dist10;
  30.  
  31.   while (1) {
  32.     dist00 = HPt3Distance(a[0], b[0]);
  33.     dist01 = HPt3Distance(a[0], b[1]);
  34.     dist11 = HPt3Distance(a[1], b[1]);
  35.     dist10 = HPt3Distance(a[1], b[0]);
  36.  
  37.     if (dist00 > precision && dist01 > precision) break;
  38.     if (dist11 > precision && dist10 > precision) break;
  39.     if (dist00 < precision && dist11 > precision) break;
  40.     if (dist01 < precision && dist10 > precision) break;
  41.     if (dist11 < precision && dist00 > precision) break;
  42.     if (dist10 < precision && dist01 > precision) break;
  43.     return 0;
  44.   }
  45.  
  46.   chara = (char *)a[0];
  47.   charb = (char *)b[0];
  48.   for (i = 0; i < sizeof(HPoint3); i++) 
  49.     if (chara[i] != charb[i]) return chara[i] - charb[i];
  50.   chara = (char *)a[1];
  51.   charb = (char *)b[1];
  52.   for (i = 0; i < sizeof(HPoint3); i++)
  53.     if (chara[i] != charb[i]) return chara[i] - charb[i];
  54.  
  55. }
  56.  
  57. Geom *Bdy(Geom *g, float prec) {
  58.   int i, j, k;
  59.  
  60.   PolyList *p;
  61.   int n_edges;
  62.   HPoint3 **edges;
  63.  
  64.   Geom *vect;
  65.   short *vcounts, *ccounts;
  66.   Point3 *verts;
  67.   ColorA color;
  68.  
  69.   g = (Geom *)AnyToPL(g, TM_IDENTITY);
  70.   if (g == NULL) return NULL;
  71.  
  72.   precision = prec;
  73.  
  74.   /* Get a consolidated version of the polylist. */
  75.   p = (PolyList *)PLConsol(g, 0.0); 
  76.   GeomDelete(g); 
  77.  
  78.   /* Count the number of edges in the polygon */
  79.   for (i = n_edges = 0; i < p->n_polys; i++) n_edges += p->p[i].n_vertices;
  80.  
  81.   /* Put the edges in an array and sort it */
  82.   edges = OOGLNewNE(HPoint3 *, 2 * n_edges, msg);
  83.   for (i = k = 0; i < p->n_polys; i++) {
  84.     for (j = 0; j < p->p[i].n_vertices; j++) {
  85.       edges[k * 2] = (HPoint3 *)
  86.     min(p->p[i].v[j], p->p[i].v[(j + 1) % p->p[i].n_vertices]);
  87.       edges[k * 2 + 1] = (HPoint3 *) 
  88.     max(p->p[i].v[j], p->p[i].v[(j + 1) % p->p[i].n_vertices]);
  89.       k++;
  90.     }
  91.     if (p->p[i].n_vertices == 2) k--;
  92.   }
  93.   n_edges = k;
  94.   precision = 0.0;
  95.   qsort(edges, n_edges, 2 * sizeof(HPoint3 *), (int (*)())EdgeCmp);
  96.   precision = prec;
  97.  
  98.   /* Eliminate everything mentioned more than once */
  99.   for (i = j = k = 0; i < n_edges; i++) 
  100.     if (EdgeCmp(&edges[i*2], &edges[k*2])) {
  101.       if (i == k + 1) {
  102.     edges[j*2] = edges[k*2];
  103.     edges[j*2 + 1] = edges[k*2 + 1];
  104.     j++;
  105.       }
  106.       k = i;
  107.     }
  108.   if (i == k + 1) {
  109.     edges[j*2] = edges[k*2];
  110.     edges[j*2 + 1] = edges[k*2 + 1];
  111.     j++;
  112.   }
  113.   if (!j) {
  114.     OOGLFree(edges);
  115.     GeomDelete((Geom *)p);
  116.     return NULL;
  117.   }
  118.  
  119.   /* Call the vect create routine */
  120.   vcounts = OOGLNewNE(short, j, msg);
  121.   ccounts = OOGLNewNE(short, j, msg);
  122.   verts = OOGLNewNE(Point3, j*2, msg);
  123.   for (i = 0; i < j; i++) {
  124.     vcounts[i] = 2;
  125.     ccounts[i] = 0;
  126.     Pt3Copy((const Point3 *)edges[i*2], &verts[i*2]);
  127.     Pt3Copy((const Point3 *)edges[i*2 + 1], &verts[i*2 + 1]);
  128.   }
  129.   ccounts[0] = 1;
  130.   color.r = 0.0;
  131.   color.g = 0.0;
  132.   color.b = 0.0;
  133.   color.a = 1.0;
  134.  
  135.   vect = GeomCreate("vect",
  136.             CR_NVECT, j,
  137.             CR_VECTC, vcounts,
  138.             CR_NVERT, j*2,
  139.             CR_POINT, verts,
  140.  
  141.             CR_NCOLR, 1,
  142.             CR_COLRC, ccounts,
  143.             CR_COLOR, &color,
  144.             CR_END);
  145.  
  146.   OOGLFree(ccounts);
  147.   OOGLFree(vcounts);
  148.   OOGLFree(edges);
  149.  
  150.   GeomDelete((Geom *)p);
  151.  
  152.   return vect;
  153.  
  154. }
  155.  
  156.