ftp.nice.ch/pub/next/graphics/3d/geomview.1.4.1.s.tar.gz#/Geomview/src/lib/geomutil/bdy/bdy.c

This is bdy.c in view mode; [Download] [Up]

/*
 * bdy.c
 * author:  Celeste Fowler
 * date:  June 12, 1992
 */

#include <stdlib.h>
#include "geom.h"
#include "polylistP.h"
#include "ooglutil.h"
#include "plutil.h"
#include "bdy.h"


#define min(a, b) ((a < b) ? a : b)
#define max(a, b) ((a > b) ? a : b)

static char msg[] = "bdy.c";

/* Precision.  The global declaration is a hack to get the value out 
 * of Bdy and into EdgeCmp where it is needed (EdgeCmp must be called by 
 * qsort. */
static float precision;

int EdgeCmp(HPoint3 **a, HPoint3 **b)
{
  int i;
  char *chara, *charb;
  float dist00, dist01, dist11, dist10;

  while (1) {
    dist00 = HPt3Distance(a[0], b[0]);
    dist01 = HPt3Distance(a[0], b[1]);
    dist11 = HPt3Distance(a[1], b[1]);
    dist10 = HPt3Distance(a[1], b[0]);

    if (dist00 > precision && dist01 > precision) break;
    if (dist11 > precision && dist10 > precision) break;
    if (dist00 < precision && dist11 > precision) break;
    if (dist01 < precision && dist10 > precision) break;
    if (dist11 < precision && dist00 > precision) break;
    if (dist10 < precision && dist01 > precision) break;
    return 0;
  }

  chara = (char *)a[0];
  charb = (char *)b[0];
  for (i = 0; i < sizeof(HPoint3); i++) 
    if (chara[i] != charb[i]) return chara[i] - charb[i];
  chara = (char *)a[1];
  charb = (char *)b[1];
  for (i = 0; i < sizeof(HPoint3); i++)
    if (chara[i] != charb[i]) return chara[i] - charb[i];

}

Geom *Bdy(Geom *g, float prec) {
  int i, j, k;

  PolyList *p;
  int n_edges;
  HPoint3 **edges;

  Geom *vect;
  short *vcounts, *ccounts;
  Point3 *verts;
  ColorA color;

  g = (Geom *)AnyToPL(g, TM_IDENTITY);
  if (g == NULL) return NULL;
 
  precision = prec;

  /* Get a consolidated version of the polylist. */
  p = (PolyList *)PLConsol(g, 0.0); 
  GeomDelete(g); 
 
  /* Count the number of edges in the polygon */
  for (i = n_edges = 0; i < p->n_polys; i++) n_edges += p->p[i].n_vertices;

  /* Put the edges in an array and sort it */
  edges = OOGLNewNE(HPoint3 *, 2 * n_edges, msg);
  for (i = k = 0; i < p->n_polys; i++) {
    for (j = 0; j < p->p[i].n_vertices; j++) {
      edges[k * 2] = (HPoint3 *)
	min(p->p[i].v[j], p->p[i].v[(j + 1) % p->p[i].n_vertices]);
      edges[k * 2 + 1] = (HPoint3 *) 
	max(p->p[i].v[j], p->p[i].v[(j + 1) % p->p[i].n_vertices]);
      k++;
    }
    if (p->p[i].n_vertices == 2) k--;
  }
  n_edges = k;
  precision = 0.0;
  qsort(edges, n_edges, 2 * sizeof(HPoint3 *), (int (*)())EdgeCmp);
  precision = prec;

  /* Eliminate everything mentioned more than once */
  for (i = j = k = 0; i < n_edges; i++) 
    if (EdgeCmp(&edges[i*2], &edges[k*2])) {
      if (i == k + 1) {
	edges[j*2] = edges[k*2];
	edges[j*2 + 1] = edges[k*2 + 1];
	j++;
      }
      k = i;
    }
  if (i == k + 1) {
    edges[j*2] = edges[k*2];
    edges[j*2 + 1] = edges[k*2 + 1];
    j++;
  }
  if (!j) {
    OOGLFree(edges);
    GeomDelete((Geom *)p);
    return NULL;
  }
 
  /* Call the vect create routine */
  vcounts = OOGLNewNE(short, j, msg);
  ccounts = OOGLNewNE(short, j, msg);
  verts = OOGLNewNE(Point3, j*2, msg);
  for (i = 0; i < j; i++) {
    vcounts[i] = 2;
    ccounts[i] = 0;
    Pt3Copy((const Point3 *)edges[i*2], &verts[i*2]);
    Pt3Copy((const Point3 *)edges[i*2 + 1], &verts[i*2 + 1]);
  }
  ccounts[0] = 1;
  color.r = 0.0;
  color.g = 0.0;
  color.b = 0.0;
  color.a = 1.0;

  vect = GeomCreate("vect",
		    CR_NVECT, j,
		    CR_VECTC, vcounts,
		    CR_NVERT, j*2,
		    CR_POINT, verts,

		    CR_NCOLR, 1,
		    CR_COLRC, ccounts,
		    CR_COLOR, &color,
		    CR_END);

  OOGLFree(ccounts);
  OOGLFree(vcounts);
  OOGLFree(edges);

  GeomDelete((Geom *)p);

  return vect;

}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.