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

# Content
1 /* Copyright (c) 1992 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 <math.h>
15 #include <ctype.h>
16 #include "color.h"
17 #include "paths.h"
18
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 #define T_TLT "%.dat"
44 /* 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 #define abspath(p) (ISDIRSEP((p)[0]) || (p)[0] == '.')
54
55 static char default_name[] = "default";
56
57 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 char *deflamp = NULL; /* default lamp type */
64 float defcolor[3] = {1.,1.,1.}; /* default lamp color */
65 float *lampcolor = defcolor; /* pointer to current lamp color */
66 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 double area; /* max. projected area */
74 } 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 *filename(), *libname(), *fullname(), *malloc(),
81 *getword(), *atos();
82 extern float *matchlamp();
83
84 #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
88
89 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 case 't': /* override lamp type */
169 lamptype = argv[++i];
170 break;
171 case 'u': /* default lamp type */
172 deflamp = argv[++i];
173 break;
174 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 initlamps(); /* get lamp data (if needed) */
191 /* 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 }
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 }
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 libname(stradd(path, libdir, DIRSEP), fname, suffix);
284
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 strcpy(stradd(stradd(path, prefdir, DIRSEP), fname, 0), suffix);
297
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 if (ISDIRSEP(*path))
310 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 if (ISDIRSEP(*p2))
323 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 fputs("# Unknown lamp type (used default)\n", outfp);
411 lampcolor = defcolor;
412 } 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 if (feof(inpfp)) {
416 fprintf(stderr, "%s: not in IES format\n", inpname);
417 goto readerr;
418 }
419 atos(tltid, MAXWORD, buf+TLTSTRLEN);
420 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 if (ISDIRSEP(tltspec[0]))
460 strcpy(buf, tltspec);
461 else
462 strcpy(stradd(buf, dir, DIRSEP), tltspec);
463 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 if (!scnint(datin,&tlt_type) || !scnint(datin,&nangles)
477 || 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 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 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 if (cvdata(in, datout, 2, nangles, 1./WHTEFFICACY, bounds) != 0) {
555 fprintf(stderr, "dosource: bad distribution data\n");
556 fclose(datout);
557 unlink(fullname(buf,name,T_DST));
558 return(-1);
559 }
560 fclose(datout);
561 fprintf(out, "# %g watt luminaire, lamp*ballast factor = %g\n",
562 wattage, bfactor*pfactor);
563 strcat(strcpy(id, filename(name)), "_dist");
564 fprintf(out, "\n%s brightdata %s\n", mod, id);
565 if (nangles[1] < 2)
566 fprintf(out, "4 ");
567 else if (pmtype == PM_B)
568 fprintf(out, "5 ");
569 else if (FEQ(bounds[1][0],90.) && FEQ(bounds[1][1],270.))
570 fprintf(out, "7 ");
571 else
572 fprintf(out, "5 ");
573 fprintf(out, "%s %s source.cal ",
574 srcshape.type==SPHERE ? "corr" : "flatcorr",
575 libname(buf,name,T_DST));
576 if (pmtype == PM_B) {
577 if (FEQ(bounds[1][0],0.))
578 fprintf(out, "srcB_horiz2 ");
579 else
580 fprintf(out, "srcB_horiz ");
581 fprintf(out, "srcB_vert ");
582 } else {
583 if (nangles[1] >= 2) {
584 d1 = bounds[1][1] - bounds[1][0];
585 if (d1 <= 90.+FTINY)
586 fprintf(out, "src_phi4 ");
587 else if (d1 <= 180.+FTINY)
588 fprintf(out, "src_phi2 ");
589 else
590 fprintf(out, "src_phi ");
591 fprintf(out, "src_theta ");
592 if (FEQ(bounds[1][0],90.) && FEQ(bounds[1][1],270.))
593 fprintf(out, "-rz -90 ");
594 } else
595 fprintf(out, "src_theta ");
596 }
597 fprintf(out, "\n0\n1 %g\n", multiplier*mult*bfactor*pfactor);
598 if (putsource(&srcshape, out, id, filename(name),
599 bounds[0][0]<90., bounds[0][1]>90.) != 0)
600 return(-1);
601 return(0);
602 }
603
604
605 putsource(shp, fp, mod, name, dolower, doupper) /* put out source */
606 SHAPE *shp;
607 FILE *fp;
608 char *mod, *name;
609 int dolower, doupper;
610 {
611 char buf[MAXWORD];
612
613 fprintf(fp, "\n%s %s %s_light\n", mod,
614 illumrad>=MINDIM/2. ? "illum" : "light",
615 name);
616 fprintf(fp, "0\n0\n3 %g %g %g\n",
617 lampcolor[0]/shp->area,
618 lampcolor[1]/shp->area,
619 lampcolor[2]/shp->area);
620 if (doupper && dolower && shp->type != SPHERE && shp->h > MINDIM) {
621 fprintf(fp, "\n%s glow %s_glow\n", mod, name);
622 fprintf(fp, "0\n0\n4 %g %g %g -1\n",
623 lampcolor[0]/shp->area,
624 lampcolor[1]/shp->area,
625 lampcolor[2]/shp->area);
626 }
627 switch (shp->type) {
628 case RECT:
629 strcat(strcpy(buf, name), "_light");
630 if (dolower)
631 putrectsrc(shp, fp, buf, name, 0);
632 if (doupper)
633 putrectsrc(shp, fp, buf, name, 1);
634 if (doupper && dolower && shp->h > MINDIM) {
635 strcat(strcpy(buf, name), "_glow");
636 putsides(shp, fp, buf, name);
637 }
638 break;
639 case DISK:
640 strcat(strcpy(buf, name), "_light");
641 if (dolower)
642 putdisksrc(shp, fp, buf, name, 0);
643 if (doupper)
644 putdisksrc(shp, fp, buf, name, 1);
645 if (doupper && dolower && shp->h > MINDIM) {
646 strcat(strcpy(buf, name), "_glow");
647 putcyl(shp, fp, buf, name);
648 }
649 break;
650 case SPHERE:
651 strcat(strcpy(buf, name), "_light");
652 putspheresrc(shp, fp, buf, name);
653 break;
654 }
655 return(0);
656 }
657
658
659 makeshape(shp, width, length, height) /* make source shape */
660 register SHAPE *shp;
661 double width, length, height;
662 {
663 if (illumrad/meters2out >= MINDIM/2.) {
664 shp->type = SPHERE;
665 shp->w = shp->l = shp->h = 2.*illumrad / meters2out;
666 } else if (width < MINDIM) {
667 width = -width;
668 if (width < MINDIM) {
669 shp->type = SPHERE;
670 shp->w = shp->l = shp->h = MINDIM;
671 } else if (height < .5*width) {
672 shp->type = DISK;
673 shp->w = shp->l = width;
674 if (height >= MINDIM)
675 shp->h = height;
676 else
677 shp->h = .5*MINDIM;
678 } else {
679 shp->type = SPHERE;
680 shp->w = shp->l = shp->h = width;
681 }
682 } else {
683 shp->type = RECT;
684 shp->w = width;
685 if (length >= MINDIM)
686 shp->l = length;
687 else
688 shp->l = MINDIM;
689 if (height >= MINDIM)
690 shp->h = height;
691 else
692 shp->h = .5*MINDIM;
693 }
694 switch (shp->type) {
695 case RECT:
696 shp->area = shp->w * shp->l;
697 break;
698 case DISK:
699 case SPHERE:
700 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 double *pt[4];
811 register int i, j;
812 double val;
813 int total;
814
815 total = 1; j = 0;
816 for (i = 0; i < ndim; i++)
817 if (npts[i] > 1) {
818 total *= npts[i];
819 j++;
820 }
821 fprintf(out, "%d\n", j);
822 /* get coordinates */
823 for (i = 0; i < ndim; i++) {
824 pt[i] = (double *)malloc(npts[i]*sizeof(double));
825 for (j = 0; j < npts[i]; j++)
826 if (!scnflt(in, &pt[i][j]))
827 return(-1);
828 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 if (!scnflt(in, &val))
859 return(-1);
860 fprintf(out, "\t%g", val*mult);
861 }
862 putc('\n', out);
863 return(0);
864 }
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 }