ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/ies2rad.c
Revision: 2.5
Committed: Mon Feb 22 15:54:55 1993 UTC (31 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.4: +1 -1 lines
Log Message:
modified to generate glow types with negative radii of influence

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