ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/ies2rad.c
Revision: 1.1
Committed: Tue Dec 11 08:45:48 1990 UTC (33 years, 4 months ago) by greg
Content type: text/plain
Branch: MAIN
Log Message:
Initial revision

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