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

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

/*
 * anytopl.c
 * author:  Celeste Fowler
 * date:  June 12, 1992
 */
#include <stdlib.h>
#include "polylistP.h"
#include "bezierP.h"
#include "quadP.h"
#include "meshP.h"
#include "vectP.h"
#include "listP.h"
#include "discgrpP.h"
#include "instP.h"
#include "hpoint3.h"
#include "point3.h"
#include "plutil.h"

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

void PLTransformInto(PolyList *src, PolyList *dest, Transform T);

/*
 * AnyToPL converter.
 * Converts any geomview object to an polylist and returns a pointer
 * to the polylist.  Should return a consolidated polylist, but right
 * now, for the sake of convenience, does not.  NB to future
 * developers: There are a lot of assumptions about the internals of
 * the various data types.  If anything changes, things will have to
 * be adjusted accordingly.
 */

Geom *AnyToPL(Geom *old, Transform T) 
{  
  char *oldtype;
  int g, h, i, j, k;
  HPoint3 *point4 = NULL;
  ColorA *color = NULL;
  Point3 *normal = NULL;
  int npoly = 0;
  int *nvert = NULL, *vert = NULL;
  PolyList *new = NULL;
  int flags = 0;
  int transpts = 1;
  int fourd = 0;

  if (old == NULL) return NULL;
  oldtype = GeomName(old);
  
  /* 
   * PolyList to PolyList 
   */
  if (!strcmp(oldtype, "polylist")) {
    new = (PolyList *) GeomCopy(old);
    flags = new->flags;
  }
  

  /*
   * Bezier to PolyList
   */
  if (!strcmp(oldtype, "bezier")) {
    Bezier *b = (Bezier *)old;

    if ((b->mesh == NULL || 
	 b->mesh->nu != b->nu ||
	 b->mesh->nv != b->nv) || 
	(b->flag & BEZ_REMESH)) BezierReDice(b);
    if (b->geomflags & VERT_4D) fourd = 1;
    return(AnyToPL((Geom *)b->mesh, T));
  }

  /*
   * Quad to PolyList 
   */ 
  if (!strcmp(oldtype, "quad")) {
    Quad *o = (Quad *)old;
    
    /* Copy vertices */
    point4 = (HPoint3 *)OOG_NewE(o->maxquad * 4 * sizeof(HPoint3), msg);
    for (i = 0; i < o->maxquad; i ++) 
      for (j = 0; j < 4; j++) HPt3Copy(&o->p[i][j], &point4[(i*4) + j]);
    
    /* Copy the colors if necessary. */
    if (o->flag & QUAD_C) {
      flags |= PL_HASVCOL;
      color = (ColorA *)OOG_NewE(o->maxquad * 4 * sizeof(ColorA), msg);
      for (i = 0; i < o->maxquad; i++)
	for (j = 0; j < 4; j++)
	  bcopy(&o->c[i][j], &color[(i*4) + j], sizeof(ColorA));
    }

    /* Copy the normals if necessary. */
    if (o->flag & QUAD_N) {
      flags |= PL_HASVN;
      normal = (Point3 *)OOG_NewE(o->maxquad * 4 * sizeof(Point3), msg);
      for (i = 0; i < o->maxquad; i++)
	for (j = 0; j < 4; j++) Pt3Copy(&o->n[i][j], &normal[(i*4) + j]);
    }
    
    /* Create the polygons. */
    nvert = (int *)OOG_NewE(o->maxquad * sizeof(int), msg);
    vert = (int *)OOG_NewE(o->maxquad * 4 * sizeof(int), msg);
    for (i = 0; i < o->maxquad; i++) {
      nvert[i] = 4; 
      for (j = 0; j < 4; j++) vert[(i*4) + j] = (i*4) + j;
    }

    if (o->geomflags & VERT_4D) fourd = 1;
    
    npoly = o->maxquad;
        
  }
  
  
  /* 
   * Mesh to PolyList
   */
  if (!strcmp(oldtype, "mesh")) {
    Mesh *m = (Mesh *)old;
    
    /* Copy vertices. */
    point4 = m->p;
    
    /* Copy the colors. */
    if (m->flag & MESH_C) {
      flags |= PL_HASVCOL;
      color = m->c;
    }

    /* Copy the normals */
    if (m->flag & MESH_N) {
      flags |= PL_HASVN;
      normal = m->n;
    }

    /* Create the polygons. */
    npoly = m->nu * m->nv;
    nvert = (int *)OOG_NewE(npoly * sizeof(int), msg);
    vert = (int *)OOG_NewE(npoly * 4 * sizeof(int), msg);
    for (i = 0; i < m->nv - 1; i++) 
      for (j = 0; j < m->nu - 1; j++) {
	nvert[i * (m->nu - 1) + j] = 4;
	vert[(i * (m->nu - 1) + j) * 4] = i * m->nu + j;
	vert[(i * (m->nu - 1) + j) * 4 + 1] = i * m->nu + j + 1;
	vert[(i * (m->nu - 1) + j) * 4 + 2] = (i + 1) * m->nu + j + 1;
	vert[(i * (m->nu - 1) + j) * 4 + 3] = (i + 1) * m->nu + j;
      }
    /* Do the wrapping if necessary. */
    npoly = (m->nu - 1) * (m->nv - 1);
    if (m->flag & MESH_UWRAP) {
      j = m->nu - 1;
      for (i = 0; i < m->nv - 1; i++) {
	nvert[npoly] = 4;
	vert[npoly * 4] = i * m->nu + j;
	vert[npoly * 4 + 1] = i * m->nu;
	vert[npoly * 4 + 2] = (i + 1) * m->nu;
	vert[npoly++ * 4 + 3] = (i + 1) * m->nu + j;
      }
    }
    if (m->flag & MESH_VWRAP) {
      i = m->nv - 1;
      for (j = 0; j < m->nu - 1; j++) {
	nvert[npoly] = 4;
	vert[npoly * 4] = i * m->nu + j;
	vert[npoly * 4 + 1] = i *m->nu + j + 1;
	vert[npoly * 4 + 2] = j + 1;
	vert[npoly++ * 4 + 3] = j;
      }
    }
    if (m->flag & MESH_UWRAP && m->flag & MESH_VWRAP) {
      nvert[npoly] = 4;
      vert[npoly * 4] = m->nu * m->nv - 1;
      vert[npoly * 4 + 1] = (m->nv - 1) * m->nu;
      vert[npoly * 4 + 2] = 0;
      vert[npoly++ * 4 + 3] = m->nu - 1; 
    }

    if (m->geomflags & VERT_4D) fourd = 1;

  }
  
  
  
  /* 
   * Vect to PolyList
   */
  if (!strcmp(oldtype, "vect")) {
    Vect *v = (Vect *)old;
    
    /* Copy points. */
    point4 = v->p;

    /* Copy colors. */
    if (v->ncolor) {
      flags |= PL_HASVCOL;
      color = OOGLNewNE(ColorA, 2 * v->nvert, msg);
      for (g = h = i = 0; h < v->nvec; h++) {
	if (h && v->vncolor[h]) i++;
	for (j = k = 0; j < abs(v->vnvert[h]); j++) {
	  bcopy(&v->c[i + k], &color[g++], sizeof(ColorA));
	  if (k + 1 < v->vncolor[h]) k++;
	}
	i += k;
      }
    }
    
    /* Create polygons to connect the points. */
    nvert = (int *)OOG_NewE(v->nvert * sizeof(int), msg);
    for (i = 0; i < v->nvert; i++) nvert[i] = 2;
    vert = (int *)OOG_NewE(v->nvert * 2 * sizeof(int), msg);
    for (h = i = k = 0; i < v->nvec; i++) {
      for (j = 0; j < abs(v->vnvert[i]);) {
	vert[h++] = k+j++;
	vert[h++] = k+j;
      }
      if (j) h -= 2;
      if (v->vnvert[i] < 0) {
	vert[h++] = k;
	vert[h++] = k+j-1;
      }
      k += j;
    }

    npoly = h/2;
    
    if (v->geomflags & VERT_4D) fourd = 1;

  }
    

  /* 
   * List to PolyList
   */
  if (!strcmp(oldtype, "list") || !strcmp(oldtype, "bezierlist")) {
    List *l = (List *)old;
    Geom *a, *b;
    
    new = (PolyList *)PLCombine(a = AnyToPL((Geom *)l->car, T), 
				b = AnyToPL((Geom *)l->cdr, T));
    GeomDelete(a);
    GeomDelete(b);

    transpts = 0;

    if (l->geomflags & VERT_4D) fourd = 1;
    
  }
  
    
  /* 
   * DiscGrp to PolyList
   */
  if (!strcmp(oldtype, "discgrp") ) {
    DiscGrp *dg = (DiscGrp *)old;
    Geom *geom = NULL, *geom2;
    PolyList *a = NULL, *b = NULL, *c = NULL, *d = NULL;
    Transform Tnew, Tnew2;
    
    if (dg->geom) geom = dg->geom;
    else if (dg->ddgeom) geom = dg->ddgeom;
    else geom = DiscGrpDirDom(dg);
    a = (PolyList *) AnyToPL(geom, TM_IDENTITY);
    b = (PolyList *) GeomCopy( (Geom *) a);
    if (dg->camgeom) 
	{
        c = (PolyList *) AnyToPL(geom, TM_IDENTITY);
	d = (PolyList *) GeomCopy( (Geom *) c);
	}

    /* this isn'tgoing to be right as long as appearances aren't respected.
    The dirichlet domain code (see /u/gcg/ngrap/src/lib/gprim/discgrp/dgdraw.c)
    has to resort to applying appearances in its inner loop in order to get
    the large copy to be drawn as edges only, and the inner as faces.
    That file shows what the reasonable behaviour should be if 
    appearances were respected (see the #ifdef REASONABLE code). */

    /* the DiscGrp object should support the GeomIterate construct, but
    it doesn't */
    for (i=0; i<dg->big_list->num_el; ++i)
    {
      TmConcat(dg->big_list->el_list[i].tform, T, Tnew); 
      PLTransformInto(a, b, Tnew);
      new = (PolyList *)PLCombine((Geom *)new, (Geom *)b);
      /* maybe need to draw the camera too */
      if (dg->flag & DG_CENTERCAM && dg->camgeom)	{
        TmConcat(dg->c2m, Tnew, Tnew2);
        PLTransformInto(c, d, Tnew);
        new = (PolyList *)PLCombine((Geom *)new, (Geom *)d);
	}
    }
    if (a) GeomDelete((Geom *)a);
    if (b) GeomDelete((Geom *)b);
    if (c) GeomDelete((Geom *)c);
    if (d) GeomDelete((Geom *)d);

    transpts = 0;

    if (dg->geomflags & VERT_4D) fourd = 1;
    
  }
  
    
  /* 
   * Inst to PolyList 
   */
  if (!strcmp(oldtype, "inst")) {
    Inst *inst = (Inst *)old;
    Transform Tnew;
    GeomIter *it;
    PolyList *a, *b;
    
    a = (PolyList *)AnyToPL(inst->geom, TM_IDENTITY);
    b = (PolyList *)GeomCopy((Geom *)a);
    it = GeomIterate((Geom *)inst, DEEP);
    while (NextTransform(it, Tnew)) {
      TmConcat(Tnew, T, Tnew); 
      PLTransformInto(a, b, Tnew);
      new = (PolyList *)PLCombine((Geom *)new, (Geom *)b);
    }
    GeomDelete((Geom *)a);
    GeomDelete((Geom *)b);

    transpts = 0;

    if (inst->geomflags & VERT_4D) fourd = 1;

  }
    
  /* Create the new object */
  if (new == NULL && npoly) new = (PolyList *) 
    GeomCreate("polylist", 
	       CR_NPOLY, npoly,
	       CR_POINT4, point4,
	       CR_COLOR, color,
	       CR_NORMAL, normal,
	       CR_NVERT, nvert,
	       CR_VERT, vert,
	       CR_FLAG, flags,
	       CR_4D, fourd,
	       CR_END);

  if (strcmp(oldtype, "mesh")) {
    if (strcmp(oldtype, "vect") && point4 != NULL) OOGLFree(point4);
    if (color != NULL) OOGLFree(color);
    if (nvert != NULL) OOGLFree(nvert);
    if (vert != NULL) OOGLFree(vert);
  }

  if (new == NULL) return NULL;
  
  /* Apply the transformation. */
  if (transpts) 
    for (i = 0; i < new->n_verts; i++) {
      HPt3Transform(T, &new->vl[i].pt, &new->vl[i].pt);
      if (!(new->geomflags & VERT_4D))
	HPt3Dehomogenize(&new->vl[i].pt, &new->vl[i].pt);
    }

  return((Geom *)new);
  
}


/* 
 * This routine transforms the points of src and places them in dest, 
 * which had better be exactely the same size. 
 */
void PLTransformInto(PolyList *src, PolyList *dest, Transform T) {
  if (src == NULL || dest == NULL) return;
  bcopy(src->vl, dest->vl, src->n_verts * sizeof(Vertex));
  GeomTransform((Geom *)dest, T);
}

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