ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/gen/mkillum.c
Revision: 2.37
Committed: Mon Aug 15 19:48:06 2011 UTC (12 years, 8 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.36: +1 -2 lines
Log Message:
Made direct visibility (-dv) flag irrelevant and fixed BSDF material sampling

File Contents

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