ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rcmain.c
Revision: 2.9
Committed: Sat Aug 11 01:41:35 2012 UTC (11 years, 8 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.8: +2 -2 lines
Log Message:
Shortened context name to "RC" from "RCONTRIB"

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: rcmain.c,v 2.8 2012/06/27 15:32:58 greg Exp $";
3 #endif
4 /*
5 * rcmain.c - main for rtcontrib ray contribution tracer
6 */
7
8 #include "copyright.h"
9
10 #include <signal.h>
11 #include "rcontrib.h"
12 #include "random.h"
13 #include "source.h"
14 #include "ambient.h"
15
16 int gargc; /* global argc */
17 char **gargv; /* global argv */
18 char *octname; /* global octree name */
19 char *progname; /* global argv[0] */
20
21 char *sigerr[NSIG]; /* signal error messages */
22
23 int nproc = 1; /* number of processes requested */
24 int nchild = 0; /* number of children (-1 in child) */
25
26 int inpfmt = 'a'; /* input format */
27 int outfmt = 'a'; /* output format */
28
29 int header = 1; /* output header? */
30 int force_open = 0; /* truncate existing output? */
31 int recover = 0; /* recover previous output? */
32 int accumulate = 1; /* input rays per output record */
33 int contrib = 0; /* computing contributions? */
34
35 int xres = 0; /* horizontal (scan) size */
36 int yres = 0; /* vertical resolution */
37
38 int using_stdout = 0; /* are we using stdout? */
39
40 int imm_irrad = 0; /* compute immediate irradiance? */
41 int lim_dist = 0; /* limit distance? */
42
43 const char *modname[MAXMODLIST]; /* ordered modifier name list */
44 int nmods = 0; /* number of modifiers */
45
46 void (*addobjnotify[8])() = {ambnotify, NULL};
47
48 char RCCONTEXT[] = "RC"; /* our special evaluation context */
49
50
51 static void
52 printdefaults(void) /* print default values to stdout */
53 {
54 char *cp;
55
56 printf("-c %-5d\t\t\t# accumulated rays per record\n", accumulate);
57 printf("-V%c\t\t\t\t# output %s\n", contrib ? '+' : '-',
58 contrib ? "contributions" : "coefficients");
59 if (imm_irrad)
60 printf("-I+\t\t\t\t# immediate irradiance on\n");
61 printf("-n %-2d\t\t\t\t# number of rendering processes\n", nproc);
62 printf("-x %-9d\t\t\t# %s\n", xres,
63 yres && xres ? "x resolution" : "flush interval");
64 printf("-y %-9d\t\t\t# y resolution\n", yres);
65 printf(lim_dist ? "-ld+\t\t\t\t# limit distance on\n" :
66 "-ld-\t\t\t\t# limit distance off\n");
67 printf("-h%c\t\t\t\t# %s header\n", header ? '+' : '-',
68 header ? "output" : "no");
69 printf("-f%c%c\t\t\t\t# format input/output = %s/%s\n",
70 inpfmt, outfmt, formstr(inpfmt), formstr(outfmt));
71 printf(erract[WARNING].pf != NULL ?
72 "-w+\t\t\t\t# warning messages on\n" :
73 "-w-\t\t\t\t# warning messages off\n");
74 print_rdefaults();
75 }
76
77
78 static void
79 onsig( /* fatal signal */
80 int signo
81 )
82 {
83 static int gotsig = 0;
84
85 if (gotsig++) /* two signals and we're gone! */
86 _exit(signo);
87
88 #ifdef SIGALRM
89 alarm(15); /* allow 15 seconds to clean up */
90 signal(SIGALRM, SIG_DFL); /* make certain we do die */
91 #endif
92 eputs("signal - ");
93 eputs(sigerr[signo]);
94 eputs("\n");
95 quit(3);
96 }
97
98
99 static void
100 sigdie( /* set fatal signal */
101 int signo,
102 char *msg
103 )
104 {
105 if (signal(signo, onsig) == SIG_IGN)
106 signal(signo, SIG_IGN);
107 sigerr[signo] = msg;
108 }
109
110
111 /* set input/output format */
112 static void
113 setformat(const char *fmt)
114 {
115 switch (fmt[0]) {
116 case 'f':
117 case 'd':
118 SET_FILE_BINARY(stdin);
119 /* fall through */
120 case 'a':
121 inpfmt = fmt[0];
122 break;
123 default:
124 goto fmterr;
125 }
126 switch (fmt[1]) {
127 case '\0':
128 outfmt = inpfmt;
129 return;
130 case 'a':
131 case 'f':
132 case 'd':
133 case 'c':
134 outfmt = fmt[1];
135 break;
136 default:
137 goto fmterr;
138 }
139 if (!fmt[2])
140 return;
141 fmterr:
142 sprintf(errmsg, "Illegal i/o format: -f%s", fmt);
143 error(USER, errmsg);
144 }
145
146
147 /* Set overriding options */
148 static void
149 override_options(void)
150 {
151 shadthresh = 0;
152 ambssamp = 0;
153 ambacc = 0;
154 if (accumulate <= 0) /* no output flushing for single record */
155 xres = yres = 0;
156 }
157
158
159 int
160 main(int argc, char *argv[])
161 {
162 #define check(ol,al) if (argv[i][ol] || \
163 badarg(argc-i-1,argv+i+1,al)) \
164 goto badopt
165 #define bool(olen,var) switch (argv[i][olen]) { \
166 case '\0': var = !var; break; \
167 case 'y': case 'Y': case 't': case 'T': \
168 case '+': case '1': var = 1; break; \
169 case 'n': case 'N': case 'f': case 'F': \
170 case '-': case '0': var = 0; break; \
171 default: goto badopt; }
172 char *curout = NULL;
173 char *binval = NULL;
174 int bincnt = 0;
175 int rval;
176 int i;
177 /* global program name */
178 progname = argv[0] = fixargv0(argv[0]);
179 gargv = argv;
180 gargc = argc;
181 /* initialize calcomp routines early */
182 initfunc();
183 setcontext(RCCONTEXT);
184 /* option city */
185 for (i = 1; i < argc; i++) {
186 /* expand arguments */
187 while ((rval = expandarg(&argc, &argv, i)) > 0)
188 ;
189 if (rval < 0) {
190 sprintf(errmsg, "cannot expand '%s'", argv[i]);
191 error(SYSTEM, errmsg);
192 }
193 if (argv[i] == NULL || argv[i][0] != '-')
194 break; /* break from options */
195 if (!strcmp(argv[i], "-version")) {
196 puts(VersionID);
197 quit(0);
198 }
199 if (!strcmp(argv[i], "-defaults") ||
200 !strcmp(argv[i], "-help")) {
201 override_options();
202 printdefaults();
203 quit(0);
204 }
205 rval = getrenderopt(argc-i, argv+i);
206 if (rval >= 0) {
207 i += rval;
208 continue;
209 }
210 switch (argv[i][1]) {
211 case 'n': /* number of cores */
212 check(2,"i");
213 nproc = atoi(argv[++i]);
214 if (nproc <= 0)
215 error(USER, "bad number of processes");
216 break;
217 case 'V': /* output contributions */
218 bool(2,contrib);
219 break;
220 case 'x': /* x resolution */
221 check(2,"i");
222 xres = atoi(argv[++i]);
223 break;
224 case 'y': /* y resolution */
225 check(2,"i");
226 yres = atoi(argv[++i]);
227 break;
228 case 'w': /* warnings */
229 rval = (erract[WARNING].pf != NULL);
230 bool(2,rval);
231 if (rval) erract[WARNING].pf = wputs;
232 else erract[WARNING].pf = NULL;
233 break;
234 case 'e': /* expression */
235 check(2,"s");
236 scompile(argv[++i], NULL, 0);
237 break;
238 case 'l': /* limit distance */
239 if (argv[i][2] != 'd')
240 goto badopt;
241 bool(3,lim_dist);
242 break;
243 case 'I': /* immed. irradiance */
244 bool(2,imm_irrad);
245 break;
246 case 'f': /* file or force or format */
247 if (!argv[i][2]) {
248 check(2,"s");
249 loadfunc(argv[++i]);
250 break;
251 }
252 if (argv[i][2] == 'o') {
253 bool(3,force_open);
254 break;
255 }
256 setformat(argv[i]+2);
257 break;
258 case 'o': /* output */
259 check(2,"s");
260 curout = argv[++i];
261 break;
262 case 'c': /* input rays per output */
263 check(2,"i");
264 accumulate = atoi(argv[++i]);
265 break;
266 case 'r': /* recover output */
267 bool(2,recover);
268 break;
269 case 'h': /* header output */
270 bool(2,header);
271 break;
272 case 'b': /* bin expression/count */
273 if (argv[i][2] == 'n') {
274 check(3,"s");
275 bincnt = (int)(eval(argv[++i]) + .5);
276 break;
277 }
278 check(2,"s");
279 binval = argv[++i];
280 break;
281 case 'm': /* modifier name */
282 check(2,"s");
283 addmodifier(argv[++i], curout, binval, bincnt);
284 break;
285 case 'M': /* modifier file */
286 check(2,"s");
287 addmodfile(argv[++i], curout, binval, bincnt);
288 break;
289 default:
290 goto badopt;
291 }
292 }
293 /* override some option settings */
294 override_options();
295 /* initialize object types */
296 initotypes();
297 /* initialize urand */
298 if (rand_samp) {
299 srandom((long)time(0));
300 initurand(0);
301 } else {
302 srandom(0L);
303 initurand(2048);
304 }
305 /* set up signal handling */
306 sigdie(SIGINT, "Interrupt");
307 #ifdef SIGHUP
308 sigdie(SIGHUP, "Hangup");
309 #endif
310 sigdie(SIGTERM, "Terminate");
311 #ifdef SIGPIPE
312 sigdie(SIGPIPE, "Broken pipe");
313 #endif
314 #ifdef SIGALRM
315 sigdie(SIGALRM, "Alarm clock");
316 #endif
317 #ifdef SIGXCPU
318 sigdie(SIGXCPU, "CPU limit exceeded");
319 sigdie(SIGXFSZ, "File size exceeded");
320 #endif
321 #ifdef NICE
322 nice(NICE); /* lower priority */
323 #endif
324 /* get octree */
325 if (i == argc)
326 octname = NULL;
327 else if (i == argc-1)
328 octname = argv[i];
329 else
330 goto badopt;
331 if (octname == NULL)
332 error(USER, "missing octree argument");
333
334 readoct(octname, ~(IO_FILES|IO_INFO), &thescene, NULL);
335 nsceneobjs = nobjects;
336
337 marksources(); /* find and mark sources */
338
339 setambient(); /* initialize ambient calculation */
340
341 rcontrib(); /* trace ray contributions (loop) */
342
343 ambsync(); /* flush ambient file */
344
345 quit(0); /* exit clean */
346
347 badopt:
348 fprintf(stderr,
349 "Usage: %s [-n nprocs][-V][-r][-e expr][-f source][-o ospec][-b binv][-bn N] {-m mod | -M file} [rtrace options] octree\n",
350 progname);
351 sprintf(errmsg, "command line error at '%s'", argv[i]);
352 error(USER, errmsg);
353 return(1); /* pro forma return */
354
355 #undef check
356 #undef bool
357 }
358
359
360 void
361 wputs( /* warning output function */
362 char *s
363 )
364 {
365 int lasterrno = errno;
366 eputs(s);
367 errno = lasterrno;
368 }
369
370
371 void
372 eputs( /* put string to stderr */
373 char *s
374 )
375 {
376 static int midline = 0;
377
378 if (!*s)
379 return;
380 if (!midline++) {
381 fputs(progname, stderr);
382 fputs(": ", stderr);
383 }
384 fputs(s, stderr);
385 if (s[strlen(s)-1] == '\n') {
386 fflush(stderr);
387 midline = 0;
388 }
389 }