This is pssnap.c in view mode; [Download] [Up]
/* * 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"); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.