home *** CD-ROM | disk | FTP | other *** search
- /*
- * 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);
- }
-