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.