ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/ies2rad.c
Revision: 2.11
Committed: Mon May 23 10:45:41 1994 UTC (29 years, 10 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.10: +2 -2 lines
Log Message:
fixed bug in -i option that caused it to assume inappropriate units

File Contents

# User Rev Content
1 greg 2.4 /* Copyright (c) 1992 Regents of the University of California */
2 greg 1.1
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 greg 2.8 #include <math.h>
15 greg 1.1 #include <ctype.h>
16 greg 1.2 #include "color.h"
17 greg 2.4 #include "paths.h"
18 greg 1.1
19     #define PI 3.14159265358979323846
20     /* floating comparisons */
21     #define FTINY 1e-6
22     #define FEQ(a,b) ((a)<=(b)+FTINY&&(a)>=(b)-FTINY)
23     /* tilt specs */
24     #define TLTSTR "TILT="
25     #define TLTSTRLEN 5
26     #define TLTNONE "NONE"
27     #define TLTINCL "INCLUDE"
28     #define TLT_VERT 1
29     #define TLT_H0 2
30     #define TLT_H90 3
31     /* photometric types */
32     #define PM_C 1
33     #define PM_B 2
34     /* unit types */
35     #define U_FEET 1
36     #define U_METERS 2
37     /* string lengths */
38     #define MAXLINE 132
39     #define MAXWORD 76
40     /* file types */
41     #define T_RAD ".rad"
42     #define T_DST ".dat"
43 greg 2.10 #define T_TLT "%.dat"
44 greg 1.1 /* shape types */
45     #define RECT 1
46     #define DISK 2
47     #define SPHERE 3
48    
49     #define MINDIM .001 /* minimum dimension (point source) */
50    
51     #define F_M .3048 /* feet to meters */
52    
53 greg 2.4 #define abspath(p) (ISDIRSEP((p)[0]) || (p)[0] == '.')
54 greg 1.1
55 greg 1.2 static char default_name[] = "default";
56    
57 greg 1.1 char *libdir = NULL; /* library directory location */
58     char *prefdir = NULL; /* subdirectory */
59     char *lampdat = "lamp.tab"; /* lamp data file */
60    
61     double meters2out = 1.0; /* conversion from meters to output */
62     char *lamptype = NULL; /* selected lamp type */
63 greg 1.2 char *deflamp = NULL; /* default lamp type */
64 greg 1.1 float defcolor[3] = {1.,1.,1.}; /* default lamp color */
65 greg 1.2 float *lampcolor = defcolor; /* pointer to current lamp color */
66 greg 1.1 double multiplier = 1.0; /* multiplier for all light sources */
67     char units[64] = "meters"; /* output units */
68     double illumrad = 0.0; /* radius for illum sphere */
69    
70     typedef struct {
71     int type; /* RECT, DISK, SPHERE */
72     double w, l, h; /* width, length, height */
73 greg 1.3 double area; /* max. projected area */
74 greg 1.1 } SHAPE; /* a source shape */
75    
76     int gargc; /* global argc (minus filenames) */
77     char **gargv; /* global argv */
78    
79     extern char *strcpy(), *strcat(), *stradd(), *tailtrunc(), *filetrunc(),
80 greg 2.6 *filename(), *libname(), *fullname(), *malloc(),
81     *getword(), *atos();
82 greg 1.1 extern float *matchlamp();
83    
84 greg 2.6 #define scnint(fp,ip) cvtint(ip,getword(fp))
85     #define scnflt(fp,rp) cvtflt(rp,getword(fp))
86     #define isint isflt /* IES allows real as integer */
87 greg 1.1
88 greg 2.6
89 greg 1.1 main(argc, argv)
90     int argc;
91     char *argv[];
92     {
93     char *outfile = NULL;
94     int status;
95     char outname[MAXWORD];
96     double d1;
97     int i;
98    
99     for (i = 1; i < argc && argv[i][0] == '-'; i++)
100     switch (argv[i][1]) {
101     case 'd': /* dimensions */
102     if (argv[i][2] == '\0')
103     goto badopt;
104     if (argv[i][3] == '\0')
105     d1 = 1.0;
106     else if (argv[i][3] == '/') {
107     d1 = atof(argv[i]+4);
108     if (d1 <= FTINY)
109     goto badopt;
110     } else
111     goto badopt;
112     switch (argv[i][2]) {
113     case 'c': /* centimeters */
114     if (FEQ(d1,10.))
115     strcpy(units,"millimeters");
116     else {
117     strcpy(units,"centimeters");
118     strcat(units,argv[i]+3);
119     }
120     meters2out = 100.*d1;
121     break;
122     case 'm': /* meters */
123     if (FEQ(d1,1000.))
124     strcpy(units,"millimeters");
125     else if (FEQ(d1,100.))
126     strcpy(units,"centimeters");
127     else {
128     strcpy(units,"meters");
129     strcat(units,argv[i]+3);
130     }
131     meters2out = d1;
132     break;
133     case 'i': /* inches */
134     strcpy(units,"inches");
135     strcat(units,argv[i]+3);
136     meters2out = d1*(12./F_M);
137     break;
138     case 'f': /* feet */
139     if (FEQ(d1,12.))
140     strcpy(units,"inches");
141     else {
142     strcpy(units,"feet");
143     strcat(units,argv[i]+3);
144     }
145     meters2out = d1/F_M;
146     break;
147     default:
148     goto badopt;
149     }
150     break;
151     case 'l': /* library directory */
152     libdir = argv[++i];
153     break;
154     case 'p': /* prefix subdirectory */
155     prefdir = argv[++i];
156     break;
157     case 'f': /* lamp data file */
158     lampdat = argv[++i];
159     break;
160     case 'o': /* output file name */
161     outfile = argv[++i];
162     break;
163     case 'i': /* illum */
164     illumrad = atof(argv[++i]);
165     if (illumrad < MINDIM)
166     illumrad = MINDIM;
167     break;
168 greg 1.2 case 't': /* override lamp type */
169 greg 1.1 lamptype = argv[++i];
170     break;
171 greg 1.2 case 'u': /* default lamp type */
172     deflamp = argv[++i];
173     break;
174 greg 1.1 case 'c': /* default lamp color */
175     defcolor[0] = atof(argv[++i]);
176     defcolor[1] = atof(argv[++i]);
177     defcolor[2] = atof(argv[++i]);
178     break;
179     case 'm': /* multiplier */
180     multiplier = atof(argv[++i]);
181     break;
182     default:
183     badopt:
184     fprintf(stderr, "%s: bad option: %s\n",
185     argv[0], argv[i]);
186     exit(1);
187     }
188     gargc = i;
189     gargv = argv;
190 greg 1.2 initlamps(); /* get lamp data (if needed) */
191 greg 1.1 /* convert ies file(s) */
192     if (outfile != NULL) {
193     if (i == argc)
194     exit(ies2rad(NULL, outfile) == 0 ? 0 : 1);
195     else if (i == argc-1)
196     exit(ies2rad(argv[i], outfile) == 0 ? 0 : 1);
197     else {
198     fprintf(stderr, "%s: single input file required\n",
199     argv[0]);
200     exit(1);
201     }
202     } else if (i >= argc) {
203     fprintf(stderr, "%s: missing output file specification\n",
204     argv[0]);
205     exit(1);
206     }
207     status = 0;
208     for ( ; i < argc; i++) {
209     tailtrunc(strcpy(outname,filename(argv[i])));
210     if (ies2rad(argv[i], outname) != 0)
211     status = 1;
212     }
213     exit(status);
214 greg 1.2 }
215    
216    
217     initlamps() /* set up lamps */
218     {
219     float *lcol;
220     int status;
221    
222     if (lamptype != NULL && !strcmp(lamptype, default_name) &&
223     deflamp == NULL)
224     return; /* no need for data */
225     /* else load file */
226     if ((status = loadlamps(lampdat)) < 0)
227     exit(1);
228     if (status == 0) {
229     fprintf(stderr, "%s: warning - no lamp data\n", lampdat);
230     lamptype = default_name;
231     return;
232     }
233     if (deflamp != NULL) { /* match default type */
234     if ((lcol = matchlamp(deflamp)) == NULL)
235     fprintf(stderr,
236     "%s: warning - unknown default lamp type\n",
237     deflamp);
238     else
239     copycolor(defcolor, lcol);
240     }
241     if (lamptype != NULL) { /* match selected type */
242     if (strcmp(lamptype, default_name)) {
243     if ((lcol = matchlamp(lamptype)) == NULL) {
244     fprintf(stderr,
245     "%s: warning - unknown lamp type\n",
246     lamptype);
247     lamptype = default_name;
248     } else
249     copycolor(defcolor, lcol);
250     }
251     freelamps(); /* all done with data */
252     }
253     /* else keep lamp data */
254 greg 1.1 }
255    
256    
257     char *
258     stradd(dst, src, sep) /* add a string at dst */
259     register char *dst, *src;
260     int sep;
261     {
262     if (src && *src) {
263     do
264     *dst++ = *src++;
265     while (*src);
266     if (sep && dst[-1] != sep)
267     *dst++ = sep;
268     }
269     *dst = '\0';
270     return(dst);
271     }
272    
273    
274     char *
275     fullname(path, fname, suffix) /* return full path name */
276     char *path, *fname, *suffix;
277     {
278     if (prefdir != NULL && abspath(prefdir))
279     libname(path, fname, suffix);
280     else if (abspath(fname))
281     strcpy(stradd(path, fname, 0), suffix);
282     else
283 greg 2.4 libname(stradd(path, libdir, DIRSEP), fname, suffix);
284 greg 1.1
285     return(path);
286     }
287    
288    
289     char *
290     libname(path, fname, suffix) /* return library relative name */
291     char *path, *fname, *suffix;
292     {
293     if (abspath(fname))
294     strcpy(stradd(path, fname, 0), suffix);
295     else
296 greg 2.4 strcpy(stradd(stradd(path, prefdir, DIRSEP), fname, 0), suffix);
297 greg 1.1
298     return(path);
299     }
300    
301    
302     char *
303     filename(path) /* get final component of pathname */
304     register char *path;
305     {
306     register char *cp;
307    
308     for (cp = path; *path; path++)
309 greg 2.4 if (ISDIRSEP(*path))
310 greg 1.1 cp = path+1;
311     return(cp);
312     }
313    
314    
315     char *
316     filetrunc(path) /* truncate filename at end of path */
317     char *path;
318     {
319     register char *p1, *p2;
320    
321     for (p1 = p2 = path; *p2; p2++)
322 greg 2.4 if (ISDIRSEP(*p2))
323 greg 1.1 p1 = p2;
324     *p1 = '\0';
325     return(path);
326     }
327    
328    
329     char *
330     tailtrunc(name) /* truncate tail of filename */
331     char *name;
332     {
333     register char *p1, *p2;
334    
335     for (p1 = filename(name); *p1 == '.'; p1++)
336     ;
337     p2 = NULL;
338     for ( ; *p1; p1++)
339     if (*p1 == '.')
340     p2 = p1;
341     if (p2 != NULL)
342     *p2 = '\0';
343     return(name);
344     }
345    
346    
347     blanktrunc(s) /* truncate spaces at end of line */
348     char *s;
349     {
350     register char *cp;
351    
352     for (cp = s; *cp; cp++)
353     ;
354     while (cp-- > s && isspace(*cp))
355     ;
356     *++cp = '\0';
357     }
358    
359    
360     putheader(out) /* print header */
361     FILE *out;
362     {
363     register int i;
364    
365     putc('#', out);
366     for (i = 0; i < gargc; i++) {
367     putc(' ', out);
368     fputs(gargv[i], out);
369     }
370     fputs("\n# Dimensions in ", out);
371     fputs(units, out);
372     putc('\n', out);
373     }
374    
375    
376     ies2rad(inpname, outname) /* convert IES file */
377     char *inpname, *outname;
378     {
379     char buf[MAXLINE], tltid[MAXWORD];
380     FILE *inpfp, *outfp;
381    
382     if (inpname == NULL) {
383     inpname = "<stdin>";
384     inpfp = stdin;
385     } else if ((inpfp = fopen(inpname, "r")) == NULL) {
386     perror(inpname);
387     return(-1);
388     }
389     if ((outfp = fopen(fullname(buf,outname,T_RAD), "w")) == NULL) {
390     perror(buf);
391     fclose(inpfp);
392     return(-1);
393     }
394     putheader(outfp);
395     if (lamptype == NULL)
396     lampcolor = NULL;
397     while (fgets(buf,sizeof(buf),inpfp) != NULL
398     && strncmp(buf,TLTSTR,TLTSTRLEN)) {
399     blanktrunc(buf);
400     if (!buf[0])
401     continue;
402     fputs("#<", outfp);
403     fputs(buf, outfp);
404     putc('\n', outfp);
405     if (lampcolor == NULL)
406     lampcolor = matchlamp(buf);
407     }
408     if (lampcolor == NULL) {
409     fprintf(stderr, "%s: warning - no lamp type\n", inpname);
410 greg 2.9 fputs("# Unknown lamp type (used default)\n", outfp);
411 greg 1.1 lampcolor = defcolor;
412 greg 2.9 } else if (lamptype == NULL)
413     fprintf(outfp,"# CIE(x,y) = (%f,%f)\n# Depreciation = %.1f%%\n",
414     lampcolor[3], lampcolor[4], 100.*lampcolor[5]);
415 greg 1.1 if (feof(inpfp)) {
416     fprintf(stderr, "%s: not in IES format\n", inpname);
417     goto readerr;
418     }
419 greg 2.6 atos(tltid, MAXWORD, buf+TLTSTRLEN);
420 greg 1.1 if (inpfp == stdin)
421     buf[0] = '\0';
422     else
423     filetrunc(strcpy(buf, inpname));
424     if (dotilt(inpfp, outfp, buf, tltid, outname, tltid) != 0) {
425     fprintf(stderr, "%s: bad tilt data\n", inpname);
426     goto readerr;
427     }
428     if (dosource(inpfp, outfp, tltid, outname) != 0) {
429     fprintf(stderr, "%s: bad luminaire data\n", inpname);
430     goto readerr;
431     }
432     fclose(outfp);
433     fclose(inpfp);
434     return(0);
435     readerr:
436     fclose(outfp);
437     fclose(inpfp);
438     unlink(fullname(buf,outname,T_RAD));
439     return(-1);
440     }
441    
442    
443     dotilt(in, out, dir, tltspec, dfltname, tltid) /* convert tilt data */
444     FILE *in, *out;
445     char *dir, *tltspec, *dfltname, *tltid;
446     {
447     int nangles, tlt_type;
448     double minmax[2];
449     char buf[MAXPATH], tltname[MAXWORD];
450     FILE *datin, *datout;
451    
452     if (!strcmp(tltspec, TLTNONE)) {
453     datin = NULL;
454     strcpy(tltid, "void");
455     } else if (!strcmp(tltspec, TLTINCL)) {
456     datin = in;
457     strcpy(tltname, dfltname);
458     } else {
459 greg 2.4 if (ISDIRSEP(tltspec[0]))
460 greg 1.1 strcpy(buf, tltspec);
461     else
462 greg 2.4 strcpy(stradd(buf, dir, DIRSEP), tltspec);
463 greg 1.1 if ((datin = fopen(buf, "r")) == NULL) {
464     perror(buf);
465     return(-1);
466     }
467     tailtrunc(strcpy(tltname,filename(tltspec)));
468     }
469     if (datin != NULL) {
470     if ((datout = fopen(fullname(buf,tltname,T_TLT),"w")) == NULL) {
471     perror(buf);
472     if (datin != in)
473     fclose(datin);
474     return(-1);
475     }
476 greg 2.6 if (!scnint(datin,&tlt_type) || !scnint(datin,&nangles)
477 greg 1.1 || cvdata(datin,datout,1,&nangles,1.,minmax) != 0) {
478     fprintf(stderr, "%s: data format error\n", tltspec);
479     fclose(datout);
480     if (datin != in)
481     fclose(datin);
482     unlink(fullname(buf,tltname,T_TLT));
483     return(-1);
484     }
485     fclose(datout);
486     if (datin != in)
487     fclose(datin);
488     strcat(strcpy(tltid, filename(tltname)), "_tilt");
489     fprintf(out, "\nvoid brightdata %s\n", tltid);
490     libname(buf,tltname,T_TLT);
491     switch (tlt_type) {
492     case TLT_VERT: /* vertical */
493     fprintf(out, "4 noop %s tilt.cal %s\n", buf,
494     minmax[1]>90.+FTINY ? "tilt_ang" : "tilt_ang2");
495     break;
496     case TLT_H0: /* horiz. in 0 deg. plane */
497     fprintf(out, "6 noop %s tilt.cal %s -rz 90\n", buf,
498     minmax[1]>90.+FTINY ? "tilt_xang" : "tilt_xang2");
499     break;
500     case TLT_H90:
501     fprintf(out, "4 noop %s tilt.cal %s\n", buf,
502     minmax[1]>90.+FTINY ? "tilt_xang" : "tilt_xang2");
503     break;
504     default:
505     fprintf(stderr,
506     "%s: illegal lamp to luminaire geometry (%d)\n",
507     tltspec, tlt_type);
508     return(-1);
509     }
510     fprintf(out, "0\n0\n");
511     }
512     return(0);
513     }
514    
515    
516     dosource(in, out, mod, name) /* create source and distribution */
517     FILE *in, *out;
518     char *mod, *name;
519     {
520     SHAPE srcshape;
521     char buf[MAXPATH], id[MAXWORD];
522     FILE *datout;
523     double mult, bfactor, pfactor, width, length, height, wattage;
524     double bounds[2][2];
525     int nangles[2], pmtype, unitype;
526     double d1;
527    
528 greg 2.6 if (!isint(getword(in)) || !isflt(getword(in)) || !scnflt(in,&mult)
529     || !scnint(in,&nangles[0]) || !scnint(in,&nangles[1])
530     || !scnint(in,&pmtype) || !scnint(in,&unitype)
531     || !scnflt(in,&width) || !scnflt(in,&length)
532     || !scnflt(in,&height) || !scnflt(in,&bfactor)
533     || !scnflt(in,&pfactor) || !scnflt(in,&wattage)) {
534 greg 1.1 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.5 if (cvdata(in, datout, 2, nangles, 1./WHTEFFICACY, 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 greg 2.7 fprintf(out, "7 ");
571 greg 1.1 else
572 greg 2.7 fprintf(out, "5 ");
573 greg 1.1 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 greg 2.7 fprintf(out, "src_theta ");
592 greg 1.1 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 greg 2.5 fprintf(fp, "0\n0\n4 %g %g %g -1\n",
623 greg 1.1 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 greg 2.11 if (illumrad/meters2out >= MINDIM/2.) {
664 greg 1.1 shp->type = SPHERE;
665 greg 2.11 shp->w = shp->l = shp->h = 2.*illumrad / meters2out;
666 greg 1.1 } 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 greg 2.3 double *pt[4];
811 greg 1.1 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 greg 2.6 if (!scnflt(in, &pt[i][j]))
827     return(-1);
828 greg 1.1 if (lim != NULL) {
829     lim[i][0] = pt[i][0];
830     lim[i][1] = pt[i][npts[i]-1];
831     }
832     }
833     /* write out in reverse */
834     for (i = ndim-1; i >= 0; i--) {
835     if (npts[i] > 1) {
836     for (j = 1; j < npts[i]-1; j++)
837     if (!FEQ(pt[i][j]-pt[i][j-1],
838     pt[i][j+1]-pt[i][j]))
839     break;
840     if (j == npts[i]-1)
841     fprintf(out, "%g %g %d\n", pt[i][0], pt[i][j],
842     npts[i]);
843     else {
844     fprintf(out, "0 0 %d", npts[i]);
845     for (j = 0; j < npts[i]; j++) {
846     if (j%4 == 0)
847     putc('\n', out);
848     fprintf(out, "\t%g", pt[i][j]);
849     }
850     putc('\n', out);
851     }
852     }
853     free((char *)pt[i]);
854     }
855     for (i = 0; i < total; i++) {
856     if (i%4 == 0)
857     putc('\n', out);
858 greg 2.6 if (!scnflt(in, &val))
859 greg 1.1 return(-1);
860     fprintf(out, "\t%g", val*mult);
861     }
862     putc('\n', out);
863     return(0);
864 greg 2.6 }
865    
866    
867     char *
868     getword(fp) /* scan a word from fp */
869     register FILE *fp;
870     {
871     static char word[MAXWORD];
872     register char *cp;
873     register int c;
874    
875     while (isspace(c=getc(fp)))
876     ;
877     for (cp = word; c != EOF && cp < word+MAXWORD-1;
878     *cp++ = c, c = getc(fp))
879     if (isspace(c) || c == ',') {
880     while (isspace(c))
881     c = getc(fp);
882     if (c != EOF & c != ',')
883     ungetc(c, fp);
884     *cp = '\0';
885     return(word);
886     }
887     *cp = '\0';
888     return(cp > word ? word : NULL);
889     }
890    
891    
892     cvtint(ip, word) /* convert a word to an integer */
893     int *ip;
894     char *word;
895     {
896     if (word == NULL || !isint(word))
897     return(0);
898     *ip = atoi(word);
899     return(1);
900     }
901    
902    
903     cvtflt(rp, word) /* convert a word to a double */
904     double *rp;
905     char *word;
906     {
907     if (word == NULL || !isflt(word))
908     return(0);
909     *rp = atof(word);
910     return(1);
911 greg 1.1 }