ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/gen/mkillum.c
Revision: 2.31
Committed: Fri Sep 21 05:53:21 2007 UTC (16 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.30: +13 -1 lines
Log Message:
Partial implementation of BSDF incorporation

File Contents

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