home *** CD-ROM | disk | FTP | other *** search
/ Compendium Deluxe 2 / LSD and 17bit Compendium Deluxe - Volume II.iso / a / prog / cprog / tdddconv.lha / writeps.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-11-12  |  8.3 KB  |  270 lines

  1. /* writeps.c - routines to output PostScript representation of object
  2.  *           - using TTDDDLIB by Glenn M. Lewis - 7/23/91
  3.  */
  4.  
  5. static char rcs_id[] = "$Id: writeps.c,v 1.10 1991/11/01 16:18:54 glewis Exp glewis $";
  6.  
  7. #include <stdio.h>
  8. #include "ttdddlib.h"
  9.  
  10. double XSIZE = 8.5;
  11. double YSIZE = 11.0;
  12. #define MARGIN    (0.25)    /* On each side of the page */
  13. #define PPI    (72.0)
  14. #define COS60    (0.5)
  15. #define COS30    (0.8660)
  16.  
  17. static void write_PS_header();
  18. static void draw_PS_view();
  19. static void render_PS_object();
  20.  
  21. static FILE *out;
  22. static WORLD *world;
  23. static MBB mbb;
  24. static double xsize, ysize;
  25. static int view;
  26. static double xoffset, yoffset, scale, ybottom;
  27.  
  28. int write_PostScript(object, file, selected_view)
  29. WORLD *object;
  30. FILE *file;
  31. int selected_view;
  32. {
  33.     double llx, lly;
  34.     register OBJECT *obj;
  35.     if (!(out = file)) return(0);        /* File not open */
  36.     if (!(world = object)) return(0);    /* No object */
  37.  
  38.     /* Determine the extent of the world object */
  39.     mbb.minx = mbb.miny = mbb.minz =  1.0e10;
  40.     mbb.maxx = mbb.maxy = mbb.maxz = -1.0e10;
  41.     for (obj=world->object; obj; obj=obj->next) {
  42.         calculate_MBB(obj);
  43.         if (!obj->user) continue;
  44.         if (((MBB*)obj->user)->minx<mbb.minx) mbb.minx = ((MBB*)obj->user)->minx;
  45.         if (((MBB*)obj->user)->miny<mbb.miny) mbb.miny = ((MBB*)obj->user)->miny;
  46.         if (((MBB*)obj->user)->minz<mbb.minz) mbb.minz = ((MBB*)obj->user)->minz;
  47.         if (((MBB*)obj->user)->maxx>mbb.maxx) mbb.maxx = ((MBB*)obj->user)->maxx;
  48.         if (((MBB*)obj->user)->maxy>mbb.maxy) mbb.maxy = ((MBB*)obj->user)->maxy;
  49.         if (((MBB*)obj->user)->maxz>mbb.maxz) mbb.maxz = ((MBB*)obj->user)->maxz;
  50.     }
  51. #ifdef DEBUG
  52.     fprintf(stderr, "MBB: (%g,%g,%g)-(%g,%g,%g)\n",
  53.         mbb.minx, mbb.miny, mbb.minz,
  54.         mbb.maxx, mbb.maxy, mbb.maxz);
  55. #endif
  56.  
  57.     write_PS_header();
  58.     if (selected_view==VIEW_ALL_FOUR) {
  59.         for (view=0; view<4; view++) {
  60.             llx = ((view&0x02) ? XSIZE/2.0 : MARGIN) * PPI;
  61.             lly = ((view&0x01) ? MARGIN : YSIZE/2.0) * PPI;
  62.             xsize = PPI*(XSIZE/2.0 - MARGIN);
  63.             ysize = PPI*(YSIZE/2.0 - MARGIN);
  64.             fprintf(out, "gsave\n0.1 setlinewidth\n%g %g translate\n", llx, lly);
  65.             draw_PS_view();
  66.             fprintf(out, "grestore\n");
  67.         }
  68.     } else {
  69.         xsize = PPI*(XSIZE - 2.0*MARGIN);
  70.         ysize = PPI*(YSIZE - 2.0*MARGIN);
  71.         fprintf(out,"0.1 setlinewidth\n%g %g translate\n",PPI*MARGIN,PPI*MARGIN);
  72.         view=selected_view;
  73.         draw_PS_view();
  74.     }
  75.     fprintf(out, "showpage\n");
  76.     return(1);
  77. }
  78.  
  79. void calculate_MBB(obj)
  80. OBJECT *obj;
  81. {
  82.     OBJECT *child;
  83.     register XYZ_st *p;
  84.     register int i;
  85.     MBB *mbb;
  86.     double x, y, z;
  87.  
  88.     if (!obj->desc) return;    /* Not an object */
  89.     if (obj->user) { free((char*)obj->user); obj->user=0; }
  90.  
  91.     if (!(mbb = (MBB*)malloc(sizeof(MBB)))) {
  92.         fputs("Out of memory", out); exit(-1); }
  93.     mbb->minx = mbb->miny = mbb->minz =  1.0e10;
  94.     mbb->maxx = mbb->maxy = mbb->maxz = -1.0e10;
  95.  
  96.     /* Account for children... */
  97.     for (child=obj->child; child; child=child->next) {
  98.         calculate_MBB(child);
  99.         if (!child->user) continue;
  100.         if (((MBB*)child->user)->minx < mbb->minx)
  101.             mbb->minx = ((MBB*)child->user)->minx;
  102.         if (((MBB*)child->user)->miny < mbb->miny)
  103.             mbb->miny = ((MBB*)child->user)->miny;
  104.         if (((MBB*)child->user)->minz < mbb->minz)
  105.             mbb->minz = ((MBB*)child->user)->minz;
  106.         if (((MBB*)child->user)->maxx > mbb->maxx)
  107.             mbb->maxx = ((MBB*)child->user)->maxx;
  108.         if (((MBB*)child->user)->maxy > mbb->maxy)
  109.             mbb->maxy = ((MBB*)child->user)->maxy;
  110.         if (((MBB*)child->user)->maxz > mbb->maxz)
  111.             mbb->maxz = ((MBB*)child->user)->maxz;
  112.     }
  113.  
  114.     x = y = z = 0.0;
  115. /*
  116.     if (obj->desc->posi) {
  117.         x = obj->desc->posi->val[0];
  118.         y = obj->desc->posi->val[1];
  119.         z = obj->desc->posi->val[2];
  120.         fprintf(out, "position: %lx (%g,%g,%g)\n", (unsigned long)obj,x,y,z);
  121.     }
  122. */
  123.     for (p=obj->desc->pnts,i=obj->desc->pcount; i--; p++) {
  124.         if (p->val[0]-x < mbb->minx) mbb->minx = p->val[0]-x;
  125.         if (p->val[1]-y < mbb->miny) mbb->miny = p->val[1]-y;
  126.         if (p->val[2]-z < mbb->minz) mbb->minz = p->val[2]-z;
  127.         if (p->val[0]-x > mbb->maxx) mbb->maxx = p->val[0]-x;
  128.         if (p->val[1]-y > mbb->maxy) mbb->maxy = p->val[1]-y;
  129.         if (p->val[2]-z > mbb->maxz) mbb->maxz = p->val[2]-z;
  130.     }
  131.     obj->user = (void *)mbb;
  132. #ifdef DEBUG
  133.     fprintf(stderr, "MBB: %lx child:%lx next:%lx (%g,%g,%g)-(%g,%g,%g)\n",
  134.         (unsigned long)obj,
  135.         (unsigned long)obj->child,
  136.         (unsigned long)obj->next,
  137.         mbb->minx, mbb->miny, mbb->minz,
  138.         mbb->maxx, mbb->maxy, mbb->maxz);
  139. #endif
  140. }
  141.  
  142. static void write_PS_header()
  143. {
  144.     fputs("%!PS-Adobe-2.0 EPSF-1.2\n", out);
  145.     fprintf(out, "%%%%BoundingBox: %g %g %g %g\n",
  146.         PPI*MARGIN, PPI*MARGIN, PPI*(XSIZE-2.0*MARGIN), PPI*(YSIZE-2.0*MARGIN));
  147.     fputs("%%Creator: TTDDDLIB by Glenn M. Lewis\n", out);
  148.     fputs("%%EndComments\n%%BeginSetup\n", out);
  149.     fputs("/M {moveto} bind def\n", out);
  150.     fputs("/D {lineto} bind def\n", out);
  151.     fputs("/S {stroke} bind def\n", out);
  152.     fputs("%%EndSetup\n", out);
  153. }
  154.  
  155. static void draw_PS_view()
  156. {
  157.     double xratio, yratio, zratio;
  158.     OBJECT *obj;
  159.     fprintf(out, "0 0 M %g 0 D %g %g D 0 %g D 0 0 D S\n",
  160.         xsize, xsize, ysize, ysize);
  161.  
  162.     if (mbb.maxx-mbb.minx>0.0) xratio=1.0/(mbb.maxx-mbb.minx); else xratio=1.0;
  163.     if (mbb.maxy-mbb.miny>0.0) yratio=1.0/(mbb.maxy-mbb.miny); else yratio=1.0;
  164.     if (mbb.maxz-mbb.minz>0.0) zratio=1.0/(mbb.maxz-mbb.minz); else zratio=1.0;
  165.     scale = (ysize*yratio < xsize*yratio ? ysize*yratio : xsize*yratio);
  166.     scale = (scale        < ysize*zratio ? scale        : ysize*zratio);
  167.     scale = (scale        < xsize*xratio ? scale        : xsize*xratio);
  168.  
  169.     switch(view) {
  170.         case VIEW_TOP:
  171.             fputs("% Top view\n", out);
  172.             xoffset = (xsize-scale/xratio)/2.0;
  173.             yoffset = (ysize-scale/yratio)/2.0;
  174.             break;
  175.         case VIEW_FRONT:
  176.             fputs("% Front view\n", out);
  177.             xoffset = (xsize-scale/xratio)/2.0;
  178.             yoffset = (ysize-scale/zratio)/2.0;
  179.             break;
  180.         case VIEW_ISO:
  181.             fputs("% Isometric view\n", out);
  182.             xratio = (mbb.maxx-mbb.minx)*COS30+(mbb.maxy-mbb.miny)*COS30;
  183.             if (xratio>0.0) xratio = 1.0/xratio; else xratio=1.0;
  184.             ybottom = -(mbb.maxx-mbb.minx)*COS60;
  185.             yratio = (mbb.maxz-mbb.minz)+(mbb.maxy-mbb.miny)*COS60    /* Top */
  186.                      - ybottom;
  187.             if (yratio>0.0) yratio = 1.0/yratio; else yratio=1.0;
  188.             scale = (xsize*xratio < ysize*yratio ? xsize*xratio : ysize*yratio);
  189.             xoffset = (xsize-scale/xratio)/2.0;
  190.             yoffset = (ysize-scale/yratio)/2.0;
  191.             break;
  192.         case VIEW_RIGHT:
  193.             fputs("% Right view\n", out);
  194.             xoffset = (xsize-scale/yratio)/2.0;
  195.             yoffset = (ysize-scale/zratio)/2.0;
  196.             break;
  197.     }
  198.     for (obj=world->object; obj; obj=obj->next)
  199.         render_PS_object(obj);
  200. }
  201.  
  202. static void render_PS_object(obj)
  203. register OBJECT *obj;
  204. {
  205.     register UWORD *f;
  206.     register OBJECT *op;
  207.     register int i, j;
  208.     int p[3];
  209.     double x[3], y[3];
  210.  
  211.     if (!obj->desc) return;
  212.     for (op=obj->child; op; op=op->next)    /* render children first */
  213.         render_PS_object(op);
  214.     
  215.     /* Now, the meat... */
  216.     if (obj->desc->shap && obj->desc->shap[1]!=0) return;    /* A lamp */
  217.     if (!obj->desc->edge || !obj->desc->pnts || !obj->desc->face) return;
  218.     for (f=obj->desc->face,i=obj->desc->fcount; i--; f+=3) {
  219.         p[0] = obj->desc->edge[((*f)<<1)];
  220.         p[1] = obj->desc->edge[((*f)<<1)+1];
  221.         if (obj->desc->edge[((f[1])<<1)] == p[0] ||
  222.             obj->desc->edge[((f[1])<<1)] == p[1])
  223.             p[2] = obj->desc->edge[((f[1])<<1)+1];
  224.         else
  225.             p[2] = obj->desc->edge[((f[1])<<1)];
  226.         switch(view) {
  227.             case VIEW_TOP:
  228.                 for (j=3; j--; ) {
  229.                     x[j] = obj->desc->pnts[p[j]].val[0]-mbb.minx;
  230.                     y[j] = obj->desc->pnts[p[j]].val[1]-mbb.miny;
  231.                 }
  232.                 break;
  233.             case VIEW_FRONT:
  234.                 for (j=3; j--; ) {
  235.                     x[j] = obj->desc->pnts[p[j]].val[0]-mbb.minx;
  236.                     y[j] = obj->desc->pnts[p[j]].val[2]-mbb.minz;
  237.                 }
  238.                 break;
  239.             case VIEW_ISO:
  240.                 for (j=3; j--; ) {
  241.                     x[j] = (obj->desc->pnts[p[j]].val[0]-mbb.minx)*COS30
  242.                           +(obj->desc->pnts[p[j]].val[1]-mbb.miny)*COS30;
  243.                     y[j] = (obj->desc->pnts[p[j]].val[2]-mbb.minz)
  244.                           -(obj->desc->pnts[p[j]].val[0]-mbb.minx)*COS60
  245.                           +(obj->desc->pnts[p[j]].val[1]-mbb.miny)*COS60
  246.                           - ybottom;
  247.                 }
  248.                 break;
  249.             case VIEW_RIGHT:
  250.                 for (j=3; j--; ) {
  251.                     x[j] = obj->desc->pnts[p[j]].val[1]-mbb.miny;
  252.                     y[j] = obj->desc->pnts[p[j]].val[2]-mbb.minz;
  253.                 }
  254.                 break;
  255.         }
  256.         if (x[0]==x[1] && x[1]==x[2] && y[0]==y[1] && y[1]==y[2]) continue;
  257.         fprintf(out, "%0.2lf %0.2lf M ", xoffset+scale*x[0],yoffset+scale*y[0]);
  258.         if (!(x[0]==x[1] && y[0]==y[1])) {
  259.             fprintf(out, "%0.2lf %0.2lf D ",
  260.                 xoffset+scale*x[1], yoffset+scale*y[1]);
  261.         }
  262.         if (!(x[0]==x[2] && y[0]==y[2]) && !(x[1]==x[2] && y[1]==y[2])) {
  263.             fprintf(out, "%0.2lf %0.2lf D ",
  264.                 xoffset+scale*x[2], yoffset+scale*y[2]);
  265.         }
  266.         fprintf(out, "%0.2lf %0.2lf D S\n",
  267.             xoffset+scale*x[0],yoffset+scale*y[0]);
  268.     }
  269. }
  270.