ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rcmain.c
Revision: 2.6
Committed: Fri Jun 22 21:58:45 2012 UTC (11 years, 10 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.5: +2 -1 lines
Log Message:
More portability fixes (missing headers)

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: rcmain.c,v 2.5 2012/06/21 17:14:32 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[] = "RCONTRIB"; /* 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 int nprocs = 1;
173 char *curout = NULL;
174 char *binval = NULL;
175 int bincnt = 0;
176 int rval;
177 int i;
178 /* global program name */
179 progname = argv[0] = fixargv0(argv[0]);
180 gargv = argv;
181 gargc = argc;
182 /* initialize calcomp routines early */
183 initfunc();
184 setcontext(RCCONTEXT);
185 /* option city */
186 for (i = 1; i < argc; i++) {
187 /* expand arguments */
188 while ((rval = expandarg(&argc, &argv, i)) > 0)
189 ;
190 if (rval < 0) {
191 sprintf(errmsg, "cannot expand '%s'", argv[i]);
192 error(SYSTEM, errmsg);
193 }
194 if (argv[i] == NULL || argv[i][0] != '-')
195 break; /* break from options */
196 if (!strcmp(argv[i], "-version")) {
197 puts(VersionID);
198 quit(0);
199 }
200 if (!strcmp(argv[i], "-defaults") ||
201 !strcmp(argv[i], "-help")) {
202 override_options();
203 printdefaults();
204 quit(0);
205 }
206 rval = getrenderopt(argc-i, argv+i);
207 if (rval >= 0) {
208 i += rval;
209 continue;
210 }
211 switch (argv[i][1]) {
212 case 'n': /* number of cores */
213 check(2,"i");
214 nproc = atoi(argv[++i]);
215 if (nproc <= 0)
216 error(USER, "bad number of processes");
217 break;
218 case 'V': /* output contributions */
219 bool(2,contrib);
220 break;
221 case 'x': /* x resolution */
222 check(2,"i");
223 xres = atoi(argv[++i]);
224 break;
225 case 'y': /* y resolution */
226 check(2,"i");
227 yres = atoi(argv[++i]);
228 break;
229 case 'w': /* warnings */
230 rval = (erract[WARNING].pf != NULL);
231 bool(2,rval);
232 if (rval) erract[WARNING].pf = wputs;
233 else erract[WARNING].pf = NULL;
234 break;
235 case 'e': /* expression */
236 check(2,"s");
237 scompile(argv[++i], NULL, 0);
238 break;
239 case 'l': /* limit distance */
240 if (argv[i][2] != 'd')
241 goto badopt;
242 bool(3,lim_dist);
243 break;
244 case 'I': /* immed. irradiance */
245 bool(2,imm_irrad);
246 break;
247 case 'f': /* file or force or format */
248 if (!argv[i][2]) {
249 check(2,"s");
250 loadfunc(argv[++i]);
251 break;
252 }
253 if (argv[i][2] == 'o') {
254 bool(3,force_open);
255 break;
256 }
257 setformat(argv[i]+2);
258 break;
259 case 'o': /* output */
260 check(2,"s");
261 curout = argv[++i];
262 break;
263 case 'c': /* input rays per output */
264 check(2,"i");
265 accumulate = atoi(argv[++i]);
266 break;
267 case 'r': /* recover output */
268 bool(2,recover);
269 break;
270 case 'h': /* header output */
271 bool(2,header);
272 break;
273 case 'b': /* bin expression/count */
274 if (argv[i][2] == 'n') {
275 check(3,"s");
276 bincnt = (int)(eval(argv[++i]) + .5);
277 break;
278 }
279 check(2,"s");
280 binval = argv[++i];
281 break;
282 case 'm': /* modifier name */
283 check(2,"s");
284 addmodifier(argv[++i], curout, binval, bincnt);
285 break;
286 case 'M': /* modifier file */
287 check(2,"s");
288 addmodfile(argv[++i], curout, binval, bincnt);
289 break;
290 default:
291 goto badopt;
292 }
293 }
294 /* override some option settings */
295 override_options();
296 /* initialize object types */
297 initotypes();
298 /* initialize urand */
299 if (rand_samp) {
300 srandom((long)time(0));
301 initurand(0);
302 } else {
303 srandom(0L);
304 initurand(2048);
305 }
306 /* set up signal handling */
307 sigdie(SIGINT, "Interrupt");
308 #ifdef SIGHUP
309 sigdie(SIGHUP, "Hangup");
310 #endif
311 sigdie(SIGTERM, "Terminate");
312 #ifdef SIGPIPE
313 sigdie(SIGPIPE, "Broken pipe");
314 #endif
315 #ifdef SIGALRM
316 sigdie(SIGALRM, "Alarm clock");
317 #endif
318 #ifdef SIGXCPU
319 sigdie(SIGXCPU, "CPU limit exceeded");
320 sigdie(SIGXFSZ, "File size exceeded");
321 #endif
322 #ifdef NICE
323 nice(NICE); /* lower priority */
324 #endif
325 /* get octree */
326 if (i == argc)
327 octname = NULL;
328 else if (i == argc-1)
329 octname = argv[i];
330 else
331 goto badopt;
332 if (octname == NULL)
333 error(USER, "missing octree argument");
334
335 readoct(octname, ~(IO_FILES|IO_INFO), &thescene, NULL);
336 nsceneobjs = nobjects;
337
338 marksources(); /* find and mark sources */
339
340 setambient(); /* initialize ambient calculation */
341
342 rcontrib(); /* trace ray contributions (loop) */
343
344 ambsync(); /* flush ambient file */
345
346 quit(0); /* exit clean */
347
348 badopt:
349 fprintf(stderr,
350 "Usage: %s [-n nprocs][-V][-r][-e expr][-f source][-o ospec][-b binv][-bn N] {-m mod | -M file} [rtrace options] octree\n",
351 progname);
352 sprintf(errmsg, "command line error at '%s'", argv[i]);
353 error(USER, errmsg);
354 return(1); /* pro forma return */
355
356 #undef check
357 #undef bool
358 }
359
360
361 void
362 wputs( /* warning output function */
363 char *s
364 )
365 {
366 int lasterrno = errno;
367 eputs(s);
368 errno = lasterrno;
369 }
370
371
372 void
373 eputs( /* put string to stderr */
374 char *s
375 )
376 {
377 static int midline = 0;
378
379 if (!*s)
380 return;
381 if (!midline++) {
382 fputs(progname, stderr);
383 fputs(": ", stderr);
384 }
385 fputs(s, stderr);
386 if (s[strlen(s)-1] == '\n') {
387 fflush(stderr);
388 midline = 0;
389 }
390 }