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, 6 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

# User Rev Content
1 greg 1.1 #ifndef lint
2 greg 2.31 static const char RCSid[] = "$Id: mkillum.c,v 2.30 2007/09/18 19:51:07 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 2.31 0.,
30 greg 1.2 DFLMAT,
31 greg 1.10 DFLDAT,
32 greg 1.2 0,
33     VOIDID,
34 greg 1.3 SAMPDENS,
35 greg 1.2 NSAMPS,
36 greg 2.30 NULL,
37 greg 1.12 0.,
38 greg 1.2 };
39 greg 1.1
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 greg 1.2 #define checkhead() if (!doneheader++) printhead(gargc,gargv)
48 greg 1.1
49 greg 1.2 int warnings = 1; /* print warnings? */
50    
51 greg 2.28 void init(char *octnm, int np);
52 schorsch 2.19 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 greg 1.1
58 schorsch 2.19
59     int
60     main( /* compute illum distributions using rtrace */
61     int argc,
62     char *argv[]
63     )
64 greg 1.1 {
65 greg 2.20 int nprocs = 1;
66 greg 1.3 FILE *fp;
67 greg 2.28 int rval;
68 greg 1.1 register int i;
69     /* set global arguments */
70 greg 1.3 gargv = argv;
71 greg 2.28 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 greg 2.29 for (i = 1; i < argc; i++) {
79 greg 2.28 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 greg 1.3 break;
87 greg 2.28 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 greg 1.1 }
107 greg 2.28 i += rval;
108 greg 1.1 }
109 greg 2.28 gargc = ++i;
110     /* add "mandatory" render options */
111     do_irrad = 0;
112     if (gargc > argc || argv[gargc-1][0] == '-')
113 greg 2.3 error(USER, "missing octree argument");
114 greg 1.1 /* else initialize and run our calculation */
115 greg 2.28 init(argv[gargc-1], nprocs);
116     if (gargc < argc) {
117     if (gargc == argc-1 || argv[gargc][0] != '<' || argv[gargc][1])
118 greg 2.30 error(USER, "use '< file1 file2 ..' for multiple inputs");
119 greg 1.3 for (i = gargc+1; i < argc; i++) {
120 greg 1.5 if ((fp = fopen(argv[i], "r")) == NULL) {
121 greg 1.3 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 greg 2.28 } else
129 greg 1.3 filter(stdin, "standard input");
130 greg 2.20 quit(0);
131 schorsch 2.27 return 0; /* pro forma return */
132 greg 1.1 }
133    
134 schorsch 2.26
135 greg 2.11 void
136 greg 2.28 init(char *octnm, int np) /* start rendering process(es) */
137 greg 1.3 {
138     /* set up signal handling */
139 greg 2.25 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 greg 1.3 signal(SIGPIPE, quit);
148 schorsch 2.13 #endif
149 greg 2.28 /* start rendering process(es) */
150     ray_pinit(octnm, np);
151 greg 1.1 }
152    
153    
154 greg 2.11 void
155 schorsch 2.19 eputs( /* put string to stderr */
156     register char *s
157     )
158 greg 1.1 {
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 greg 2.11 void
172 greg 1.2 wputs(s) /* print warning if enabled */
173     char *s;
174     {
175     if (warnings)
176     eputs(s);
177     }
178    
179    
180 schorsch 2.19 void
181     filter( /* process stream */
182     register FILE *infp,
183     char *name
184     )
185 greg 1.1 {
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 greg 1.2 xoptions(buf, name);
197 greg 1.1 } 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 greg 1.2 filter(pfp, buf);
205 greg 1.1 pclose(pfp);
206     } else { /* object */
207     ungetc(c, infp);
208     xobject(infp, name);
209     }
210     }
211     }
212    
213    
214 schorsch 2.19 void
215     xoptions( /* process options in string s */
216     char *s,
217     char *nm
218     )
219 greg 1.1 {
220     extern FILE *freopen();
221     char buf[64];
222 greg 2.30 int negax;
223 greg 1.1 int nerrs = 0;
224     register char *cp;
225    
226 greg 1.2 if (strncmp(s, "#@mkillum", 9) || !isspace(s[9])) {
227     fputs(s, stdout); /* not for us */
228 greg 1.1 return;
229 greg 1.2 }
230 greg 1.1 cp = s+10;
231     while (*cp) {
232     switch (*cp) {
233     case ' ':
234     case '\t':
235     case '\n':
236 greg 2.11 case '\r':
237     case '\f':
238 greg 1.1 cp++;
239     continue;
240     case 'm': /* material name */
241 greg 1.2 if (*++cp != '=')
242 greg 1.1 break;
243 greg 2.8 if (!*++cp || isspace(*cp))
244 greg 1.2 break;
245 greg 1.1 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 greg 1.2 if (*++cp != '=')
254 greg 1.1 break;
255 greg 2.8 if (!*++cp || isspace(*cp)) {
256 greg 1.6 strcpy(thisillum.datafile,thisillum.matname);
257 greg 1.10 thisillum.dfnum = 0;
258 greg 1.1 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 greg 1.6 if (cp[1] != '=')
269 greg 1.1 break;
270 greg 1.7 matselect = (*cp == 'i') ? S_ELEM : S_COMPL;
271     cp += 2;
272     atos(matcheck, MAXSTR, cp);
273 greg 1.1 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 greg 1.2 if (*++cp != '=')
285 greg 1.1 break;
286 greg 1.2 switch (*++cp) {
287 greg 1.1 case 'a': /* average */
288 greg 1.6 thisillum.flags = (thisillum.flags|IL_COLAVG)
289     & ~IL_COLDST;
290 greg 1.1 break;
291     case 'd': /* distribution */
292 greg 1.5 thisillum.flags |= (IL_COLDST|IL_COLAVG);
293 greg 1.1 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 greg 2.30 case 'd': /* sample density / BSDF data */
303 greg 1.2 if (*++cp != '=')
304 greg 1.1 break;
305 greg 2.30 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 greg 1.1 cp = sskip(cp);
320     continue;
321 greg 2.30 case 's': /* surface super-samples */
322 greg 1.2 if (*++cp != '=')
323 greg 1.1 break;
324 greg 2.11 if (!isintd(++cp, " \t\n\r"))
325 greg 1.1 break;
326     thisillum.nsamps = atoi(cp);
327     cp = sskip(cp);
328     continue;
329 greg 1.3 case 'l': /* light sources */
330 greg 1.4 cp++;
331     if (*cp == '+')
332 greg 1.3 thisillum.flags |= IL_LIGHT;
333 greg 1.4 else if (*cp == '-')
334     thisillum.flags &= ~IL_LIGHT;
335 greg 1.3 else
336 greg 1.4 break;
337     cp++;
338 greg 1.3 continue;
339 greg 1.12 case 'b': /* brightness */
340     if (*++cp != '=')
341     break;
342 greg 2.11 if (!isfltd(++cp, " \t\n\r"))
343 greg 1.12 break;
344     thisillum.minbrt = atof(cp);
345 greg 1.13 if (thisillum.minbrt < 0.)
346     thisillum.minbrt = 0.;
347 greg 1.12 cp = sskip(cp);
348     continue;
349 greg 1.1 case 'o': /* output file */
350 greg 1.2 if (*++cp != '=')
351 greg 1.1 break;
352 greg 2.8 if (!*++cp || isspace(*cp))
353 greg 1.2 break;
354 greg 1.1 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 greg 2.30 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 greg 2.31 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 greg 1.6 case '!': /* processed file! */
408 greg 1.7 sprintf(errmsg, "(%s): already processed!", nm);
409 greg 1.6 error(WARNING, errmsg);
410 greg 1.7 matselect = S_NONE;
411 greg 1.6 return;
412 greg 1.1 }
413     opterr: /* skip faulty option */
414 greg 2.9 while (*cp && !isspace(*cp))
415     cp++;
416 greg 1.1 nerrs++;
417     }
418 greg 1.2 /* print header? */
419     checkhead();
420     /* issue warnings? */
421 greg 1.1 if (nerrs) {
422     sprintf(errmsg, "(%s): %d error(s) in option line:",
423     nm, nerrs);
424     error(WARNING, errmsg);
425 greg 1.2 wputs(s);
426     printf("# %s: the following option line has %d error(s):\n",
427     progname, nerrs);
428 greg 1.1 }
429 greg 1.2 /* print pure comment */
430 greg 1.4 printf("# %s", s+2);
431 greg 1.9 }
432    
433 schorsch 2.19 void
434     printopts(void) /* print out option default values */
435 greg 1.9 {
436 greg 1.11 printf("m=%-15s\t\t# material name\n", thisillum.matname);
437     printf("f=%-15s\t\t# data file name\n", thisillum.datafile);
438 greg 2.2 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 greg 1.9 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 greg 1.12 printf("b=%f\t\t\t# minimum average brightness\n", thisillum.minbrt);
452 greg 2.30 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 greg 2.31 printf("t=%f\t\t\t# object thickness\n", thisillum.thick);
475 greg 1.1 }
476 greg 1.2
477    
478 schorsch 2.19 void
479     printhead( /* print out header */
480     register int ac,
481     register char **av
482     )
483 greg 1.2 {
484     putchar('#');
485     while (ac-- > 0) {
486     putchar(' ');
487     fputs(*av++, stdout);
488     }
489 greg 1.6 fputs("\n#@mkillum !\n", stdout);
490 greg 1.2 }
491    
492    
493 schorsch 2.19 void
494     xobject( /* translate an object from fp */
495     FILE *fp,
496     char *nm
497     )
498 greg 1.2 {
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 greg 2.12 if (!strcmp(str, ALIASKEY)) {
509 greg 1.2 if (fgetword(str, MAXSTR, fp) == NULL)
510     goto readerr;
511 greg 2.12 printf("\n%s %s %s", thisillum.altmat, ALIASKEY, str);
512 greg 1.2 if (fgetword(str, MAXSTR, fp) == NULL)
513     goto readerr;
514 greg 1.4 printf("\t%s\n", str);
515 greg 1.2 return;
516     }
517 greg 1.4 thisobj.omod = OVOID; /* unused field */
518 greg 1.2 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 greg 1.4 doit = 1;
535 greg 1.2 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 greg 1.4 doit = doit && issurface(thisobj.otype);
544 greg 1.2 /* print header? */
545     checkhead();
546     /* process object */
547     if (doit)
548 greg 2.28 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 greg 1.2 else
563     printobj(thisillum.altmat, &thisobj);
564     /* free arguments */
565     freefargs(&thisobj.oargs);
566     return;
567     readerr:
568 greg 2.28 sprintf(errmsg, "(%s): error reading input", nm);
569 greg 1.2 error(USER, errmsg);
570     }