ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/gen/mkillum.c
Revision: 2.30
Committed: Tue Sep 18 19:51:07 2007 UTC (16 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.29: +77 -7 lines
Log Message:
Partway addition of BSDF data in mkillum

File Contents

# User Rev Content
1 greg 1.1 #ifndef lint
2 greg 2.30 static const char RCSid[] = "$Id: mkillum.c,v 2.29 2007/09/14 21:29:08 greg Exp $";
3 greg 1.1 #endif
4     /*
5     * Make illum sources for optimizing rendering process
6     */
7    
8 greg 1.3 #include <signal.h>
9 schorsch 2.13 #include <ctype.h>
10 greg 1.3
11 greg 2.18 #include "platform.h"
12 greg 2.15 #include "mkillum.h"
13 schorsch 2.19 #include "random.h"
14 greg 1.1
15     /* default parameters */
16 greg 1.8 #define SAMPDENS 48 /* points per projected steradian */
17 greg 1.1 #define NSAMPS 32 /* samples per point */
18     #define DFLMAT "illum_mat" /* material name */
19 greg 1.10 #define DFLDAT "illum" /* data file name */
20 greg 1.1 /* selection options */
21     #define S_NONE 0 /* select none */
22     #define S_ELEM 1 /* select specified element */
23     #define S_COMPL 2 /* select all but element */
24     #define S_ALL 3 /* select all */
25    
26 greg 1.2 struct illum_args thisillum = { /* our illum and default values */
27     0,
28 greg 2.30 UDzpos,
29 greg 1.2 DFLMAT,
30 greg 1.10 DFLDAT,
31 greg 1.2 0,
32     VOIDID,
33 greg 1.3 SAMPDENS,
34 greg 1.2 NSAMPS,
35 greg 2.30 NULL,
36 greg 1.12 0.,
37 greg 1.2 };
38 greg 1.1
39     char matcheck[MAXSTR]; /* current material to include or exclude */
40     int matselect = S_ALL; /* selection criterion */
41    
42     int gargc; /* global argc */
43     char **gargv; /* global argv */
44    
45     int doneheader = 0; /* printed header yet? */
46 greg 1.2 #define checkhead() if (!doneheader++) printhead(gargc,gargv)
47 greg 1.1
48 greg 1.2 int warnings = 1; /* print warnings? */
49    
50 greg 2.28 void init(char *octnm, int np);
51 schorsch 2.19 void filter(register FILE *infp, char *name);
52     void xoptions(char *s, char *nm);
53     void printopts(void);
54     void printhead(register int ac, register char **av);
55     void xobject(FILE *fp, char *nm);
56 greg 1.1
57 schorsch 2.19
58     int
59     main( /* compute illum distributions using rtrace */
60     int argc,
61     char *argv[]
62     )
63 greg 1.1 {
64 greg 2.20 int nprocs = 1;
65 greg 1.3 FILE *fp;
66 greg 2.28 int rval;
67 greg 1.1 register int i;
68     /* set global arguments */
69 greg 1.3 gargv = argv;
70 greg 2.28 progname = gargv[0];
71     /* set up rendering defaults */
72     dstrsrc = 0.25;
73     directrelay = 3;
74     directvis = 0;
75     ambounce = 2;
76     /* get options from command line */
77 greg 2.29 for (i = 1; i < argc; i++) {
78 greg 2.28 while ((rval = expandarg(&argc, &argv, i)) > 0)
79     ;
80     if (rval < 0) {
81     sprintf(errmsg, "cannot expand '%s'", argv[i]);
82     error(SYSTEM, errmsg);
83     }
84     if (argv[i][0] != '-')
85 greg 1.3 break;
86 greg 2.28 if (!strcmp(argv[i], "-w")) {
87     warnings = 0;
88     continue;
89     }
90     if (!strcmp(argv[i], "-n")) {
91     nprocs = atoi(argv[++i]);
92     if (nprocs <= 0)
93     error(USER, "illegal number of processes");
94     continue;
95     }
96     if (!strcmp(argv[i], "-defaults")) {
97     printopts();
98     print_rdefaults();
99     quit(0);
100     }
101     rval = getrenderopt(argc-i, argv+i);
102     if (rval < 0) {
103     sprintf(errmsg, "bad render option at '%s'", argv[i]);
104     error(USER, errmsg);
105 greg 1.1 }
106 greg 2.28 i += rval;
107 greg 1.1 }
108 greg 2.28 gargc = ++i;
109     /* add "mandatory" render options */
110     do_irrad = 0;
111     if (gargc > argc || argv[gargc-1][0] == '-')
112 greg 2.3 error(USER, "missing octree argument");
113 greg 1.1 /* else initialize and run our calculation */
114 greg 2.28 init(argv[gargc-1], nprocs);
115     if (gargc < argc) {
116     if (gargc == argc-1 || argv[gargc][0] != '<' || argv[gargc][1])
117 greg 2.30 error(USER, "use '< file1 file2 ..' for multiple inputs");
118 greg 1.3 for (i = gargc+1; i < argc; i++) {
119 greg 1.5 if ((fp = fopen(argv[i], "r")) == NULL) {
120 greg 1.3 sprintf(errmsg,
121     "cannot open scene file \"%s\"", argv[i]);
122     error(SYSTEM, errmsg);
123     }
124     filter(fp, argv[i]);
125     fclose(fp);
126     }
127 greg 2.28 } else
128 greg 1.3 filter(stdin, "standard input");
129 greg 2.20 quit(0);
130 schorsch 2.27 return 0; /* pro forma return */
131 greg 1.1 }
132    
133 schorsch 2.26
134 greg 2.11 void
135 greg 2.28 init(char *octnm, int np) /* start rendering process(es) */
136 greg 1.3 {
137     /* set up signal handling */
138 greg 2.25 signal(SIGINT, quit);
139     #ifdef SIGHUP
140     signal(SIGHUP, quit);
141     #endif
142     #ifdef SIGTERM
143     signal(SIGTERM, quit);
144     #endif
145     #ifdef SIGPIPE
146 greg 1.3 signal(SIGPIPE, quit);
147 schorsch 2.13 #endif
148 greg 2.28 /* start rendering process(es) */
149     ray_pinit(octnm, np);
150 greg 1.1 }
151    
152    
153 greg 2.11 void
154 schorsch 2.19 eputs( /* put string to stderr */
155     register char *s
156     )
157 greg 1.1 {
158     static int midline = 0;
159    
160     if (!*s) return;
161     if (!midline) {
162     fputs(progname, stderr);
163     fputs(": ", stderr);
164     }
165     fputs(s, stderr);
166     midline = s[strlen(s)-1] != '\n';
167     }
168    
169    
170 greg 2.11 void
171 greg 1.2 wputs(s) /* print warning if enabled */
172     char *s;
173     {
174     if (warnings)
175     eputs(s);
176     }
177    
178    
179 schorsch 2.19 void
180     filter( /* process stream */
181     register FILE *infp,
182     char *name
183     )
184 greg 1.1 {
185     char buf[512];
186     FILE *pfp;
187     register int c;
188    
189     while ((c = getc(infp)) != EOF) {
190     if (isspace(c))
191     continue;
192     if (c == '#') { /* comment/options */
193     buf[0] = c;
194     fgets(buf+1, sizeof(buf)-1, infp);
195 greg 1.2 xoptions(buf, name);
196 greg 1.1 } else if (c == '!') { /* command */
197     buf[0] = c;
198     fgetline(buf+1, sizeof(buf)-1, infp);
199     if ((pfp = popen(buf+1, "r")) == NULL) {
200     sprintf(errmsg, "cannot execute \"%s\"", buf);
201     error(SYSTEM, errmsg);
202     }
203 greg 1.2 filter(pfp, buf);
204 greg 1.1 pclose(pfp);
205     } else { /* object */
206     ungetc(c, infp);
207     xobject(infp, name);
208     }
209     }
210     }
211    
212    
213 schorsch 2.19 void
214     xoptions( /* process options in string s */
215     char *s,
216     char *nm
217     )
218 greg 1.1 {
219     extern FILE *freopen();
220     char buf[64];
221 greg 2.30 int negax;
222 greg 1.1 int nerrs = 0;
223     register char *cp;
224    
225 greg 1.2 if (strncmp(s, "#@mkillum", 9) || !isspace(s[9])) {
226     fputs(s, stdout); /* not for us */
227 greg 1.1 return;
228 greg 1.2 }
229 greg 1.1 cp = s+10;
230     while (*cp) {
231     switch (*cp) {
232     case ' ':
233     case '\t':
234     case '\n':
235 greg 2.11 case '\r':
236     case '\f':
237 greg 1.1 cp++;
238     continue;
239     case 'm': /* material name */
240 greg 1.2 if (*++cp != '=')
241 greg 1.1 break;
242 greg 2.8 if (!*++cp || isspace(*cp))
243 greg 1.2 break;
244 greg 1.1 atos(thisillum.matname, MAXSTR, cp);
245     cp = sskip(cp);
246     if (!(thisillum.flags & IL_DATCLB)) {
247     strcpy(thisillum.datafile, thisillum.matname);
248     thisillum.dfnum = 0;
249     }
250     continue;
251     case 'f': /* data file name */
252 greg 1.2 if (*++cp != '=')
253 greg 1.1 break;
254 greg 2.8 if (!*++cp || isspace(*cp)) {
255 greg 1.6 strcpy(thisillum.datafile,thisillum.matname);
256 greg 1.10 thisillum.dfnum = 0;
257 greg 1.1 thisillum.flags &= ~IL_DATCLB;
258     continue;
259     }
260     atos(thisillum.datafile, MAXSTR, cp);
261     cp = sskip(cp);
262     thisillum.dfnum = 0;
263     thisillum.flags |= IL_DATCLB;
264     continue;
265     case 'i': /* include material */
266     case 'e': /* exclude material */
267 greg 1.6 if (cp[1] != '=')
268 greg 1.1 break;
269 greg 1.7 matselect = (*cp == 'i') ? S_ELEM : S_COMPL;
270     cp += 2;
271     atos(matcheck, MAXSTR, cp);
272 greg 1.1 cp = sskip(cp);
273     continue;
274     case 'a': /* use everything */
275     cp = sskip(cp);
276     matselect = S_ALL;
277     continue;
278     case 'n': /* use nothing (passive) */
279     cp = sskip(cp);
280     matselect = S_NONE;
281     continue;
282     case 'c': /* color calculation */
283 greg 1.2 if (*++cp != '=')
284 greg 1.1 break;
285 greg 1.2 switch (*++cp) {
286 greg 1.1 case 'a': /* average */
287 greg 1.6 thisillum.flags = (thisillum.flags|IL_COLAVG)
288     & ~IL_COLDST;
289 greg 1.1 break;
290     case 'd': /* distribution */
291 greg 1.5 thisillum.flags |= (IL_COLDST|IL_COLAVG);
292 greg 1.1 break;
293     case 'n': /* none */
294     thisillum.flags &= ~(IL_COLAVG|IL_COLDST);
295     break;
296     default:
297     goto opterr;
298     }
299     cp = sskip(cp);
300     continue;
301 greg 2.30 case 'd': /* sample density / BSDF data */
302 greg 1.2 if (*++cp != '=')
303 greg 1.1 break;
304 greg 2.30 if (thisillum.sd != NULL) {
305     free_BSDF(thisillum.sd);
306     thisillum.sd = NULL;
307     }
308     if (!*++cp || isspace(*cp))
309     continue;
310     if (isintd(++cp, " \t\n\r")) {
311     thisillum.sampdens = atoi(cp);
312     } else {
313     atos(buf, sizeof(buf), cp);
314     thisillum.sd = load_BSDF(buf);
315     if (thisillum.sd == NULL)
316     break;
317     }
318 greg 1.1 cp = sskip(cp);
319     continue;
320 greg 2.30 case 's': /* surface super-samples */
321 greg 1.2 if (*++cp != '=')
322 greg 1.1 break;
323 greg 2.11 if (!isintd(++cp, " \t\n\r"))
324 greg 1.1 break;
325     thisillum.nsamps = atoi(cp);
326     cp = sskip(cp);
327     continue;
328 greg 1.3 case 'l': /* light sources */
329 greg 1.4 cp++;
330     if (*cp == '+')
331 greg 1.3 thisillum.flags |= IL_LIGHT;
332 greg 1.4 else if (*cp == '-')
333     thisillum.flags &= ~IL_LIGHT;
334 greg 1.3 else
335 greg 1.4 break;
336     cp++;
337 greg 1.3 continue;
338 greg 1.12 case 'b': /* brightness */
339     if (*++cp != '=')
340     break;
341 greg 2.11 if (!isfltd(++cp, " \t\n\r"))
342 greg 1.12 break;
343     thisillum.minbrt = atof(cp);
344 greg 1.13 if (thisillum.minbrt < 0.)
345     thisillum.minbrt = 0.;
346 greg 1.12 cp = sskip(cp);
347     continue;
348 greg 1.1 case 'o': /* output file */
349 greg 1.2 if (*++cp != '=')
350 greg 1.1 break;
351 greg 2.8 if (!*++cp || isspace(*cp))
352 greg 1.2 break;
353 greg 1.1 atos(buf, sizeof(buf), cp);
354     cp = sskip(cp);
355     if (freopen(buf, "w", stdout) == NULL) {
356     sprintf(errmsg,
357     "cannot open output file \"%s\"", buf);
358     error(SYSTEM, errmsg);
359     }
360     doneheader = 0;
361     continue;
362 greg 2.30 case 'u': /* up direction */
363     if (*++cp != '=')
364     break;
365     if (!*++cp || isspace(*cp)) {
366     thisillum.udir = UDunknown;
367     continue;
368     }
369     negax = 0;
370     if (*cp == '+')
371     cp++;
372     else if (*cp == '-') {
373     negax++;
374     cp++;
375     }
376     switch (*cp++) {
377     case 'x':
378     case 'X':
379     thisillum.udir = negax ? UDxneg : UDxpos;
380     break;
381     case 'y':
382     case 'Y':
383     thisillum.udir = negax ? UDyneg : UDypos;
384     break;
385     case 'z':
386     case 'Z':
387     thisillum.udir = negax ? UDxneg : UDxpos;
388     break;
389     default:
390     thisillum.udir = UDunknown;
391     break;
392     }
393     if (thisillum.udir == UDunknown || !isspace(*cp))
394     break;
395     continue;
396 greg 1.6 case '!': /* processed file! */
397 greg 1.7 sprintf(errmsg, "(%s): already processed!", nm);
398 greg 1.6 error(WARNING, errmsg);
399 greg 1.7 matselect = S_NONE;
400 greg 1.6 return;
401 greg 1.1 }
402     opterr: /* skip faulty option */
403 greg 2.9 while (*cp && !isspace(*cp))
404     cp++;
405 greg 1.1 nerrs++;
406     }
407 greg 1.2 /* print header? */
408     checkhead();
409     /* issue warnings? */
410 greg 1.1 if (nerrs) {
411     sprintf(errmsg, "(%s): %d error(s) in option line:",
412     nm, nerrs);
413     error(WARNING, errmsg);
414 greg 1.2 wputs(s);
415     printf("# %s: the following option line has %d error(s):\n",
416     progname, nerrs);
417 greg 1.1 }
418 greg 1.2 /* print pure comment */
419 greg 1.4 printf("# %s", s+2);
420 greg 1.9 }
421    
422 schorsch 2.19 void
423     printopts(void) /* print out option default values */
424 greg 1.9 {
425 greg 1.11 printf("m=%-15s\t\t# material name\n", thisillum.matname);
426     printf("f=%-15s\t\t# data file name\n", thisillum.datafile);
427 greg 2.2 if (thisillum.flags & IL_COLAVG)
428     if (thisillum.flags & IL_COLDST)
429     printf("c=d\t\t\t\t# color distribution\n");
430     else
431     printf("c=a\t\t\t\t# color average\n");
432     else
433     printf("c=n\t\t\t\t# color none\n");
434     if (thisillum.flags & IL_LIGHT)
435     printf("l+\t\t\t\t# light type on\n");
436     else
437     printf("l-\t\t\t\t# light type off\n");
438 greg 1.9 printf("d=%d\t\t\t\t# density of points\n", thisillum.sampdens);
439     printf("s=%d\t\t\t\t# samples per point\n", thisillum.nsamps);
440 greg 1.12 printf("b=%f\t\t\t# minimum average brightness\n", thisillum.minbrt);
441 greg 2.30 switch (thisillum.udir) {
442     case UDzneg:
443     fputs("u=-Z\t\t\t\t# up is negative Z\n", stdout);
444     break;
445     case UDyneg:
446     fputs("u=-Y\t\t\t\t# up is negative Y\n", stdout);
447     break;
448     case UDxneg:
449     fputs("u=-X\t\t\t\t# up is negative X\n", stdout);
450     break;
451     case UDxpos:
452     fputs("u=+X\t\t\t\t# up is positive X\n", stdout);
453     break;
454     case UDypos:
455     fputs("u=+Y\t\t\t\t# up is positive Y\n", stdout);
456     break;
457     case UDzpos:
458     fputs("u=+Z\t\t\t\t# up is positive Z\n", stdout);
459     break;
460     case UDunknown:
461     break;
462     }
463 greg 1.1 }
464 greg 1.2
465    
466 schorsch 2.19 void
467     printhead( /* print out header */
468     register int ac,
469     register char **av
470     )
471 greg 1.2 {
472     putchar('#');
473     while (ac-- > 0) {
474     putchar(' ');
475     fputs(*av++, stdout);
476     }
477 greg 1.6 fputs("\n#@mkillum !\n", stdout);
478 greg 1.2 }
479    
480    
481 schorsch 2.19 void
482     xobject( /* translate an object from fp */
483     FILE *fp,
484     char *nm
485     )
486 greg 1.2 {
487     OBJREC thisobj;
488     char str[MAXSTR];
489     int doit;
490     /* read the object */
491     if (fgetword(thisillum.altmat, MAXSTR, fp) == NULL)
492     goto readerr;
493     if (fgetword(str, MAXSTR, fp) == NULL)
494     goto readerr;
495     /* is it an alias? */
496 greg 2.12 if (!strcmp(str, ALIASKEY)) {
497 greg 1.2 if (fgetword(str, MAXSTR, fp) == NULL)
498     goto readerr;
499 greg 2.12 printf("\n%s %s %s", thisillum.altmat, ALIASKEY, str);
500 greg 1.2 if (fgetword(str, MAXSTR, fp) == NULL)
501     goto readerr;
502 greg 1.4 printf("\t%s\n", str);
503 greg 1.2 return;
504     }
505 greg 1.4 thisobj.omod = OVOID; /* unused field */
506 greg 1.2 if ((thisobj.otype = otype(str)) < 0) {
507     sprintf(errmsg, "(%s): unknown type \"%s\"", nm, str);
508     error(USER, errmsg);
509     }
510     if (fgetword(str, MAXSTR, fp) == NULL)
511     goto readerr;
512     thisobj.oname = str;
513     if (readfargs(&thisobj.oargs, fp) != 1)
514     goto readerr;
515     thisobj.os = NULL;
516     /* check for translation */
517     switch (matselect) {
518     case S_NONE:
519     doit = 0;
520     break;
521     case S_ALL:
522 greg 1.4 doit = 1;
523 greg 1.2 break;
524     case S_ELEM:
525     doit = !strcmp(thisillum.altmat, matcheck);
526     break;
527     case S_COMPL:
528     doit = strcmp(thisillum.altmat, matcheck);
529     break;
530     }
531 greg 1.4 doit = doit && issurface(thisobj.otype);
532 greg 1.2 /* print header? */
533     checkhead();
534     /* process object */
535     if (doit)
536 greg 2.28 switch (thisobj.otype) {
537     case OBJ_FACE:
538     my_face(&thisobj, &thisillum, nm);
539     break;
540     case OBJ_SPHERE:
541     my_sphere(&thisobj, &thisillum, nm);
542     break;
543     case OBJ_RING:
544     my_ring(&thisobj, &thisillum, nm);
545     break;
546     default:
547     my_default(&thisobj, &thisillum, nm);
548     break;
549     }
550 greg 1.2 else
551     printobj(thisillum.altmat, &thisobj);
552     /* free arguments */
553     freefargs(&thisobj.oargs);
554     return;
555     readerr:
556 greg 2.28 sprintf(errmsg, "(%s): error reading input", nm);
557 greg 1.2 error(USER, errmsg);
558     }