home *** CD-ROM | disk | FTP | other *** search
- /*
- * pssnap.c
- * author: Celeste Fowler
- * date: June 12, 1992
- */
-
- #include <stdio.h>
- #include <math.h>
- #include <time.h>
- #include "geom.h"
- #include "polylistP.h"
- #include "camera.h"
- #include "hpoint3.h"
- #include "point3.h"
- #include "bbox.h"
- #include "sortbyz.h"
- #include "plutil.h"
- #include "pssnap.h"
-
- #define min(a, b) ((a) < (b) ? (a) : (b))
- #define max(a, b) ((a) > (b) ? (a) : (b))
-
- static float camaspect = 1.0;
- static float Ks = 0.3;
-
- Geom *PolyProject(Geom *o, Camera *c) {
- int i, j;
- Geom *onew;
- PolyList *p;
- Transform T;
-
- onew = (Geom *)AnyToPL(o, TM_IDENTITY);
- if (onew == NULL) return NULL;
-
- /* Perform all the transformations except the projection. */
- CamGet(c, CAM_W2C, T);
- GeomTransform(onew, T);
-
- p = (PolyList *)onew;
-
- /* Get rid of all the polygons that have a vertex which is
- * behind the camera */
- for (i = 0; i < p->n_polys; i++)
- for (j = 0; j < p->p[i].n_vertices; j++)
- if (p->p[i].v[j]->pt.z > 0.0) {
- p->p[i].n_vertices = 0;
- j = p->p[i].n_vertices;
- }
-
- /* Do the (pseudo) z-buffering */
- o = SortByZ(onew);
- GeomDelete(onew);
- onew = o;
-
- PolyListComputeNormals((PolyList *)onew, NULL);
-
- /* Do the projection. */
- CamViewProjection(c, T);
- p = (PolyList *)onew;
- for (i = 0; i < p->n_verts; i++)
- HPt3TransPt3(T, &p->vl[i].pt, &p->vl[i].pt);
-
- CamGet(c, CAM_ASPECT, &camaspect);
-
- return(onew);
-
- }
-
- #define setcolor(c) \
- if (flag & PS_COLOR) \
- fprintf(outfile, "%.2f %.2f %.2f\n", (float)c.r, (float)c.g, (float)c.b); \
- else fprintf(outfile, "%.2f\n", .299 * c.r + .587 * c.g + .114 * c.b);
-
- /*
- * PolyToPSInit
- * Output the polygon - drawing routines. Sets up the viewing area as a
- * seven inch by seven inch box. Assumes a paper size of 8.5 x 11 inches.
- */
- void PolyToPSInit(FILE *outfile, int flag) {
- time_t tm;
- float xrange = 3.5*72, yrange = 3.5*72;
- float xmid = 8.5*.5*72, ymid = 11*.5*72;
-
- if(camaspect > 1) yrange /= camaspect;
- else xrange *= camaspect;
-
- time(&tm);
-
- fprintf(outfile, "%%!PS-Adobe-2.0 EPSF-1.2\n");
- fprintf(outfile, "%%%%Title: PSSnapshot\n");
- fprintf(outfile, "%%%%Creator: pssnap.c\n");
- fprintf(outfile, "%%%%CreationDate: %s", ctime(&tm));
- fprintf(outfile, "%%%%For: %s\n", (char *)getlogin());
- fprintf(outfile, "%%%%Pages: 0 1\n");
- fprintf(outfile, "%%%%BoundingBox: %d %d %d %d\n",
- (int)(xmid - 1.02*xrange), (int)(ymid - 1.02*yrange),
- (int)(xmid + 1.02*xrange), (int)(ymid + 1.02*yrange));
- fprintf(outfile, "%%%%EndComments \n");
-
- fprintf(outfile, "currentdict /edgecolor known not { /edgecolor {");
- fprintf(outfile, (flag & PS_COLOR) ? "0 0 0 setrgbcolor" : "0 setgray");
- fprintf(outfile, "} def } if\n");
-
- fprintf(outfile, "/drawpoly { ");
-
- if (flag & PS_COLOR) fprintf(outfile, "setrgbcolor ");
- else fprintf(outfile, "setgray ");
-
- fprintf(outfile, "newpath ");
- fprintf(outfile, "moveto ");
- fprintf(outfile, "count 4 ge {\n");
- fprintf(outfile, " count 2 idiv { lineto } repeat closepath\n");
- switch(flag & (PS_FACES|PS_EDGES)) {
- case PS_FACES: fprintf(outfile, "\tfill");
- case PS_EDGES: fprintf(outfile, "\tedgecolor stroke");
- case PS_FACES|PS_EDGES: fprintf(outfile, "\tgsave fill grestore edgecolor stroke");
- }
- fprintf(outfile, " }\n");
- fprintf(outfile, " { count 2 eq {lineto} {0 0 rmoveto} ifelse stroke }\n");
- fprintf(outfile, " ifelse\n");
- fprintf(outfile, "} def \n");
- fprintf(outfile, "/NaN { 0 } def \n");
- fprintf(outfile, "%f %f translate %f %f scale\n",
- xmid, ymid, xrange, yrange);
-
- fprintf(outfile, ".001 setlinewidth\n");
- fprintf(outfile, "1 setlinejoin\n");
-
- /* This is equivalent to rectclip, but isn't rectclip because
- * rectclip is a level 2 thing. */
- fprintf(outfile, "newpath -1.0 -1.0 moveto\n\
- 2.0 0 rlineto 0 2.0 rlineto 2.0 neg 0 rlineto\n\
- closepath clip newpath\n");
-
- }
-
- void PolyToPS(Geom *o, FILE *outfile, int flag) {
- int i, j;
- PolyList *p = (PolyList *)o;
- ColorA c;
- Point3 *pn, n;
- double cosine, specular;
-
- if (o == NULL) return;
-
- c.r = c.g = c.b = .9;
- n.x = n.y = 0;
- n.z = 1;
-
- fprintf(outfile, "%%%% Min: -1.0 -1.0 Max: 1.0 1.0\n");
- fprintf(outfile, "gsave\n");
-
- for (i = 0; i < p->n_polys; i++) if (p->p[i].n_vertices) {
- for (j = 0; j < p->p[i].n_vertices; j++)
- fprintf(outfile, "%f %f\n", p->p[i].v[j]->pt.x, p->p[i].v[j]->pt.y);
-
- if (p->flags & PL_HASPCOL) c = p->p[i].pcol;
- else if (p->flags & PL_HASVCOL && p->p[i].n_vertices)
- c = p->p[i].v[0]->vcol;
- else c.r = c.g = c.b = .9;
-
- /* Figure out the normal vector of the polygon. */
- pn = &n;
- if (p->p[i].n_vertices > 2) {
- if (p->flags & PL_HASPN) pn = &p->p[i].pn;
- else if (p->flags & PL_HASVN && p->p[i].n_vertices)
- pn = &p->p[i].v[0]->vn;
-
- /* Find the cosine between the normal vector and (0, 0, 1) */
- cosine = fabs(Pt3Dot(pn, &n) / (Pt3Length(pn) * Pt3Length(&n)));
-
- /* Multiply the color by the cosine. */
- c.r *= cosine;
- c.g *= cosine;
- c.b *= cosine;
-
- /* Add Ks*cos(theta)^8 specular highlight */
- specular = cosine*cosine;
- specular *= specular;
- specular *= Ks*specular;
- c.r += specular; c.g += specular; c.b += specular;
- }
-
- setcolor(c);
-
- fprintf(outfile, "drawpoly\n");
- }
-
- fprintf(outfile, "grestore\n");
-
- }
-
-