ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/rholo.c
Revision: 3.10
Committed: Wed Nov 19 17:04:56 1997 UTC (26 years, 5 months ago) by gregl
Content type: text/plain
Branch: MAIN
Changes since 3.9: +14 -9 lines
Log Message:
fixed improper pointer alignment in loadholo()

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 int fd;
322 FILE *fp;
323 /* open & truncate file */
324 if ((fp = fopen(hdkfile, "w+")) == NULL) {
325 sprintf(errmsg, "cannot open \"%s\" for writing", hdkfile);
326 error(SYSTEM, errmsg);
327 }
328 /* write information header */
329 newheader("RADIANCE", fp);
330 printvars(fp);
331 fputformat(HOLOFMT, fp);
332 fputc('\n', fp);
333 putw(HOLOMAGIC, fp); /* put magic number & terminus */
334 fwrite(&endloc, sizeof(long), 1, fp);
335 fd = dup(fileno(fp));
336 fclose(fp); /* flush and close stdio stream */
337 hdinit(fd, gp); /* allocate and initialize index */
338 }
339
340
341 headline(s) /* process information header line */
342 char *s;
343 {
344 extern char FMTSTR[];
345 register char *cp;
346 char fmt[32];
347
348 if (formatval(fmt, s)) {
349 if (strcmp(fmt, HOLOFMT)) {
350 sprintf(errmsg, "%s file \"%s\" has %s%s",
351 HOLOFMT, hdkfile, FMTSTR, fmt);
352 error(USER, errmsg);
353 }
354 return;
355 }
356 for (cp = s; *cp; cp++) /* take off any comments */
357 if (*cp == '#') {
358 *cp = '\0';
359 break;
360 }
361 setvariable(s, matchvar); /* don't flag errors */
362 }
363
364
365 loadholo() /* start loading a holodeck from fname */
366 {
367 extern long ftell();
368 FILE *fp;
369 int fd;
370 long fpos;
371 /* open holodeck file */
372 if ((fp = fopen(hdkfile, ncprocs>0 ? "r+" : "r")) == NULL) {
373 sprintf(errmsg, "cannot open \"%s\" for %s", hdkfile,
374 ncprocs>0 ? "appending" : "reading");
375 error(SYSTEM, errmsg);
376 }
377 /* load variables from header */
378 getheader(fp, headline, NULL);
379 /* check magic number */
380 if (getw(fp) != HOLOMAGIC) {
381 sprintf(errmsg, "bad magic number in holodeck file \"%s\"",
382 hdkfile);
383 error(USER, errmsg);
384 }
385 fread(&fpos, sizeof(long), 1, fp);
386 if (fpos != 0)
387 error(WARNING, "ignoring multiple sections in holodeck file");
388 fpos = ftell(fp); /* get stdio position */
389 fd = dup(fileno(fp));
390 fclose(fp); /* done with stdio */
391 lseek(fd, fpos, 0); /* align system file pointer */
392 hdinit(fd, NULL); /* allocate and load index */
393 }
394
395
396 done_packets(pl) /* handle finished packets */
397 PACKET *pl;
398 {
399 static int nunflushed = 0;
400 register PACKET *p;
401
402 while (pl != NULL) {
403 p = pl; pl = p->next; p->next = NULL;
404 if (p->nr > 0) { /* add to holodeck */
405 bcopy((char *)p->ra,
406 (char *)hdnewrays(hdlist[p->hd],p->bi,p->nr),
407 p->nr*sizeof(RAYVAL));
408 if (outdev != NULL) /* display it */
409 disp_packet((PACKHEAD *)p);
410 else
411 nunflushed += p->nr;
412 nraysdone += p->nr;
413 npacksdone++;
414 }
415 p->nr = 0; /* push onto free list */
416 p->next = freepacks;
417 freepacks = p;
418 }
419 if (nunflushed >= 256*RPACKSIZ) {
420 hdflush(NULL); /* flush holodeck buffers */
421 nunflushed = 0;
422 }
423 }
424
425
426 getradfile(rfargs) /* run rad and get needed variables */
427 char *rfargs;
428 {
429 static short mvar[] = {OCTREE,EXPOSURE,-1};
430 static char tf1[] = TEMPLATE;
431 char tf2[64];
432 char combuf[256];
433 char *pippt;
434 register int i;
435 register char *cp;
436 /* create rad command */
437 mktemp(tf1);
438 sprintf(tf2, "%s.rif", tf1);
439 sprintf(combuf,
440 "rad -v 0 -s -e -w %s OPTFILE=%s | egrep '^[ \t]*(NOMATCH",
441 rfargs, tf1);
442 cp = combuf;
443 while (*cp){
444 if (*cp == '|') pippt = cp;
445 cp++;
446 } /* match unset variables */
447 for (i = 0; mvar[i] >= 0; i++)
448 if (!vdef(mvar[i])) {
449 *cp++ = '|';
450 strcpy(cp, vnam(mvar[i]));
451 while (*cp) cp++;
452 pippt = NULL;
453 }
454 if (pippt != NULL)
455 strcpy(pippt, "> /dev/null"); /* nothing to match */
456 else
457 sprintf(cp, ")[ \t]*=' > %s", tf2);
458 if (system(combuf)) {
459 error(SYSTEM, "cannot execute rad command");
460 unlink(tf2); /* clean up */
461 unlink(tf1);
462 quit(1);
463 }
464 if (pippt == NULL) {
465 loadvars(tf2); /* load variables */
466 unlink(tf2);
467 }
468 rtargc += wordfile(rtargv+rtargc, tf1); /* get rtrace options */
469 unlink(tf1); /* clean up */
470 }
471
472
473 rootname(rn, fn) /* remove tail from end of fn */
474 register char *rn, *fn;
475 {
476 char *tp, *dp;
477
478 for (tp = NULL, dp = rn; *rn = *fn++; rn++)
479 if (ISDIRSEP(*rn))
480 dp = rn;
481 else if (*rn == '.')
482 tp = rn;
483 if (tp != NULL && tp > dp)
484 *tp = '\0';
485 }
486
487
488 badvalue(vc) /* report bad variable value and exit */
489 int vc;
490 {
491 sprintf(errmsg, "bad value for variable '%s'", vnam(vc));
492 error(USER, errmsg);
493 }
494
495
496 eputs(s) /* put error message to stderr */
497 register char *s;
498 {
499 static int midline = 0;
500
501 if (!*s)
502 return;
503 if (!midline++) { /* prepend line with program name */
504 fputs(progname, stderr);
505 fputs(": ", stderr);
506 }
507 fputs(s, stderr);
508 if (s[strlen(s)-1] == '\n') {
509 fflush(stderr);
510 midline = 0;
511 }
512 }
513
514
515 wputs(s) /* put warning string to stderr */
516 char *s;
517 {
518 if (!nowarn)
519 eputs(s);
520 }
521
522
523 quit(ec) /* exit program gracefully */
524 int ec;
525 {
526 int status = 0;
527
528 if (outdev != NULL) /* close display */
529 disp_close();
530 if (hdlist[0] != NULL) { /* flush holodeck */
531 if (ncprocs > 0) {
532 done_packets(flush_queue());
533 status = end_rtrace(); /* close rtrace */
534 hdflush(NULL);
535 if (vdef(REPORT)) {
536 long fsiz, fuse;
537 report(0);
538 fsiz = hdfilen(hdlist[0]->fd);
539 fuse = hdfiluse(hdlist[0]->fd, 1);
540 fprintf(stderr,
541 "%s: %.1f Mbyte holodeck file, %.1f%% fragmentation\n",
542 hdkfile, fsiz/(1024.*1024.),
543 100.*(fsiz-fuse)/fsiz);
544 }
545 } else
546 hdflush(NULL);
547 }
548 exit(ec ? ec : status); /* exit */
549 }