ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/ies2rad.c
Revision: 1.4
Committed: Thu Sep 5 13:17:13 1991 UTC (32 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.3: +1 -1 lines
Log Message:
corrected lumens to watts conversion factor

File Contents

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