ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/gen/mkillum.c
Revision: 2.36
Committed: Sat Dec 12 19:00:59 2009 UTC (14 years, 4 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad4R0
Changes since 2.35: +11 -1 lines
Log Message:
Added -n option to rtrace and moved quit() funciton out of raypcalls

File Contents

# User Rev Content
1 greg 1.1 #ifndef lint
2 greg 2.36 static const char RCSid[] = "$Id: mkillum.c,v 2.35 2009/06/06 05:03:47 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     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 greg 2.36 quit(ec) /* make sure exit is called */
180     int ec;
181     {
182     if (ray_pnprocs > 0) /* close children if any */
183     ray_pclose(0);
184     exit(ec);
185     }
186    
187    
188     void
189 schorsch 2.19 filter( /* process stream */
190     register FILE *infp,
191     char *name
192     )
193 greg 1.1 {
194     char buf[512];
195     FILE *pfp;
196     register int c;
197    
198     while ((c = getc(infp)) != EOF) {
199     if (isspace(c))
200     continue;
201     if (c == '#') { /* comment/options */
202     buf[0] = c;
203     fgets(buf+1, sizeof(buf)-1, infp);
204 greg 1.2 xoptions(buf, name);
205 greg 1.1 } else if (c == '!') { /* command */
206     buf[0] = c;
207     fgetline(buf+1, sizeof(buf)-1, infp);
208     if ((pfp = popen(buf+1, "r")) == NULL) {
209     sprintf(errmsg, "cannot execute \"%s\"", buf);
210     error(SYSTEM, errmsg);
211     }
212 greg 1.2 filter(pfp, buf);
213 greg 1.1 pclose(pfp);
214     } else { /* object */
215     ungetc(c, infp);
216     xobject(infp, name);
217     }
218     }
219     }
220    
221    
222 schorsch 2.19 void
223     xoptions( /* process options in string s */
224     char *s,
225     char *nm
226     )
227 greg 1.1 {
228     extern FILE *freopen();
229     char buf[64];
230 greg 2.30 int negax;
231 greg 1.1 int nerrs = 0;
232     register char *cp;
233    
234 greg 1.2 if (strncmp(s, "#@mkillum", 9) || !isspace(s[9])) {
235     fputs(s, stdout); /* not for us */
236 greg 1.1 return;
237 greg 1.2 }
238 greg 1.1 cp = s+10;
239     while (*cp) {
240     switch (*cp) {
241     case ' ':
242     case '\t':
243     case '\n':
244 greg 2.11 case '\r':
245     case '\f':
246 greg 1.1 cp++;
247     continue;
248     case 'm': /* material name */
249 greg 1.2 if (*++cp != '=')
250 greg 1.1 break;
251 greg 2.8 if (!*++cp || isspace(*cp))
252 greg 1.2 break;
253 greg 1.1 atos(thisillum.matname, MAXSTR, cp);
254     cp = sskip(cp);
255     if (!(thisillum.flags & IL_DATCLB)) {
256     strcpy(thisillum.datafile, thisillum.matname);
257     thisillum.dfnum = 0;
258     }
259     continue;
260     case 'f': /* data file name */
261 greg 1.2 if (*++cp != '=')
262 greg 1.1 break;
263 greg 2.8 if (!*++cp || isspace(*cp)) {
264 greg 1.6 strcpy(thisillum.datafile,thisillum.matname);
265 greg 1.10 thisillum.dfnum = 0;
266 greg 1.1 thisillum.flags &= ~IL_DATCLB;
267     continue;
268     }
269     atos(thisillum.datafile, MAXSTR, cp);
270     cp = sskip(cp);
271     thisillum.dfnum = 0;
272     thisillum.flags |= IL_DATCLB;
273     continue;
274     case 'i': /* include material */
275     case 'e': /* exclude material */
276 greg 1.6 if (cp[1] != '=')
277 greg 1.1 break;
278 greg 1.7 matselect = (*cp == 'i') ? S_ELEM : S_COMPL;
279     cp += 2;
280     atos(matcheck, MAXSTR, cp);
281 greg 1.1 cp = sskip(cp);
282     continue;
283     case 'a': /* use everything */
284     cp = sskip(cp);
285     matselect = S_ALL;
286     continue;
287     case 'n': /* use nothing (passive) */
288     cp = sskip(cp);
289     matselect = S_NONE;
290     continue;
291     case 'c': /* color calculation */
292 greg 1.2 if (*++cp != '=')
293 greg 1.1 break;
294 greg 1.2 switch (*++cp) {
295 greg 1.1 case 'a': /* average */
296 greg 1.6 thisillum.flags = (thisillum.flags|IL_COLAVG)
297     & ~IL_COLDST;
298 greg 1.1 break;
299     case 'd': /* distribution */
300 greg 1.5 thisillum.flags |= (IL_COLDST|IL_COLAVG);
301 greg 1.1 break;
302     case 'n': /* none */
303     thisillum.flags &= ~(IL_COLAVG|IL_COLDST);
304     break;
305     default:
306     goto opterr;
307     }
308     cp = sskip(cp);
309     continue;
310 greg 2.30 case 'd': /* sample density / BSDF data */
311 greg 1.2 if (*++cp != '=')
312 greg 1.1 break;
313 greg 2.30 if (thisillum.sd != NULL) {
314     free_BSDF(thisillum.sd);
315     thisillum.sd = NULL;
316     }
317     if (!*++cp || isspace(*cp))
318     continue;
319 greg 2.33 if (isintd(cp, " \t\n\r")) {
320 greg 2.30 thisillum.sampdens = atoi(cp);
321     } else {
322     atos(buf, sizeof(buf), cp);
323     thisillum.sd = load_BSDF(buf);
324     if (thisillum.sd == NULL)
325     break;
326     }
327 greg 1.1 cp = sskip(cp);
328     continue;
329 greg 2.30 case 's': /* surface super-samples */
330 greg 1.2 if (*++cp != '=')
331 greg 1.1 break;
332 greg 2.11 if (!isintd(++cp, " \t\n\r"))
333 greg 1.1 break;
334     thisillum.nsamps = atoi(cp);
335     cp = sskip(cp);
336     continue;
337 greg 1.3 case 'l': /* light sources */
338 greg 1.4 cp++;
339     if (*cp == '+')
340 greg 1.3 thisillum.flags |= IL_LIGHT;
341 greg 1.4 else if (*cp == '-')
342     thisillum.flags &= ~IL_LIGHT;
343 greg 1.3 else
344 greg 1.4 break;
345     cp++;
346 greg 1.3 continue;
347 greg 1.12 case 'b': /* brightness */
348     if (*++cp != '=')
349     break;
350 greg 2.11 if (!isfltd(++cp, " \t\n\r"))
351 greg 1.12 break;
352     thisillum.minbrt = atof(cp);
353 greg 1.13 if (thisillum.minbrt < 0.)
354     thisillum.minbrt = 0.;
355 greg 1.12 cp = sskip(cp);
356     continue;
357 greg 1.1 case 'o': /* output file */
358 greg 1.2 if (*++cp != '=')
359 greg 1.1 break;
360 greg 2.8 if (!*++cp || isspace(*cp))
361 greg 1.2 break;
362 greg 1.1 atos(buf, sizeof(buf), cp);
363     cp = sskip(cp);
364     if (freopen(buf, "w", stdout) == NULL) {
365     sprintf(errmsg,
366     "cannot open output file \"%s\"", buf);
367     error(SYSTEM, errmsg);
368     }
369     doneheader = 0;
370     continue;
371 greg 2.30 case 'u': /* up direction */
372     if (*++cp != '=')
373     break;
374     if (!*++cp || isspace(*cp)) {
375     thisillum.udir = UDunknown;
376     continue;
377     }
378     negax = 0;
379     if (*cp == '+')
380     cp++;
381     else if (*cp == '-') {
382     negax++;
383     cp++;
384     }
385     switch (*cp++) {
386     case 'x':
387     case 'X':
388     thisillum.udir = negax ? UDxneg : UDxpos;
389     break;
390     case 'y':
391     case 'Y':
392     thisillum.udir = negax ? UDyneg : UDypos;
393     break;
394     case 'z':
395     case 'Z':
396 greg 2.33 thisillum.udir = negax ? UDzneg : UDzpos;
397 greg 2.30 break;
398     default:
399     thisillum.udir = UDunknown;
400     break;
401     }
402     if (thisillum.udir == UDunknown || !isspace(*cp))
403     break;
404     continue;
405 greg 2.31 case 't': /* object thickness */
406     if (*++cp != '=')
407     break;
408     if (!isfltd(++cp, " \t\n\r"))
409     break;
410     thisillum.thick = atof(cp);
411     if (thisillum.thick < .0)
412     thisillum.thick = .0;
413     cp = sskip(cp);
414     continue;
415 greg 1.6 case '!': /* processed file! */
416 greg 1.7 sprintf(errmsg, "(%s): already processed!", nm);
417 greg 1.6 error(WARNING, errmsg);
418 greg 1.7 matselect = S_NONE;
419 greg 1.6 return;
420 greg 1.1 }
421     opterr: /* skip faulty option */
422 greg 2.9 while (*cp && !isspace(*cp))
423     cp++;
424 greg 1.1 nerrs++;
425     }
426 greg 1.2 /* print header? */
427     checkhead();
428     /* issue warnings? */
429 greg 1.1 if (nerrs) {
430     sprintf(errmsg, "(%s): %d error(s) in option line:",
431     nm, nerrs);
432     error(WARNING, errmsg);
433 greg 1.2 wputs(s);
434     printf("# %s: the following option line has %d error(s):\n",
435     progname, nerrs);
436 greg 1.1 }
437 greg 1.2 /* print pure comment */
438 greg 1.4 printf("# %s", s+2);
439 greg 1.9 }
440    
441 schorsch 2.19 void
442     printopts(void) /* print out option default values */
443 greg 1.9 {
444 greg 1.11 printf("m=%-15s\t\t# material name\n", thisillum.matname);
445     printf("f=%-15s\t\t# data file name\n", thisillum.datafile);
446 greg 2.2 if (thisillum.flags & IL_COLAVG)
447     if (thisillum.flags & IL_COLDST)
448     printf("c=d\t\t\t\t# color distribution\n");
449     else
450     printf("c=a\t\t\t\t# color average\n");
451     else
452     printf("c=n\t\t\t\t# color none\n");
453     if (thisillum.flags & IL_LIGHT)
454     printf("l+\t\t\t\t# light type on\n");
455     else
456     printf("l-\t\t\t\t# light type off\n");
457 greg 2.34 printf("d=%d\t\t\t\t# density of directions\n", thisillum.sampdens);
458     printf("s=%d\t\t\t\t# samples per direction\n", thisillum.nsamps);
459 greg 1.12 printf("b=%f\t\t\t# minimum average brightness\n", thisillum.minbrt);
460 greg 2.30 switch (thisillum.udir) {
461     case UDzneg:
462     fputs("u=-Z\t\t\t\t# up is negative Z\n", stdout);
463     break;
464     case UDyneg:
465     fputs("u=-Y\t\t\t\t# up is negative Y\n", stdout);
466     break;
467     case UDxneg:
468     fputs("u=-X\t\t\t\t# up is negative X\n", stdout);
469     break;
470     case UDxpos:
471     fputs("u=+X\t\t\t\t# up is positive X\n", stdout);
472     break;
473     case UDypos:
474     fputs("u=+Y\t\t\t\t# up is positive Y\n", stdout);
475     break;
476     case UDzpos:
477     fputs("u=+Z\t\t\t\t# up is positive Z\n", stdout);
478     break;
479     case UDunknown:
480     break;
481     }
482 greg 2.31 printf("t=%f\t\t\t# object thickness\n", thisillum.thick);
483 greg 1.1 }
484 greg 1.2
485    
486 schorsch 2.19 void
487     printhead( /* print out header */
488     register int ac,
489     register char **av
490     )
491 greg 1.2 {
492     putchar('#');
493     while (ac-- > 0) {
494     putchar(' ');
495     fputs(*av++, stdout);
496     }
497 greg 1.6 fputs("\n#@mkillum !\n", stdout);
498 greg 1.2 }
499    
500    
501 schorsch 2.19 void
502     xobject( /* translate an object from fp */
503     FILE *fp,
504     char *nm
505     )
506 greg 1.2 {
507     OBJREC thisobj;
508     char str[MAXSTR];
509     int doit;
510     /* read the object */
511     if (fgetword(thisillum.altmat, MAXSTR, fp) == NULL)
512     goto readerr;
513     if (fgetword(str, MAXSTR, fp) == NULL)
514     goto readerr;
515     /* is it an alias? */
516 greg 2.12 if (!strcmp(str, ALIASKEY)) {
517 greg 1.2 if (fgetword(str, MAXSTR, fp) == NULL)
518     goto readerr;
519 greg 2.12 printf("\n%s %s %s", thisillum.altmat, ALIASKEY, str);
520 greg 1.2 if (fgetword(str, MAXSTR, fp) == NULL)
521     goto readerr;
522 greg 1.4 printf("\t%s\n", str);
523 greg 1.2 return;
524     }
525 greg 1.4 thisobj.omod = OVOID; /* unused field */
526 greg 1.2 if ((thisobj.otype = otype(str)) < 0) {
527     sprintf(errmsg, "(%s): unknown type \"%s\"", nm, str);
528     error(USER, errmsg);
529     }
530     if (fgetword(str, MAXSTR, fp) == NULL)
531     goto readerr;
532     thisobj.oname = str;
533     if (readfargs(&thisobj.oargs, fp) != 1)
534     goto readerr;
535     thisobj.os = NULL;
536     /* check for translation */
537     switch (matselect) {
538     case S_NONE:
539     doit = 0;
540     break;
541     case S_ALL:
542 greg 1.4 doit = 1;
543 greg 1.2 break;
544     case S_ELEM:
545     doit = !strcmp(thisillum.altmat, matcheck);
546     break;
547     case S_COMPL:
548     doit = strcmp(thisillum.altmat, matcheck);
549     break;
550     }
551 greg 1.4 doit = doit && issurface(thisobj.otype);
552 greg 1.2 /* print header? */
553     checkhead();
554     /* process object */
555     if (doit)
556 greg 2.28 switch (thisobj.otype) {
557     case OBJ_FACE:
558     my_face(&thisobj, &thisillum, nm);
559     break;
560     case OBJ_SPHERE:
561     my_sphere(&thisobj, &thisillum, nm);
562     break;
563     case OBJ_RING:
564     my_ring(&thisobj, &thisillum, nm);
565     break;
566     default:
567     my_default(&thisobj, &thisillum, nm);
568     break;
569     }
570 greg 1.2 else
571     printobj(thisillum.altmat, &thisobj);
572     /* free arguments */
573     freefargs(&thisobj.oargs);
574     return;
575     readerr:
576 greg 2.28 sprintf(errmsg, "(%s): error reading input", nm);
577 greg 1.2 error(USER, errmsg);
578     }