#include <math.h>
#include <stdlib.h>
#include "geomclass.h"
#include "geom.h"
#include "polylist.h"
#include "polylistP.h"
#include "hpoint3.h"
#include "plutil.h"

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

/* This is the precision, declared globally so that it will
 * be accessible in the compare routine which must be called 
 * from qsort */
static float precision;

/*
 * Note:  This deals only with the location of the points, not with 
 * their colors or normals.  
 */
int VertexCmp(a, b) 
Vertex *a;
Vertex *b;
{
  int i;
  char *achar, *bchar;
  if (HPt3Distance(&a->pt, &b->pt) > precision) {
    achar = (char *)a;
    bchar = (char *)b;
    for (i = 0; i < sizeof(Vertex); i++) 
      if (achar[i] != bchar[i]) return achar[i] - bchar[i];
  }
  return 0;

}

Geom *PLConsol(Geom *g, float prec) {
  Vertex **table;
  PolyList *o = (PolyList *)g, *o2;
  int i, j;

  if (g == NULL) return NULL;

  /* Make sure we have the right thing. */
  if (strcmp(GeomName(g), "polylist")) {
    OOGLError(0, "Object not of polylist type.");
    return NULL;
  }

  precision = prec;

  /* Create a copy of the data structure. */
  o2 = (PolyList *)GeomCopy((Geom *)o);
  
  /* Sort the new array. */
  precision = 0.0;
  qsort(o2->vl, o2->n_verts, sizeof(Vertex), VertexCmp);
  precision = prec;

  /* Consolidate the new array to eliminate identical vertices. */
  for (i = j = 0; i < o2->n_verts; i++) 
    if (VertexCmp(&o2->vl[i], &o2->vl[j]))
      HPt3Copy(&o2->vl[i], &o2->vl[++j]);
  o2->n_verts = j+1;

  /* Create a lookup table of the new addresses of the vertices. */
  table = (Vertex **)OOG_NewE(o->n_verts * sizeof(Vertex *), msg);
  for (i = 0; i < o->n_verts; i++) 
    table[i] = bsearch(&(o->vl[i]), o2->vl, o2->n_verts, sizeof(Vertex),
		       VertexCmp);

  /* Match the polygons in the structure with the new vertices.  */
  for (i = 0; i < o2->n_polys; i++)
    for (j = 0; j < o2->p[i].n_vertices; j++)
      o2->p[i].v[j] = table[o2->p[i].v[j] - o2->vl];

  /* Trim off the excess memory */
  o2->vl = OOGLRenewNE(Vertex, o2->vl, o2->n_verts, msg);

  return((Geom *)o2);

}









