ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rpmain.c
Revision: 2.3
Committed: Thu Jun 5 19:29:34 2003 UTC (20 years, 10 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 2.2: +8 -14 lines
Log Message:
Macros for setting binary file mode. Replacing MSDOS by _WIN32.

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: rpmain.c,v 2.2 2003/02/25 02:47:23 greg Exp $";
3 #endif
4 /*
5 * rpmain.c - main for rpict batch rendering program
6 */
7
8 #include "copyright.h"
9
10 #include <sys/types.h>
11 #include <signal.h>
12
13 #include "platform.h"
14 #include "ray.h"
15 #include "source.h"
16 #include "ambient.h"
17 #include "random.h"
18 #include "paths.h"
19 #include "view.h"
20
21 /* persistent processes define */
22 #ifdef F_SETLKW
23 #define PERSIST 1 /* normal persist */
24 #define PARALLEL 2 /* parallel persist */
25 #define PCHILD 3 /* child of normal persist */
26 #endif
27
28 char *progname; /* argv[0] */
29
30 char *octname; /* octree name */
31
32 char *sigerr[NSIG]; /* signal error messages */
33
34 char *shm_boundary = NULL; /* boundary of shared memory */
35
36 char *errfile = NULL; /* error output file */
37
38 extern time_t time();
39 extern time_t tstart; /* start time */
40
41 extern int ralrm; /* seconds between reports */
42
43 extern VIEW ourview; /* viewing parameters */
44
45 extern int hresolu; /* horizontal resolution */
46 extern int vresolu; /* vertical resolution */
47 extern double pixaspect; /* pixel aspect ratio */
48
49 extern int psample; /* pixel sample size */
50 extern double maxdiff; /* max. sample difference */
51 extern double dstrpix; /* square pixel distribution */
52
53 extern double mblur; /* motion blur parameter */
54
55 void onsig();
56 void sigdie();
57 void printdefaults();
58
59
60 int
61 main(argc, argv)
62 int argc;
63 char *argv[];
64 {
65 #define check(ol,al) if (argv[i][ol] || \
66 badarg(argc-i-1,argv+i+1,al)) \
67 goto badopt
68 #define bool(olen,var) switch (argv[i][olen]) { \
69 case '\0': var = !var; break; \
70 case 'y': case 'Y': case 't': case 'T': \
71 case '+': case '1': var = 1; break; \
72 case 'n': case 'N': case 'f': case 'F': \
73 case '-': case '0': var = 0; break; \
74 default: goto badopt; }
75 char *err;
76 char *recover = NULL;
77 char *outfile = NULL;
78 char *zfile = NULL;
79 int loadflags = ~IO_FILES;
80 int seqstart = 0;
81 int persist = 0;
82 int duped1;
83 int rval;
84 int i;
85 /* record start time */
86 tstart = time((time_t *)NULL);
87 /* global program name */
88 progname = argv[0] = fixargv0(argv[0]);
89 /* option city */
90 for (i = 1; i < argc; i++) {
91 /* expand arguments */
92 while ((rval = expandarg(&argc, &argv, i)) > 0)
93 ;
94 if (rval < 0) {
95 sprintf(errmsg, "cannot expand '%s'", argv[i]);
96 error(SYSTEM, errmsg);
97 }
98 if (argv[i] == NULL || argv[i][0] != '-')
99 break; /* break from options */
100 if (!strcmp(argv[i], "-version")) {
101 puts(VersionID);
102 quit(0);
103 }
104 if (!strcmp(argv[i], "-defaults") ||
105 !strcmp(argv[i], "-help")) {
106 printdefaults();
107 quit(0);
108 }
109 rval = getrenderopt(argc-i, argv+i);
110 if (rval >= 0) {
111 i += rval;
112 continue;
113 }
114 rval = getviewopt(&ourview, argc-i, argv+i);
115 if (rval >= 0) {
116 i += rval;
117 continue;
118 }
119 /* rpict options */
120 switch (argv[i][1]) {
121 case 'v': /* view file */
122 if (argv[i][2] != 'f')
123 goto badopt;
124 check(3,"s");
125 rval = viewfile(argv[++i], &ourview, NULL);
126 if (rval < 0) {
127 sprintf(errmsg,
128 "cannot open view file \"%s\"",
129 argv[i]);
130 error(SYSTEM, errmsg);
131 } else if (rval == 0) {
132 sprintf(errmsg,
133 "bad view file \"%s\"",
134 argv[i]);
135 error(USER, errmsg);
136 }
137 break;
138 case 'p': /* pixel */
139 switch (argv[i][2]) {
140 case 's': /* sample */
141 check(3,"i");
142 psample = atoi(argv[++i]);
143 break;
144 case 't': /* threshold */
145 check(3,"f");
146 maxdiff = atof(argv[++i]);
147 break;
148 case 'j': /* jitter */
149 check(3,"f");
150 dstrpix = atof(argv[++i]);
151 break;
152 case 'a': /* aspect */
153 check(3,"f");
154 pixaspect = atof(argv[++i]);
155 break;
156 case 'm': /* motion */
157 check(3,"f");
158 mblur = atof(argv[++i]);
159 break;
160 default:
161 goto badopt;
162 }
163 break;
164 case 'x': /* x resolution */
165 check(2,"i");
166 hresolu = atoi(argv[++i]);
167 break;
168 case 'y': /* y resolution */
169 check(2,"i");
170 vresolu = atoi(argv[++i]);
171 break;
172 case 'S': /* slave index */
173 check(2,"i");
174 seqstart = atoi(argv[++i]);
175 break;
176 case 'o': /* output file */
177 check(2,"s");
178 outfile = argv[++i];
179 break;
180 case 'z': /* z file */
181 check(2,"s");
182 zfile = argv[++i];
183 break;
184 case 'r': /* recover file */
185 if (argv[i][2] == 'o') { /* +output */
186 check(3,"s");
187 outfile = argv[i+1];
188 } else
189 check(2,"s");
190 recover = argv[++i];
191 break;
192 case 't': /* timer */
193 check(2,"i");
194 ralrm = atoi(argv[++i]);
195 break;
196 #ifdef PERSIST
197 case 'P': /* persist file */
198 if (argv[i][2] == 'P') {
199 check(3,"s");
200 persist = PARALLEL;
201 } else {
202 check(2,"s");
203 persist = PERSIST;
204 }
205 persistfile(argv[++i]);
206 break;
207 #endif
208 case 'w': /* warnings */
209 rval = erract[WARNING].pf != NULL;
210 bool(2,rval);
211 if (rval) erract[WARNING].pf = wputs;
212 else erract[WARNING].pf = NULL;
213 break;
214 case 'e': /* error file */
215 check(2,"s");
216 errfile = argv[++i];
217 break;
218 default:
219 goto badopt;
220 }
221 }
222 err = setview(&ourview); /* set viewing parameters */
223 if (err != NULL)
224 error(USER, err);
225 /* initialize object types */
226 initotypes();
227 /* initialize urand */
228 initurand(2048);
229 /* set up signal handling */
230 sigdie(SIGINT, "Interrupt");
231 sigdie(SIGHUP, "Hangup");
232 sigdie(SIGTERM, "Terminate");
233 sigdie(SIGPIPE, "Broken pipe");
234 sigdie(SIGALRM, "Alarm clock");
235 #ifdef SIGXCPU
236 sigdie(SIGXCPU, "CPU limit exceeded");
237 sigdie(SIGXFSZ, "File size exceeded");
238 #endif
239 /* open error file */
240 if (errfile != NULL) {
241 if (freopen(errfile, "a", stderr) == NULL)
242 quit(2);
243 fprintf(stderr, "**************\n*** PID %5d: ",
244 getpid());
245 printargs(argc, argv, stderr);
246 putc('\n', stderr);
247 fflush(stderr);
248 }
249 #ifdef NICE
250 nice(NICE); /* lower priority */
251 #endif
252 /* get octree */
253 if (i == argc)
254 octname = NULL;
255 else if (i == argc-1)
256 octname = argv[i];
257 else
258 goto badopt;
259 if (seqstart > 0 && octname == NULL)
260 error(USER, "missing octree argument");
261 /* set up output */
262 #ifdef PERSIST
263 if (persist) {
264 if (recover != NULL)
265 error(USER, "persist option used with recover file");
266 if (seqstart <= 0)
267 error(USER, "persist option only for sequences");
268 if (outfile == NULL)
269 duped1 = dup(fileno(stdout)); /* don't lose our output */
270 openheader();
271 } else
272 #endif
273 if (outfile != NULL)
274 openheader();
275 #ifdef _WIN32
276 SET_FILE_BINARY(stdout);
277 if (octname == NULL)
278 SET_FILE_BINARY(stdin);
279 #endif
280 readoct(octname, loadflags, &thescene, NULL);
281 nsceneobjs = nobjects;
282
283 if (loadflags & IO_INFO) { /* print header */
284 printargs(i, argv, stdout);
285 printf("SOFTWARE= %s\n", VersionID);
286 fputnow(stdout);
287 }
288
289 marksources(); /* find and mark sources */
290
291 setambient(); /* initialize ambient calculation */
292
293 #ifdef PERSIST
294 if (persist) {
295 fflush(stdout);
296 if (outfile == NULL) { /* reconnect stdout */
297 dup2(duped1, fileno(stdout));
298 close(duped1);
299 }
300 if (persist == PARALLEL) { /* multiprocessing */
301 preload_objs(); /* preload scene */
302 shm_boundary = (char *)malloc(16);
303 strcpy(shm_boundary, "SHM_BOUNDARY");
304 while ((rval=fork()) == 0) { /* keep on forkin' */
305 pflock(1);
306 pfhold();
307 tstart = time((time_t *)NULL);
308 }
309 if (rval < 0)
310 error(SYSTEM, "cannot fork child for persist function");
311 pfdetach(); /* parent exits */
312 }
313 }
314 runagain:
315 if (persist)
316 if (outfile == NULL) /* if out to stdout */
317 dupheader(); /* send header */
318 else /* if out to file */
319 duped1 = dup(fileno(stdout)); /* hang onto pipe */
320 #endif
321 /* batch render picture(s) */
322 rpict(seqstart, outfile, zfile, recover);
323 /* flush ambient file */
324 ambsync();
325 #ifdef PERSIST
326 if (persist == PERSIST) { /* first run-through */
327 if ((rval=fork()) == 0) { /* child loops until killed */
328 pflock(1);
329 persist = PCHILD;
330 } else { /* original process exits */
331 if (rval < 0)
332 error(SYSTEM, "cannot fork child for persist function");
333 pfdetach(); /* parent exits */
334 }
335 }
336 if (persist == PCHILD) { /* wait for a signal then go again */
337 if (outfile != NULL)
338 close(duped1); /* release output handle */
339 pfhold();
340 tstart = time((time_t *)NULL); /* reinitialize */
341 raynum = nrays = 0;
342 goto runagain;
343 }
344 #endif
345 quit(0);
346
347 badopt:
348 sprintf(errmsg, "command line error at '%s'", argv[i]);
349 error(USER, errmsg);
350
351 #undef check
352 #undef bool
353 }
354
355
356 void
357 wputs(s) /* warning output function */
358 char *s;
359 {
360 int lasterrno = errno;
361 eputs(s);
362 errno = lasterrno;
363 }
364
365
366 void
367 eputs(s) /* put string to stderr */
368 register char *s;
369 {
370 static int midline = 0;
371
372 if (!*s)
373 return;
374 if (!midline++) {
375 fputs(progname, stderr);
376 fputs(": ", stderr);
377 }
378 fputs(s, stderr);
379 if (s[strlen(s)-1] == '\n') {
380 fflush(stderr);
381 midline = 0;
382 }
383 }
384
385
386 void
387 onsig(signo) /* fatal signal */
388 int signo;
389 {
390 static int gotsig = 0;
391
392 if (gotsig++) /* two signals and we're gone! */
393 _exit(signo);
394
395 alarm(15); /* allow 15 seconds to clean up */
396 signal(SIGALRM, SIG_DFL); /* make certain we do die */
397 eputs("signal - ");
398 eputs(sigerr[signo]);
399 eputs("\n");
400 quit(3);
401 }
402
403
404 void
405 sigdie(signo, msg) /* set fatal signal */
406 int signo;
407 char *msg;
408 {
409 if (signal(signo, onsig) == SIG_IGN)
410 signal(signo, SIG_IGN);
411 sigerr[signo] = msg;
412 }
413
414
415 void
416 printdefaults() /* print default values to stdout */
417 {
418 register char *cp;
419
420 printf("-vt%c\t\t\t\t# view type %s\n", ourview.type,
421 ourview.type==VT_PER ? "perspective" :
422 ourview.type==VT_PAR ? "parallel" :
423 ourview.type==VT_HEM ? "hemispherical" :
424 ourview.type==VT_ANG ? "angular" :
425 ourview.type==VT_CYL ? "cylindrical" :
426 "unknown");
427 printf("-vp %f %f %f\t# view point\n",
428 ourview.vp[0], ourview.vp[1], ourview.vp[2]);
429 printf("-vd %f %f %f\t# view direction\n",
430 ourview.vdir[0], ourview.vdir[1], ourview.vdir[2]);
431 printf("-vu %f %f %f\t# view up\n",
432 ourview.vup[0], ourview.vup[1], ourview.vup[2]);
433 printf("-vh %f\t\t\t# view horizontal size\n", ourview.horiz);
434 printf("-vv %f\t\t\t# view vertical size\n", ourview.vert);
435 printf("-vo %f\t\t\t# view fore clipping plane\n", ourview.vfore);
436 printf("-va %f\t\t\t# view aft clipping plane\n", ourview.vaft);
437 printf("-vs %f\t\t\t# view shift\n", ourview.hoff);
438 printf("-vl %f\t\t\t# view lift\n", ourview.voff);
439 printf("-x %-9d\t\t\t# x resolution\n", hresolu);
440 printf("-y %-9d\t\t\t# y resolution\n", vresolu);
441 printf("-pa %f\t\t\t# pixel aspect ratio\n", pixaspect);
442 printf("-pj %f\t\t\t# pixel jitter\n", dstrpix);
443 printf("-pm %f\t\t\t# pixel motion\n", mblur);
444 printf("-ps %-9d\t\t\t# pixel sample\n", psample);
445 printf("-pt %f\t\t\t# pixel threshold\n", maxdiff);
446 printf("-t %-9d\t\t\t# time between reports\n", ralrm);
447 printf(erract[WARNING].pf != NULL ?
448 "-w+\t\t\t\t# warning messages on\n" :
449 "-w-\t\t\t\t# warning messages off\n");
450 print_rdefaults();
451 }