ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/gen/mkillum.c
Revision: 2.33
Committed: Thu Dec 13 07:03:37 2007 UTC (16 years, 4 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R9
Changes since 2.32: +3 -3 lines
Log Message:
Superficially working version of mkillum with BSDF input

File Contents

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