home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / modelers / geomview / source.lha / Geomview / src / bin / pssnap / common / pssnap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-09  |  5.1 KB  |  193 lines

  1. /*
  2.  * pssnap.c
  3.  * author:  Celeste Fowler
  4.  * date:  June 12, 1992
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include <math.h>
  9. #include <time.h>
  10. #include "geom.h"
  11. #include "polylistP.h"
  12. #include "camera.h"
  13. #include "hpoint3.h"
  14. #include "point3.h"
  15. #include "bbox.h"
  16. #include "sortbyz.h"
  17. #include "plutil.h"
  18. #include "pssnap.h"
  19.  
  20. #define min(a, b) ((a) < (b) ? (a) : (b))
  21. #define max(a, b) ((a) > (b) ? (a) : (b))
  22.  
  23. static float camaspect = 1.0;
  24. static float Ks = 0.3;
  25.  
  26. Geom *PolyProject(Geom *o, Camera *c) {
  27.   int i, j;
  28.   Geom *onew;
  29.   PolyList *p;
  30.   Transform T;
  31.  
  32.   onew = (Geom *)AnyToPL(o, TM_IDENTITY);
  33.   if (onew == NULL) return NULL;
  34.  
  35.   /* Perform all the transformations except the projection. */
  36.   CamGet(c, CAM_W2C, T);
  37.   GeomTransform(onew, T);
  38.  
  39.   p = (PolyList *)onew;
  40.  
  41.   /* Get rid of all the polygons that have a vertex which is 
  42.    * behind the camera */
  43.   for (i = 0; i < p->n_polys; i++)
  44.     for (j = 0; j < p->p[i].n_vertices; j++) 
  45.       if (p->p[i].v[j]->pt.z > 0.0) {
  46.     p->p[i].n_vertices = 0;
  47.     j = p->p[i].n_vertices;
  48.       }
  49.  
  50.   /* Do the (pseudo) z-buffering */
  51.   o = SortByZ(onew);
  52.   GeomDelete(onew);
  53.   onew = o;
  54.  
  55.   PolyListComputeNormals((PolyList *)onew, NULL);
  56.  
  57.   /* Do the projection. */
  58.   CamViewProjection(c, T);
  59.   p = (PolyList *)onew;
  60.   for (i = 0; i < p->n_verts; i++) 
  61.     HPt3TransPt3(T, &p->vl[i].pt, &p->vl[i].pt);
  62.  
  63.   CamGet(c, CAM_ASPECT, &camaspect);
  64.  
  65.   return(onew);
  66.  
  67. }
  68.   
  69. #define setcolor(c) \
  70.   if (flag & PS_COLOR) \
  71.   fprintf(outfile, "%.2f %.2f %.2f\n", (float)c.r, (float)c.g, (float)c.b); \
  72.   else fprintf(outfile, "%.2f\n", .299 * c.r + .587 * c.g + .114 * c.b);
  73.  
  74. /* 
  75.  * PolyToPSInit 
  76.  * Output the polygon - drawing routines.   Sets up the viewing area as a
  77.  * seven inch by seven inch box.  Assumes a paper size of 8.5 x 11 inches.
  78.  */
  79. void PolyToPSInit(FILE *outfile, int flag) {
  80.   time_t tm;
  81.   float xrange = 3.5*72, yrange = 3.5*72;
  82.   float xmid = 8.5*.5*72, ymid = 11*.5*72;
  83.  
  84.   if(camaspect > 1) yrange /= camaspect;
  85.   else xrange *= camaspect;
  86.  
  87.   time(&tm);
  88.  
  89.   fprintf(outfile, "%%!PS-Adobe-2.0 EPSF-1.2\n");
  90.   fprintf(outfile, "%%%%Title: PSSnapshot\n");
  91.   fprintf(outfile, "%%%%Creator: pssnap.c\n");
  92.   fprintf(outfile, "%%%%CreationDate: %s", ctime(&tm));
  93.   fprintf(outfile, "%%%%For: %s\n", (char *)getlogin());
  94.   fprintf(outfile, "%%%%Pages: 0 1\n");
  95.   fprintf(outfile, "%%%%BoundingBox: %d %d %d %d\n",
  96.     (int)(xmid - 1.02*xrange), (int)(ymid - 1.02*yrange),
  97.     (int)(xmid + 1.02*xrange), (int)(ymid + 1.02*yrange));
  98.   fprintf(outfile, "%%%%EndComments \n");
  99.  
  100.   fprintf(outfile, "currentdict /edgecolor known not { /edgecolor {");
  101.   fprintf(outfile, (flag & PS_COLOR) ? "0 0 0 setrgbcolor" : "0 setgray");
  102.   fprintf(outfile, "} def } if\n");
  103.  
  104.   fprintf(outfile, "/drawpoly { ");
  105.  
  106.   if (flag & PS_COLOR) fprintf(outfile, "setrgbcolor ");
  107.   else fprintf(outfile, "setgray ");
  108.   
  109.   fprintf(outfile, "newpath "); 
  110.   fprintf(outfile, "moveto ");
  111.   fprintf(outfile, "count 4 ge {\n");
  112.   fprintf(outfile, "   count 2 idiv { lineto } repeat closepath\n");
  113.   switch(flag & (PS_FACES|PS_EDGES)) {
  114.   case PS_FACES: fprintf(outfile, "\tfill");
  115.   case PS_EDGES: fprintf(outfile, "\tedgecolor stroke");
  116.   case PS_FACES|PS_EDGES: fprintf(outfile, "\tgsave fill grestore edgecolor stroke");
  117.   }
  118.   fprintf(outfile, "  }\n");
  119.   fprintf(outfile, "  { count 2 eq {lineto} {0 0 rmoveto} ifelse stroke }\n");
  120.   fprintf(outfile, " ifelse\n");
  121.   fprintf(outfile, "} def \n");
  122.   fprintf(outfile, "/NaN { 0 } def \n");
  123.   fprintf(outfile, "%f %f translate %f %f scale\n",
  124.     xmid, ymid, xrange, yrange);
  125.  
  126.   fprintf(outfile, ".001 setlinewidth\n");  
  127.   fprintf(outfile, "1 setlinejoin\n");
  128.  
  129.   /* This is equivalent to rectclip, but isn't rectclip because 
  130.    * rectclip is a level 2 thing. */
  131.   fprintf(outfile, "newpath -1.0 -1.0 moveto\n\
  132. 2.0 0 rlineto 0 2.0 rlineto 2.0 neg 0 rlineto\n\
  133. closepath clip newpath\n");
  134.  
  135. }
  136.  
  137. void PolyToPS(Geom *o, FILE *outfile, int flag) {
  138.   int i, j;
  139.   PolyList *p = (PolyList *)o;
  140.   ColorA c;
  141.   Point3 *pn, n;
  142.   double cosine, specular;
  143.  
  144.   if (o == NULL) return;
  145.  
  146.   c.r = c.g = c.b = .9;
  147.   n.x = n.y = 0;
  148.   n.z = 1;
  149.   
  150.   fprintf(outfile, "%%%% Min: -1.0 -1.0 Max: 1.0 1.0\n");
  151.   fprintf(outfile, "gsave\n");
  152.  
  153.   for (i = 0; i < p->n_polys; i++) if (p->p[i].n_vertices) {
  154.     for (j = 0; j < p->p[i].n_vertices; j++) 
  155.       fprintf(outfile, "%f %f\n", p->p[i].v[j]->pt.x, p->p[i].v[j]->pt.y);
  156.     
  157.     if (p->flags & PL_HASPCOL) c = p->p[i].pcol;
  158.     else if (p->flags & PL_HASVCOL && p->p[i].n_vertices) 
  159.       c = p->p[i].v[0]->vcol;
  160.     else c.r = c.g = c.b = .9;
  161.  
  162.     /* Figure out the normal vector of the polygon. */
  163.     pn = &n;
  164.     if (p->p[i].n_vertices > 2) {
  165.     if (p->flags & PL_HASPN) pn = &p->p[i].pn;
  166.     else if (p->flags & PL_HASVN && p->p[i].n_vertices) 
  167.         pn = &p->p[i].v[0]->vn;
  168.  
  169.     /* Find the cosine between the normal vector and (0, 0, 1) */
  170.     cosine = fabs(Pt3Dot(pn, &n) / (Pt3Length(pn) * Pt3Length(&n)));
  171.  
  172.     /* Multiply the color by the cosine. */
  173.     c.r *= cosine;
  174.     c.g *= cosine;
  175.     c.b *= cosine;
  176.  
  177.     /* Add Ks*cos(theta)^8 specular highlight */
  178.     specular = cosine*cosine;
  179.     specular *= specular;
  180.     specular *= Ks*specular;
  181.     c.r += specular;  c.g += specular;  c.b += specular;
  182.     }
  183.  
  184.     setcolor(c);
  185.  
  186.     fprintf(outfile, "drawpoly\n");
  187.   }
  188.  
  189.   fprintf(outfile, "grestore\n");
  190.  
  191. }
  192.  
  193.