ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/rholo.c
Revision: 3.9
Committed: Tue Nov 11 11:31:54 1997 UTC (26 years, 5 months ago) by gregl
Content type: text/plain
Branch: MAIN
Changes since 3.8: +4 -4 lines
Log Message:
made file length testing more efficient

File Contents

# Content
1 /* Copyright (c) 1997 Silicon Graphics, Inc. */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ SGI";
5 #endif
6
7 /*
8 * Radiance holodeck generation controller
9 */
10
11 #include "rholo.h"
12 #include "paths.h"
13 #include <sys/types.h>
14
15 /* the following must be consistent with rholo.h */
16 int NVARS = NRHVARS; /* total number of variables */
17
18 VARIABLE vv[] = RHVINIT; /* variable-value pairs */
19
20 char *progname; /* our program name */
21 char *hdkfile; /* holodeck file name */
22 char froot[MAXPATH]; /* root file name */
23
24 int nowarn = 0; /* turn warnings off? */
25
26 double expval = 1.; /* global exposure value */
27
28 int ncprocs = 0; /* desired number of compute processes */
29
30 char *outdev = NULL; /* output device name */
31
32 time_t starttime; /* time we got started */
33 time_t endtime; /* time we should end by */
34 time_t reporttime; /* time for next report */
35
36 long maxdisk; /* maximum file space (bytes) */
37
38 int rtargc = 1; /* rtrace command */
39 char *rtargv[128] = {"rtrace", NULL};
40
41 long nraysdone = 0L; /* number of rays done */
42 long npacksdone = 0L; /* number of packets done */
43
44 PACKET *freepacks; /* available packets */
45
46 extern time_t time();
47
48
49 main(argc, argv)
50 int argc;
51 char *argv[];
52 {
53 HDGRID hdg;
54 int i;
55 int force = 0;
56 /* mark start time */
57 starttime = time(NULL);
58 progname = argv[0]; /* get arguments */
59 for (i = 1; i < argc && argv[i][0] == '-'; i++)
60 switch (argv[i][1]) {
61 case 'w': /* turn off warnings */
62 nowarn++;
63 break;
64 case 'f': /* force overwrite */
65 force++;
66 break;
67 case 'n': /* compute processes */
68 if (i >= argc-2)
69 goto userr;
70 ncprocs = atoi(argv[++i]);
71 break;
72 case 'o': /* output display */
73 if (i >= argc-2)
74 goto userr;
75 outdev = argv[++i];
76 break;
77 default:
78 goto userr;
79 }
80 /* do we have a job? */
81 if (outdev == NULL && ncprocs <= 0)
82 goto userr;
83 /* get root file name */
84 rootname(froot, hdkfile=argv[i++]);
85 /* load... */
86 if (i < argc) { /* variables */
87 loadvars(argv[i++]);
88 /* cmdline settings */
89 for ( ; i < argc; i++)
90 if (setvariable(argv[i], matchvar) < 0) {
91 sprintf(errmsg, "unknown variable: %s",
92 argv[i]);
93 error(USER, errmsg);
94 }
95 /* check settings */
96 checkvalues();
97 /* load RIF if any */
98 if (vdef(RIF))
99 getradfile(vval(RIF));
100 /* set defaults */
101 setdefaults(&hdg);
102 /* holodeck exists? */
103 if (!force && access(hdkfile, R_OK|W_OK) == 0)
104 error(USER,
105 "holodeck file exists -- use -f to overwrite");
106 /* create holodeck */
107 creatholo(&hdg);
108 } else { /* else load holodeck */
109 loadholo();
110 if (vdef(RIF)) /* load RIF if any */
111 getradfile(vval(RIF));
112 }
113 /* initialize */
114 initrholo();
115 /* run */
116 while (rholo())
117 ;
118 /* done */
119 quit(0);
120 userr:
121 fprintf(stderr,
122 "Usage: %s {-n nprocs|-o disp} [-w][-f] output.hdk [control.hif [VAR=val ..]]\n",
123 progname);
124 quit(1);
125 }
126
127
128 initrholo() /* get our holodeck running */
129 {
130 extern int global_packet();
131 register int i;
132
133 if (outdev != NULL) /* open output device */
134 disp_open(outdev);
135 else if (ncprocs > 0) /* else use global ray feed */
136 init_global();
137 /* record disk space limit */
138 if (!vdef(DISKSPACE))
139 maxdisk = 0;
140 else
141 maxdisk = 1024.*1024.*vflt(DISKSPACE);
142 /* record end time */
143 if (!vdef(TIME) || vflt(TIME) <= FTINY)
144 endtime = 0;
145 else
146 endtime = starttime + vflt(TIME)*3600.;
147 /* set up memory cache */
148 if (outdev == NULL)
149 hdcachesize = 0; /* manual flushing */
150 else if (vdef(CACHE))
151 hdcachesize = 1024.*1024.*vflt(CACHE);
152 /* open report file */
153 if (vdef(REPORT)) {
154 register char *s = sskip2(vval(REPORT), 1);
155 if (*s && freopen(s, "a", stderr) == NULL)
156 quit(2);
157 }
158 /* start rtrace */
159 if (ncprocs > 0) {
160 i = start_rtrace();
161 if (i < 1)
162 error(USER, "cannot start rtrace process");
163 if (vdef(REPORT)) { /* make first report */
164 printargs(rtargc, rtargv, stderr);
165 report(0);
166 }
167 /* allocate packets */
168 freepacks = (PACKET *)bmalloc(i*sizeof(PACKET));
169 if (freepacks == NULL)
170 goto memerr;
171 freepacks[--i].nr = 0;
172 freepacks[i].next = NULL;
173 if (!vbool(OBSTRUCTIONS)) {
174 freepacks[i].offset = (float *)bmalloc(
175 RPACKSIZ*sizeof(float)*(i+1) );
176 if (freepacks[i].offset == NULL)
177 goto memerr;
178 } else
179 freepacks[i].offset = NULL;
180 while (i--) {
181 freepacks[i].nr = 0;
182 freepacks[i].offset = freepacks[i+1].offset == NULL ?
183 NULL : freepacks[i+1].offset+RPACKSIZ ;
184 freepacks[i].next = &freepacks[i+1];
185 }
186 }
187 return;
188 memerr:
189 error(SYSTEM, "out of memory in initrholo");
190 }
191
192
193 rholo() /* holodeck main loop */
194 {
195 static int idle = 1;
196 PACKET *pl = NULL, *plend;
197 register PACKET *p;
198 time_t t;
199 long l;
200
201 if (outdev != NULL) /* check display */
202 if (!disp_check(idle))
203 return(0);
204 /* display only? */
205 if (ncprocs <= 0)
206 return(1);
207 /* check file size */
208 if (maxdisk > 0 && hdfilen(hdlist[0]->fd) >= maxdisk) {
209 error(WARNING, "file limit exceeded");
210 return(0);
211 }
212 /* check time */
213 if (endtime > 0 || reporttime > 0)
214 t = time(NULL);
215 if (endtime > 0 && t >= endtime) {
216 error(WARNING, "time limit exceeded");
217 return(0);
218 }
219 if (reporttime > 0 && t >= reporttime)
220 report(t);
221 /* get packets to process */
222 while (freepacks != NULL) {
223 p = freepacks; freepacks = p->next; p->next = NULL;
224 if (!next_packet(p)) {
225 p->next = freepacks; freepacks = p;
226 break;
227 }
228 if (pl == NULL) pl = p;
229 else plend->next = p;
230 plend = p;
231 }
232 idle = pl == NULL && freepacks != NULL;
233 /* are we out of stuff to do? */
234 if (idle && outdev == NULL)
235 return(0);
236 /* else process packets */
237 done_packets(do_packets(pl));
238 return(1); /* and continue */
239 }
240
241
242 report(t) /* report progress so far */
243 time_t t;
244 {
245 if (t == 0)
246 t = time(NULL);
247 fprintf(stderr, "%s: %ld packets (%ld rays) done after %.2f hours\n",
248 progname, npacksdone, nraysdone, (t-starttime)/3600.);
249 fflush(stderr);
250 if (vdef(REPORT))
251 reporttime = t + (time_t)(vflt(REPORT)*60.+.5);
252 }
253
254
255 setdefaults(gp) /* set default values */
256 register HDGRID *gp;
257 {
258 extern char *atos();
259 register int i;
260 double len[3], maxlen, d;
261 char buf[64];
262
263 if (!vdef(SECTION)) {
264 sprintf(errmsg, "%s must be defined", vnam(SECTION));
265 error(USER, errmsg);
266 }
267 if (vdef(SECTION) > 1) {
268 sprintf(errmsg, "ignoring all but first %s", vnam(SECTION));
269 error(WARNING, errmsg);
270 }
271 if (sscanf(vval(SECTION),
272 "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf",
273 &gp->orig[0], &gp->orig[1], &gp->orig[2],
274 &gp->xv[0][0], &gp->xv[0][1], &gp->xv[0][2],
275 &gp->xv[1][0], &gp->xv[1][1], &gp->xv[1][2],
276 &gp->xv[2][0], &gp->xv[2][1], &gp->xv[2][2]) != 12)
277 badvalue(SECTION);
278 maxlen = 0.;
279 for (i = 0; i < 3; i++)
280 if ((len[i] = VLEN(gp->xv[i])) > maxlen)
281 maxlen = len[i];
282 if (!vdef(GRID)) {
283 sprintf(buf, "%.4f", maxlen/8.);
284 vval(GRID) = savqstr(buf);
285 vdef(GRID)++;
286 }
287 if ((d = vflt(GRID)) <= FTINY)
288 badvalue(GRID);
289 for (i = 0; i < 3; i++)
290 gp->grid[i] = len[i]/d + (1.-FTINY);
291 if (!vdef(EXPOSURE)) {
292 sprintf(errmsg, "%s must be defined", vnam(EXPOSURE));
293 error(USER, errmsg);
294 }
295 expval = vval(EXPOSURE)[0] == '-' || vval(EXPOSURE)[0] == '+' ?
296 pow(2., vflt(EXPOSURE)) : vflt(EXPOSURE);
297 if (!vdef(OCTREE)) {
298 if ((vval(OCTREE) = bmalloc(strlen(froot)+5)) == NULL)
299 error(SYSTEM, "out of memory");
300 sprintf(vval(OCTREE), "%s.oct", froot);
301 vdef(OCTREE)++;
302 }
303 if (!vdef(OBSTRUCTIONS)) {
304 vval(OBSTRUCTIONS) = "T";
305 vdef(OBSTRUCTIONS)++;
306 }
307 if (!vdef(OCCUPANCY)) {
308 vval(OCCUPANCY) = "U";
309 vdef(OCCUPANCY)++;
310 }
311 /* append rendering options */
312 if (vdef(RENDER))
313 rtargc += wordstring(rtargv+rtargc, vval(RENDER));
314 }
315
316
317 creatholo(gp) /* create a holodeck output file */
318 HDGRID *gp;
319 {
320 long endloc = 0;
321 FILE *fp;
322 /* open & truncate file */
323 if ((fp = fopen(hdkfile, "w+")) == NULL) {
324 sprintf(errmsg, "cannot open \"%s\" for writing", hdkfile);
325 error(SYSTEM, errmsg);
326 }
327 /* write information header */
328 newheader("RADIANCE", fp);
329 printvars(fp);
330 fputformat(HOLOFMT, fp);
331 fputc('\n', fp);
332 putw(HOLOMAGIC, fp); /* put magic number & terminus */
333 fwrite(&endloc, sizeof(long), 1, fp);
334 fflush(fp); /* flush buffer */
335 hdinit(fileno(fp), gp); /* allocate and initialize index */
336 /* we're dropping fp here.... */
337 }
338
339
340 headline(s) /* process information header line */
341 char *s;
342 {
343 extern char FMTSTR[];
344 register char *cp;
345 char fmt[32];
346
347 if (formatval(fmt, s)) {
348 if (strcmp(fmt, HOLOFMT)) {
349 sprintf(errmsg, "%s file \"%s\" has %s%s",
350 HOLOFMT, hdkfile, FMTSTR, fmt);
351 error(USER, errmsg);
352 }
353 return;
354 }
355 for (cp = s; *cp; cp++) /* take off any comments */
356 if (*cp == '#') {
357 *cp = '\0';
358 break;
359 }
360 setvariable(s, matchvar); /* don't flag errors */
361 }
362
363
364 loadholo() /* start loading a holodeck from fname */
365 {
366 FILE *fp;
367 long endloc;
368 /* open holodeck file */
369 if ((fp = fopen(hdkfile, ncprocs>0 ? "r+" : "r")) == NULL) {
370 sprintf(errmsg, "cannot open \"%s\" for %s", hdkfile,
371 ncprocs>0 ? "appending" : "reading");
372 error(SYSTEM, errmsg);
373 }
374 /* load variables from header */
375 getheader(fp, headline, NULL);
376 /* check magic number */
377 if (getw(fp) != HOLOMAGIC) {
378 sprintf(errmsg, "bad magic number in holodeck file \"%s\"",
379 hdkfile);
380 error(USER, errmsg);
381 }
382 fread(&endloc, sizeof(long), 1, fp);
383 if (endloc != 0)
384 error(WARNING, "ignoring multiple sections in holodeck file");
385 fseek(fp, 0L, 1); /* align system file pointer */
386 hdinit(fileno(fp), NULL); /* allocate and load index */
387 /* we're dropping fp here.... */
388 }
389
390
391 done_packets(pl) /* handle finished packets */
392 PACKET *pl;
393 {
394 static int nunflushed = 0;
395 register PACKET *p;
396
397 while (pl != NULL) {
398 p = pl; pl = p->next; p->next = NULL;
399 if (p->nr > 0) { /* add to holodeck */
400 bcopy((char *)p->ra,
401 (char *)hdnewrays(hdlist[p->hd],p->bi,p->nr),
402 p->nr*sizeof(RAYVAL));
403 if (outdev != NULL) /* display it */
404 disp_packet((PACKHEAD *)p);
405 else
406 nunflushed += p->nr;
407 nraysdone += p->nr;
408 npacksdone++;
409 }
410 p->nr = 0; /* push onto free list */
411 p->next = freepacks;
412 freepacks = p;
413 }
414 if (nunflushed >= 256*RPACKSIZ) {
415 hdflush(NULL); /* flush holodeck buffers */
416 nunflushed = 0;
417 }
418 }
419
420
421 getradfile(rfargs) /* run rad and get needed variables */
422 char *rfargs;
423 {
424 static short mvar[] = {OCTREE,EXPOSURE,-1};
425 static char tf1[] = TEMPLATE;
426 char tf2[64];
427 char combuf[256];
428 char *pippt;
429 register int i;
430 register char *cp;
431 /* create rad command */
432 mktemp(tf1);
433 sprintf(tf2, "%s.rif", tf1);
434 sprintf(combuf,
435 "rad -v 0 -s -e -w %s OPTFILE=%s | egrep '^[ \t]*(NOMATCH",
436 rfargs, tf1);
437 cp = combuf;
438 while (*cp){
439 if (*cp == '|') pippt = cp;
440 cp++;
441 } /* match unset variables */
442 for (i = 0; mvar[i] >= 0; i++)
443 if (!vdef(mvar[i])) {
444 *cp++ = '|';
445 strcpy(cp, vnam(mvar[i]));
446 while (*cp) cp++;
447 pippt = NULL;
448 }
449 if (pippt != NULL)
450 strcpy(pippt, "> /dev/null"); /* nothing to match */
451 else
452 sprintf(cp, ")[ \t]*=' > %s", tf2);
453 if (system(combuf)) {
454 error(SYSTEM, "cannot execute rad command");
455 unlink(tf2); /* clean up */
456 unlink(tf1);
457 quit(1);
458 }
459 if (pippt == NULL) {
460 loadvars(tf2); /* load variables */
461 unlink(tf2);
462 }
463 rtargc += wordfile(rtargv+rtargc, tf1); /* get rtrace options */
464 unlink(tf1); /* clean up */
465 }
466
467
468 rootname(rn, fn) /* remove tail from end of fn */
469 register char *rn, *fn;
470 {
471 char *tp, *dp;
472
473 for (tp = NULL, dp = rn; *rn = *fn++; rn++)
474 if (ISDIRSEP(*rn))
475 dp = rn;
476 else if (*rn == '.')
477 tp = rn;
478 if (tp != NULL && tp > dp)
479 *tp = '\0';
480 }
481
482
483 badvalue(vc) /* report bad variable value and exit */
484 int vc;
485 {
486 sprintf(errmsg, "bad value for variable '%s'", vnam(vc));
487 error(USER, errmsg);
488 }
489
490
491 eputs(s) /* put error message to stderr */
492 register char *s;
493 {
494 static int midline = 0;
495
496 if (!*s)
497 return;
498 if (!midline++) { /* prepend line with program name */
499 fputs(progname, stderr);
500 fputs(": ", stderr);
501 }
502 fputs(s, stderr);
503 if (s[strlen(s)-1] == '\n') {
504 fflush(stderr);
505 midline = 0;
506 }
507 }
508
509
510 wputs(s) /* put warning string to stderr */
511 char *s;
512 {
513 if (!nowarn)
514 eputs(s);
515 }
516
517
518 quit(ec) /* exit program gracefully */
519 int ec;
520 {
521 int status = 0;
522
523 if (outdev != NULL) /* close display */
524 disp_close();
525 if (hdlist[0] != NULL) { /* flush holodeck */
526 if (ncprocs > 0) {
527 done_packets(flush_queue());
528 status = end_rtrace(); /* close rtrace */
529 hdflush(NULL);
530 if (vdef(REPORT)) {
531 long fsiz, fuse;
532 report(0);
533 fsiz = hdfilen(hdlist[0]->fd);
534 fuse = hdfiluse(hdlist[0]->fd, 1);
535 fprintf(stderr,
536 "%s: %.1f Mbyte holodeck file, %.1f%% fragmentation\n",
537 hdkfile, fsiz/(1024.*1024.),
538 100.*(fsiz-fuse)/fsiz);
539 }
540 } else
541 hdflush(NULL);
542 }
543 exit(ec ? ec : status); /* exit */
544 }