ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/ies2rad.c
Revision: 2.6
Committed: Thu Mar 18 11:21:21 1993 UTC (31 years ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.5: +64 -9 lines
Log Message:
better checking of input data -- allow comma separators

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