ftp.nice.ch/pub/next/graphics/3d/geomview.1.4.1.s.tar.gz#/Geomview/src/bin/pssnap/common/pssnap.c

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.