home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 8 / CDASC08.ISO / NEWS / RADIANCE / SRC / CV / IES2RAD.C < prev    next >
C/C++ Source or Header  |  1993-10-07  |  20KB  |  853 lines

  1. /* Copyright (c) 1992 Regents of the University of California */
  2.  
  3. #ifndef lint
  4. static char SCCSid[] = "@(#)ies2rad.c 2.4 9/8/92 LBL";
  5. #endif
  6.  
  7. /*
  8.  * Convert IES luminaire data to Radiance description
  9.  *
  10.  *    07Apr90        Greg Ward
  11.  */
  12.  
  13. #include <stdio.h>
  14. #include <ctype.h>
  15. #include "color.h"
  16. #include "paths.h"
  17.  
  18. #define PI        3.14159265358979323846
  19.                     /* floating comparisons */
  20. #define FTINY        1e-6
  21. #define FEQ(a,b)    ((a)<=(b)+FTINY&&(a)>=(b)-FTINY)
  22.                     /* tilt specs */
  23. #define TLTSTR        "TILT="
  24. #define TLTSTRLEN    5
  25. #define TLTNONE        "NONE"
  26. #define TLTINCL        "INCLUDE"
  27. #define TLT_VERT    1
  28. #define TLT_H0        2
  29. #define TLT_H90        3
  30.                     /* photometric types */
  31. #define PM_C        1
  32. #define PM_B        2
  33.                     /* unit types */
  34. #define U_FEET        1
  35. #define U_METERS    2
  36.                     /* string lengths */
  37. #define MAXLINE        132
  38. #define MAXWORD        76
  39.                     /* file types */
  40. #define T_RAD        ".rad"
  41. #define T_DST        ".dat"
  42. #define T_TLT        "+.dat"
  43.                     /* shape types */
  44. #define RECT        1
  45. #define DISK        2
  46. #define SPHERE        3
  47.  
  48. #define MINDIM        .001        /* minimum dimension (point source) */
  49.  
  50. #define F_M        .3048        /* feet to meters */
  51.  
  52. #define abspath(p)    (ISDIRSEP((p)[0]) || (p)[0] == '.')
  53.  
  54. static char    default_name[] = "default";
  55.  
  56. char    *libdir = NULL;            /* library directory location */
  57. char    *prefdir = NULL;        /* subdirectory */
  58. char    *lampdat = "lamp.tab";        /* lamp data file */
  59.  
  60. double    meters2out = 1.0;        /* conversion from meters to output */
  61. char    *lamptype = NULL;        /* selected lamp type */
  62. char    *deflamp = NULL;        /* default lamp type */
  63. float    defcolor[3] = {1.,1.,1.};    /* default lamp color */
  64. float    *lampcolor = defcolor;        /* pointer to current lamp color */
  65. double    multiplier = 1.0;        /* multiplier for all light sources */
  66. char    units[64] = "meters";        /* output units */
  67. double    illumrad = 0.0;            /* radius for illum sphere */
  68.  
  69. typedef struct {
  70.     int    type;                /* RECT, DISK, SPHERE */
  71.     double    w, l, h;            /* width, length, height */
  72.     double    area;                /* max. projected area */
  73. } SHAPE;                /* a source shape */
  74.  
  75. int    gargc;                /* global argc (minus filenames) */
  76. char    **gargv;            /* global argv */
  77.  
  78. extern char    *strcpy(), *strcat(), *stradd(), *tailtrunc(), *filetrunc(),
  79.         *filename(), *libname(), *fullname(), *malloc();
  80. extern float    *matchlamp();
  81.  
  82.  
  83. main(argc, argv)
  84. int    argc;
  85. char    *argv[];
  86. {
  87.     char    *outfile = NULL;
  88.     int    status;
  89.     char    outname[MAXWORD];
  90.     double    d1;
  91.     int    i;
  92.     
  93.     for (i = 1; i < argc && argv[i][0] == '-'; i++)
  94.         switch (argv[i][1]) {
  95.         case 'd':        /* dimensions */
  96.             if (argv[i][2] == '\0')
  97.                 goto badopt;
  98.             if (argv[i][3] == '\0')
  99.                 d1 = 1.0;
  100.             else if (argv[i][3] == '/') {
  101.                 d1 = atof(argv[i]+4);
  102.                 if (d1 <= FTINY)
  103.                     goto badopt;
  104.             } else
  105.                 goto badopt;
  106.             switch (argv[i][2]) {
  107.             case 'c':        /* centimeters */
  108.                 if (FEQ(d1,10.))
  109.                     strcpy(units,"millimeters");
  110.                 else {
  111.                     strcpy(units,"centimeters");
  112.                     strcat(units,argv[i]+3);
  113.                 }
  114.                 meters2out = 100.*d1;
  115.                 break;
  116.             case 'm':        /* meters */
  117.                 if (FEQ(d1,1000.))
  118.                     strcpy(units,"millimeters");
  119.                 else if (FEQ(d1,100.))
  120.                     strcpy(units,"centimeters");
  121.                 else {
  122.                     strcpy(units,"meters");
  123.                     strcat(units,argv[i]+3);
  124.                 }
  125.                 meters2out = d1;
  126.                 break;
  127.             case 'i':        /* inches */
  128.                 strcpy(units,"inches");
  129.                 strcat(units,argv[i]+3);
  130.                 meters2out = d1*(12./F_M);
  131.                 break;
  132.             case 'f':        /* feet */
  133.                 if (FEQ(d1,12.))
  134.                     strcpy(units,"inches");
  135.                 else {
  136.                     strcpy(units,"feet");
  137.                     strcat(units,argv[i]+3);
  138.                 }
  139.                 meters2out = d1/F_M;
  140.                 break;
  141.             default:
  142.                 goto badopt;
  143.             }
  144.             break;
  145.         case 'l':        /* library directory */
  146.             libdir = argv[++i];
  147.             break;
  148.         case 'p':        /* prefix subdirectory */
  149.             prefdir = argv[++i];
  150.             break;
  151.         case 'f':        /* lamp data file */
  152.             lampdat = argv[++i];
  153.             break;
  154.         case 'o':        /* output file name */
  155.             outfile = argv[++i];
  156.             break;
  157.         case 'i':        /* illum */
  158.             illumrad = atof(argv[++i]);
  159.             if (illumrad < MINDIM)
  160.                 illumrad = MINDIM;
  161.             break;
  162.         case 't':        /* override lamp type */
  163.             lamptype = argv[++i];
  164.             break;
  165.         case 'u':        /* default lamp type */
  166.             deflamp = argv[++i];
  167.             break;
  168.         case 'c':        /* default lamp color */
  169.             defcolor[0] = atof(argv[++i]);
  170.             defcolor[1] = atof(argv[++i]);
  171.             defcolor[2] = atof(argv[++i]);
  172.             break;
  173.         case 'm':        /* multiplier */
  174.             multiplier = atof(argv[++i]);
  175.             break;
  176.         default:
  177.         badopt:
  178.             fprintf(stderr, "%s: bad option: %s\n",
  179.                     argv[0], argv[i]);
  180.             exit(1);
  181.         }
  182.     gargc = i;
  183.     gargv = argv;
  184.     initlamps();            /* get lamp data (if needed) */
  185.                     /* convert ies file(s) */
  186.     if (outfile != NULL) {
  187.         if (i == argc)
  188.             exit(ies2rad(NULL, outfile) == 0 ? 0 : 1);
  189.         else if (i == argc-1)
  190.             exit(ies2rad(argv[i], outfile) == 0 ? 0 : 1);
  191.         else {
  192.             fprintf(stderr, "%s: single input file required\n",
  193.                     argv[0]);
  194.             exit(1);
  195.         }
  196.     } else if (i >= argc) {
  197.         fprintf(stderr, "%s: missing output file specification\n",
  198.                 argv[0]);
  199.         exit(1);
  200.     }
  201.     status = 0;
  202.     for ( ; i < argc; i++) {
  203.         tailtrunc(strcpy(outname,filename(argv[i])));
  204.         if (ies2rad(argv[i], outname) != 0)
  205.             status = 1;
  206.     }
  207.     exit(status);
  208. }
  209.  
  210.  
  211. initlamps()                /* set up lamps */
  212. {
  213.     float    *lcol;
  214.     int    status;
  215.  
  216.     if (lamptype != NULL && !strcmp(lamptype, default_name) &&
  217.             deflamp == NULL)
  218.         return;                /* no need for data */
  219.                         /* else load file */
  220.     if ((status = loadlamps(lampdat)) < 0)
  221.         exit(1);
  222.     if (status == 0) {
  223.         fprintf(stderr, "%s: warning - no lamp data\n", lampdat);
  224.         lamptype = default_name;
  225.         return;
  226.     }
  227.     if (deflamp != NULL) {            /* match default type */
  228.         if ((lcol = matchlamp(deflamp)) == NULL)
  229.             fprintf(stderr,
  230.                 "%s: warning - unknown default lamp type\n",
  231.                     deflamp);
  232.         else
  233.             copycolor(defcolor, lcol);
  234.     }
  235.     if (lamptype != NULL) {            /* match selected type */
  236.         if (strcmp(lamptype, default_name)) {
  237.             if ((lcol = matchlamp(lamptype)) == NULL) {
  238.                 fprintf(stderr,
  239.                     "%s: warning - unknown lamp type\n",
  240.                         lamptype);
  241.                 lamptype = default_name;
  242.             } else
  243.                 copycolor(defcolor, lcol);
  244.         }
  245.         freelamps();            /* all done with data */
  246.     }
  247.                         /* else keep lamp data */
  248. }
  249.  
  250.  
  251. char *
  252. stradd(dst, src, sep)            /* add a string at dst */
  253. register char    *dst, *src;
  254. int    sep;
  255. {
  256.     if (src && *src) {
  257.         do
  258.             *dst++ = *src++;
  259.         while (*src);
  260.         if (sep && dst[-1] != sep)
  261.             *dst++ = sep;
  262.     }
  263.     *dst = '\0';
  264.     return(dst);
  265. }
  266.  
  267.  
  268. char *
  269. fullname(path, fname, suffix)        /* return full path name */
  270. char    *path, *fname, *suffix;
  271. {
  272.     if (prefdir != NULL && abspath(prefdir))
  273.         libname(path, fname, suffix);
  274.     else if (abspath(fname))
  275.         strcpy(stradd(path, fname, 0), suffix);
  276.     else
  277.         libname(stradd(path, libdir, DIRSEP), fname, suffix);
  278.  
  279.     return(path);
  280. }
  281.  
  282.  
  283. char *
  284. libname(path, fname, suffix)        /* return library relative name */
  285. char    *path, *fname, *suffix;
  286. {
  287.     if (abspath(fname))
  288.         strcpy(stradd(path, fname, 0), suffix);
  289.     else
  290.         strcpy(stradd(stradd(path, prefdir, DIRSEP), fname, 0), suffix);
  291.  
  292.     return(path);
  293. }
  294.  
  295.  
  296. char *
  297. filename(path)            /* get final component of pathname */
  298. register char    *path;
  299. {
  300.     register char    *cp;
  301.  
  302.     for (cp = path; *path; path++)
  303.         if (ISDIRSEP(*path))
  304.             cp = path+1;
  305.     return(cp);
  306. }
  307.  
  308.  
  309. char *
  310. filetrunc(path)                /* truncate filename at end of path */
  311. char    *path;
  312. {
  313.     register char    *p1, *p2;
  314.  
  315.     for (p1 = p2 = path; *p2; p2++)
  316.         if (ISDIRSEP(*p2))
  317.             p1 = p2;
  318.     *p1 = '\0';
  319.     return(path);
  320. }
  321.  
  322.  
  323. char *
  324. tailtrunc(name)                /* truncate tail of filename */
  325. char    *name;
  326. {
  327.     register char    *p1, *p2;
  328.  
  329.     for (p1 = filename(name); *p1 == '.'; p1++)
  330.         ;
  331.     p2 = NULL;
  332.     for ( ; *p1; p1++)
  333.         if (*p1 == '.')
  334.             p2 = p1;
  335.     if (p2 != NULL)
  336.         *p2 = '\0';
  337.     return(name);
  338. }
  339.  
  340.  
  341. blanktrunc(s)                /* truncate spaces at end of line */
  342. char    *s;
  343. {
  344.     register char    *cp;
  345.  
  346.     for (cp = s; *cp; cp++)
  347.         ;
  348.     while (cp-- > s && isspace(*cp))
  349.         ;
  350.     *++cp = '\0';
  351. }
  352.  
  353.  
  354. putheader(out)                /* print header */
  355. FILE    *out;
  356. {
  357.     register int    i;
  358.     
  359.     putc('#', out);
  360.     for (i = 0; i < gargc; i++) {
  361.         putc(' ', out);
  362.         fputs(gargv[i], out);
  363.     }
  364.     fputs("\n# Dimensions in ", out);
  365.     fputs(units, out);
  366.     putc('\n', out);
  367. }
  368.  
  369.  
  370. ies2rad(inpname, outname)        /* convert IES file */
  371. char    *inpname, *outname;
  372. {
  373.     char    buf[MAXLINE], tltid[MAXWORD];
  374.     FILE    *inpfp, *outfp;
  375.  
  376.     if (inpname == NULL) {
  377.         inpname = "<stdin>";
  378.         inpfp = stdin;
  379.     } else if ((inpfp = fopen(inpname, "r")) == NULL) {
  380.         perror(inpname);
  381.         return(-1);
  382.     }
  383.     if ((outfp = fopen(fullname(buf,outname,T_RAD), "w")) == NULL) {
  384.         perror(buf);
  385.         fclose(inpfp);
  386.         return(-1);
  387.     }
  388.     putheader(outfp);
  389.     if (lamptype == NULL)
  390.         lampcolor = NULL;
  391.     while (fgets(buf,sizeof(buf),inpfp) != NULL
  392.             && strncmp(buf,TLTSTR,TLTSTRLEN)) {
  393.         blanktrunc(buf);
  394.         if (!buf[0])
  395.             continue;
  396.         fputs("#<", outfp);
  397.         fputs(buf, outfp);
  398.         putc('\n', outfp);
  399.         if (lampcolor == NULL)
  400.             lampcolor = matchlamp(buf);
  401.     }
  402.     if (lampcolor == NULL) {
  403.         fprintf(stderr, "%s: warning - no lamp type\n", inpname);
  404.         lampcolor = defcolor;
  405.     }
  406.     if (feof(inpfp)) {
  407.         fprintf(stderr, "%s: not in IES format\n", inpname);
  408.         goto readerr;
  409.     }
  410.     sscanf(buf+TLTSTRLEN, "%s", tltid);
  411.     if (inpfp == stdin)
  412.         buf[0] = '\0';
  413.     else
  414.         filetrunc(strcpy(buf, inpname));
  415.     if (dotilt(inpfp, outfp, buf, tltid, outname, tltid) != 0) {
  416.         fprintf(stderr, "%s: bad tilt data\n", inpname);
  417.         goto readerr;
  418.     }
  419.     if (dosource(inpfp, outfp, tltid, outname) != 0) {
  420.         fprintf(stderr, "%s: bad luminaire data\n", inpname);
  421.         goto readerr;
  422.     }
  423.     fclose(outfp);
  424.     fclose(inpfp);
  425.     return(0);
  426. readerr:
  427.     fclose(outfp);
  428.     fclose(inpfp);
  429.     unlink(fullname(buf,outname,T_RAD));
  430.     return(-1);
  431. }
  432.  
  433.  
  434. dotilt(in, out, dir, tltspec, dfltname, tltid)    /* convert tilt data */
  435. FILE    *in, *out;
  436. char    *dir, *tltspec, *dfltname, *tltid;
  437. {
  438.     int    nangles, tlt_type;
  439.     double    minmax[2];
  440.     char    buf[MAXPATH], tltname[MAXWORD];
  441.     FILE    *datin, *datout;
  442.  
  443.     if (!strcmp(tltspec, TLTNONE)) {
  444.         datin = NULL;
  445.         strcpy(tltid, "void");
  446.     } else if (!strcmp(tltspec, TLTINCL)) {
  447.         datin = in;
  448.         strcpy(tltname, dfltname);
  449.     } else {
  450.         if (ISDIRSEP(tltspec[0]))
  451.             strcpy(buf, tltspec);
  452.         else
  453.             strcpy(stradd(buf, dir, DIRSEP), tltspec);
  454.         if ((datin = fopen(buf, "r")) == NULL) {
  455.             perror(buf);
  456.             return(-1);
  457.         }
  458.         tailtrunc(strcpy(tltname,filename(tltspec)));
  459.     }
  460.     if (datin != NULL) {
  461.         if ((datout = fopen(fullname(buf,tltname,T_TLT),"w")) == NULL) {
  462.             perror(buf);
  463.             if (datin != in)
  464.                 fclose(datin);
  465.             return(-1);
  466.         }
  467.         if (fscanf(datin, "%d %d", &tlt_type, &nangles) != 2
  468.             || cvdata(datin,datout,1,&nangles,1.,minmax) != 0) {
  469.             fprintf(stderr, "%s: data format error\n", tltspec);
  470.             fclose(datout);
  471.             if (datin != in)
  472.                 fclose(datin);
  473.             unlink(fullname(buf,tltname,T_TLT));
  474.             return(-1);
  475.         }
  476.         fclose(datout);
  477.         if (datin != in)
  478.             fclose(datin);
  479.         strcat(strcpy(tltid, filename(tltname)), "_tilt");
  480.         fprintf(out, "\nvoid brightdata %s\n", tltid);
  481.         libname(buf,tltname,T_TLT);
  482.         switch (tlt_type) {
  483.         case TLT_VERT:            /* vertical */
  484.             fprintf(out, "4 noop %s tilt.cal %s\n", buf,
  485.                 minmax[1]>90.+FTINY ? "tilt_ang" : "tilt_ang2");
  486.             break;
  487.         case TLT_H0:            /* horiz. in 0 deg. plane */
  488.             fprintf(out, "6 noop %s tilt.cal %s -rz 90\n", buf,
  489.             minmax[1]>90.+FTINY ? "tilt_xang" : "tilt_xang2");
  490.             break;
  491.         case TLT_H90:
  492.             fprintf(out, "4 noop %s tilt.cal %s\n", buf,
  493.             minmax[1]>90.+FTINY ? "tilt_xang" : "tilt_xang2");
  494.             break;
  495.         default:
  496.             fprintf(stderr,
  497.                 "%s: illegal lamp to luminaire geometry (%d)\n",
  498.                 tltspec, tlt_type);
  499.             return(-1);
  500.         }
  501.         fprintf(out, "0\n0\n");
  502.     }
  503.     return(0);
  504. }
  505.  
  506.  
  507. dosource(in, out, mod, name)        /* create source and distribution */
  508. FILE    *in, *out;
  509. char    *mod, *name;
  510. {
  511.     SHAPE    srcshape;
  512.     char    buf[MAXPATH], id[MAXWORD];
  513.     FILE    *datout;
  514.     double    mult, bfactor, pfactor, width, length, height, wattage;
  515.     double    bounds[2][2];
  516.     int    nangles[2], pmtype, unitype;
  517.     double    d1;
  518.  
  519.     if (fscanf(in, "%*d %*f %lf %d %d %d %d %lf %lf %lf %lf %lf %lf",
  520.             &mult, &nangles[0], &nangles[1], &pmtype, &unitype,
  521.             &width, &length, &height, &bfactor, &pfactor,
  522.             &wattage) != 11) {
  523.         fprintf(stderr, "dosource: bad lamp specification\n");
  524.         return(-1);
  525.     }
  526.     if (nangles[0] < 2 || nangles[1] < 1) {
  527.         fprintf(stderr, "dosource: too few measured angles\n");
  528.         return(-1);
  529.     }
  530.     if (unitype == U_FEET) {
  531.         width *= F_M;
  532.         length *= F_M;
  533.         height *= F_M;
  534.     }
  535.     if (makeshape(&srcshape, width, length, height) != 0) {
  536.         fprintf(stderr, "dosource: illegal source dimensions");
  537.         return(-1);
  538.     }
  539.     if ((datout = fopen(fullname(buf,name,T_DST), "w")) == NULL) {
  540.         perror(buf);
  541.         return(-1);
  542.     }
  543.     if (cvdata(in, datout, 2, nangles, 1./WHTEFFICACY, bounds) != 0) {
  544.         fprintf(stderr, "dosource: bad distribution data\n");
  545.         fclose(datout);
  546.         unlink(fullname(buf,name,T_DST));
  547.         return(-1);
  548.     }
  549.     fclose(datout);
  550.     fprintf(out, "# %g watt luminaire, lamp*ballast factor = %g\n",
  551.             wattage, bfactor*pfactor);
  552.     strcat(strcpy(id, filename(name)), "_dist");
  553.     fprintf(out, "\n%s brightdata %s\n", mod, id);
  554.     if (nangles[1] < 2)
  555.         fprintf(out, "4 ");
  556.     else if (pmtype == PM_B)
  557.         fprintf(out, "5 ");
  558.     else if (FEQ(bounds[1][0],90.) && FEQ(bounds[1][1],270.))
  559.         fprintf(out, "8 ");
  560.     else
  561.         fprintf(out, "6 ");
  562.     fprintf(out, "%s %s source.cal ",
  563.             srcshape.type==SPHERE ? "corr" : "flatcorr",
  564.             libname(buf,name,T_DST));
  565.     if (pmtype == PM_B) {
  566.         if (FEQ(bounds[1][0],0.))
  567.             fprintf(out, "srcB_horiz2 ");
  568.         else
  569.             fprintf(out, "srcB_horiz ");
  570.         fprintf(out, "srcB_vert ");
  571.     } else {
  572.         if (nangles[1] >= 2) {
  573.             d1 = bounds[1][1] - bounds[1][0];
  574.             if (d1 <= 90.+FTINY)
  575.                 fprintf(out, "src_phi4 ");
  576.             else if (d1 <= 180.+FTINY)
  577.                 fprintf(out, "src_phi2 ");
  578.             else
  579.                 fprintf(out, "src_phi ");
  580.             fprintf(out, "src_theta -my ");
  581.             if (FEQ(bounds[1][0],90.) && FEQ(bounds[1][1],270.))
  582.                 fprintf(out, "-rz -90 ");
  583.         } else
  584.             fprintf(out, "src_theta ");
  585.     }
  586.     fprintf(out, "\n0\n1 %g\n", multiplier*mult*bfactor*pfactor);
  587.     if (putsource(&srcshape, out, id, filename(name),
  588.             bounds[0][0]<90., bounds[0][1]>90.) != 0)
  589.         return(-1);
  590.     return(0);
  591. }
  592.  
  593.  
  594. putsource(shp, fp, mod, name, dolower, doupper)        /* put out source */
  595. SHAPE    *shp;
  596. FILE    *fp;
  597. char    *mod, *name;
  598. int    dolower, doupper;
  599. {
  600.     char    buf[MAXWORD];
  601.     
  602.     fprintf(fp, "\n%s %s %s_light\n", mod,
  603.             illumrad>=MINDIM/2. ? "illum" : "light",
  604.             name);
  605.     fprintf(fp, "0\n0\n3 %g %g %g\n",
  606.             lampcolor[0]/shp->area,
  607.             lampcolor[1]/shp->area,
  608.             lampcolor[2]/shp->area);
  609.     if (doupper && dolower && shp->type != SPHERE && shp->h > MINDIM) {
  610.         fprintf(fp, "\n%s glow %s_glow\n", mod, name);
  611.         fprintf(fp, "0\n0\n4 %g %g %g 0\n",
  612.                 lampcolor[0]/shp->area,
  613.                 lampcolor[1]/shp->area,
  614.                 lampcolor[2]/shp->area);
  615.     }
  616.     switch (shp->type) {
  617.     case RECT:
  618.         strcat(strcpy(buf, name), "_light");
  619.         if (dolower)
  620.             putrectsrc(shp, fp, buf, name, 0);
  621.         if (doupper)
  622.             putrectsrc(shp, fp, buf, name, 1);
  623.         if (doupper && dolower && shp->h > MINDIM) {
  624.             strcat(strcpy(buf, name), "_glow");
  625.             putsides(shp, fp, buf, name);
  626.         }
  627.         break;
  628.     case DISK:
  629.         strcat(strcpy(buf, name), "_light");
  630.         if (dolower)
  631.             putdisksrc(shp, fp, buf, name, 0);
  632.         if (doupper)
  633.             putdisksrc(shp, fp, buf, name, 1);
  634.         if (doupper && dolower && shp->h > MINDIM) {
  635.             strcat(strcpy(buf, name), "_glow");
  636.             putcyl(shp, fp, buf, name);
  637.         }
  638.         break;
  639.     case SPHERE:
  640.         strcat(strcpy(buf, name), "_light");
  641.         putspheresrc(shp, fp, buf, name);
  642.         break;
  643.     }
  644.     return(0);
  645. }
  646.  
  647.  
  648. makeshape(shp, width, length, height)        /* make source shape */
  649. register SHAPE    *shp;
  650. double    width, length, height;
  651. {
  652.     if (illumrad >= MINDIM/2.) {
  653.         shp->type = SPHERE;
  654.         shp->w = shp->l = shp->h = 2.*illumrad;
  655.     } else if (width < MINDIM) {
  656.         width = -width;
  657.         if (width < MINDIM) {
  658.             shp->type = SPHERE;
  659.             shp->w = shp->l = shp->h = MINDIM;
  660.         } else if (height < .5*width) {
  661.             shp->type = DISK;
  662.             shp->w = shp->l = width;
  663.             if (height >= MINDIM)
  664.                 shp->h = height;
  665.             else
  666.                 shp->h = .5*MINDIM;
  667.         } else {
  668.             shp->type = SPHERE;
  669.             shp->w = shp->l = shp->h = width;
  670.         }
  671.     } else {
  672.         shp->type = RECT;
  673.         shp->w = width;
  674.         if (length >= MINDIM)
  675.             shp->l = length;
  676.         else
  677.             shp->l = MINDIM;
  678.         if (height >= MINDIM)
  679.             shp->h = height;
  680.         else
  681.             shp->h = .5*MINDIM;
  682.     }
  683.     switch (shp->type) {
  684.     case RECT:
  685.         shp->area = shp->w * shp->l;
  686.         break;
  687.     case DISK:
  688.     case SPHERE:
  689.         shp->area = PI/4. * shp->w * shp->w;
  690.         break;
  691.     }
  692.     return(0);
  693. }
  694.  
  695.  
  696. putrectsrc(shp, fp, mod, name, up)        /* rectangular source */
  697. SHAPE    *shp;
  698. FILE    *fp;
  699. char    *mod, *name;
  700. int    up;
  701. {
  702.     if (up)
  703.         putrect(shp, fp, mod, name, ".u", 4, 5, 7, 6);
  704.     else
  705.         putrect(shp, fp, mod, name, ".d", 0, 2, 3, 1);
  706. }
  707.  
  708.  
  709. putsides(shp, fp, mod, name)            /* put out sides of box */
  710. register SHAPE    *shp;
  711. FILE    *fp;
  712. char    *mod, *name;
  713. {
  714.     putrect(shp, fp, mod, name, ".1", 0, 1, 5, 4);
  715.     putrect(shp, fp, mod, name, ".2", 1, 3, 7, 5);
  716.     putrect(shp, fp, mod, name, ".3", 3, 2, 6, 7);
  717.     putrect(shp, fp, mod, name, ".4", 2, 0, 4, 6);
  718. }
  719.     
  720.  
  721. putrect(shp, fp, mod, name, suffix, a, b, c, d)    /* put out a rectangle */
  722. SHAPE    *shp;
  723. FILE    *fp;
  724. char    *mod, *name, *suffix;
  725. int    a, b, c, d;
  726. {
  727.     fprintf(fp, "\n%s polygon %s%s\n0\n0\n12\n", mod, name, suffix);
  728.     putpoint(shp, fp, a);
  729.     putpoint(shp, fp, b);
  730.     putpoint(shp, fp, c);
  731.     putpoint(shp, fp, d);
  732. }
  733.  
  734.  
  735. putpoint(shp, fp, p)                /* put out a point */
  736. register SHAPE    *shp;
  737. FILE    *fp;
  738. int    p;
  739. {
  740.     static double    mult[2] = {-.5, .5};
  741.  
  742.     fprintf(fp, "\t%g\t%g\t%g\n",
  743.             mult[p&1]*shp->l*meters2out,
  744.             mult[p>>1&1]*shp->w*meters2out,
  745.             mult[p>>2]*shp->h*meters2out);
  746. }
  747.  
  748.  
  749. putdisksrc(shp, fp, mod, name, up)        /* put out a disk source */
  750. register SHAPE    *shp;
  751. FILE    *fp;
  752. char    *mod, *name;
  753. int    up;
  754. {
  755.     if (up) {
  756.         fprintf(fp, "\n%s ring %s.u\n", mod, name);
  757.         fprintf(fp, "0\n0\n8\n");
  758.         fprintf(fp, "\t0 0 %g\n", .5*shp->h*meters2out);
  759.         fprintf(fp, "\t0 0 1\n");
  760.         fprintf(fp, "\t0 %g\n", .5*shp->w*meters2out);
  761.     } else {
  762.         fprintf(fp, "\n%s ring %s.d\n", mod, name);
  763.         fprintf(fp, "0\n0\n8\n");
  764.         fprintf(fp, "\t0 0 %g\n", -.5*shp->h*meters2out);
  765.         fprintf(fp, "\t0 0 -1\n");
  766.         fprintf(fp, "\t0 %g\n", .5*shp->w*meters2out);
  767.     }
  768. }
  769.  
  770.  
  771. putcyl(shp, fp, mod, name)            /* put out a cylinder */
  772. register SHAPE    *shp;
  773. FILE    *fp;
  774. char    *mod, *name;
  775. {
  776.     fprintf(fp, "\n%s cylinder %s.c\n", mod, name);
  777.     fprintf(fp, "0\n0\n7\n");
  778.     fprintf(fp, "\t0 0 %g\n", .5*shp->h*meters2out);
  779.     fprintf(fp, "\t0 0 %g\n", -.5*shp->h*meters2out);
  780.     fprintf(fp, "\t%g\n", .5*shp->w*meters2out);
  781. }
  782.  
  783.  
  784. putspheresrc(shp, fp, mod, name)        /* put out a sphere source */
  785. SHAPE    *shp;
  786. FILE    *fp;
  787. char    *mod, *name;
  788. {
  789.     fprintf(fp, "\n%s sphere %s.s\n", mod, name);
  790.     fprintf(fp, "0\n0\n4 0 0 0 %g\n", .5*shp->w*meters2out);
  791. }
  792.  
  793.  
  794. cvdata(in, out, ndim, npts, mult, lim)        /* convert data */
  795. FILE    *in, *out;
  796. int    ndim, npts[];
  797. double    mult, lim[][2];
  798. {
  799.     double    *pt[4];
  800.     register int    i, j;
  801.     double    val;
  802.     int    total;
  803.  
  804.     total = 1; j = 0;
  805.     for (i = 0; i < ndim; i++)
  806.         if (npts[i] > 1) {
  807.             total *= npts[i];
  808.             j++;
  809.         }
  810.     fprintf(out, "%d\n", j);
  811.                     /* get coordinates */
  812.     for (i = 0; i < ndim; i++) {
  813.         pt[i] = (double *)malloc(npts[i]*sizeof(double));
  814.         for (j = 0; j < npts[i]; j++)
  815.             fscanf(in, "%lf", &pt[i][j]);
  816.         if (lim != NULL) {
  817.             lim[i][0] = pt[i][0];
  818.             lim[i][1] = pt[i][npts[i]-1];
  819.         }
  820.     }
  821.                     /* write out in reverse */
  822.     for (i = ndim-1; i >= 0; i--) {
  823.         if (npts[i] > 1) {
  824.             for (j = 1; j < npts[i]-1; j++)
  825.                 if (!FEQ(pt[i][j]-pt[i][j-1],
  826.                         pt[i][j+1]-pt[i][j]))
  827.                     break;
  828.             if (j == npts[i]-1)
  829.                 fprintf(out, "%g %g %d\n", pt[i][0], pt[i][j],
  830.                         npts[i]);
  831.             else {
  832.                 fprintf(out, "0 0 %d", npts[i]);
  833.                 for (j = 0; j < npts[i]; j++) {
  834.                     if (j%4 == 0)
  835.                         putc('\n', out);
  836.                     fprintf(out, "\t%g", pt[i][j]);
  837.                 }
  838.                 putc('\n', out);
  839.             }
  840.         }
  841.         free((char *)pt[i]);
  842.     }
  843.     for (i = 0; i < total; i++) {
  844.         if (i%4 == 0)
  845.             putc('\n', out);
  846.         if (fscanf(in, "%lf", &val) != 1)
  847.             return(-1);
  848.         fprintf(out, "\t%g", val*mult);
  849.     }
  850.     putc('\n', out);
  851.     return(0);
  852. }
  853.