ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rtrace.c
Revision: 2.57
Committed: Sat Dec 12 19:01:00 2009 UTC (14 years, 4 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.56: +40 -77 lines
Log Message:
Added -n option to rtrace and moved quit() funciton out of raypcalls

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: rtrace.c,v 2.56 2009/07/17 06:21:29 greg Exp $";
3 #endif
4 /*
5 * rtrace.c - program and variables for individual ray tracing.
6 */
7
8 #include "copyright.h"
9
10 /*
11 * Input is in the form:
12 *
13 * xorg yorg zorg xdir ydir zdir
14 *
15 * The direction need not be normalized. Output is flexible.
16 * If the direction vector is (0,0,0), then the output is flushed.
17 * All values default to ascii representation of real
18 * numbers. Binary representations can be selected
19 * with '-ff' for float or '-fd' for double. By default,
20 * radiance is computed. The '-i' or '-I' options indicate that
21 * irradiance values are desired.
22 */
23
24 #include <time.h>
25
26 #include "platform.h"
27 #include "ray.h"
28 #include "ambient.h"
29 #include "source.h"
30 #include "otypes.h"
31 #include "resolu.h"
32 #include "random.h"
33
34 extern int inform; /* input format */
35 extern int outform; /* output format */
36 extern char *outvals; /* output values */
37
38 extern int imm_irrad; /* compute immediate irradiance? */
39 extern int lim_dist; /* limit distance? */
40
41 extern char *tralist[]; /* list of modifers to trace (or no) */
42 extern int traincl; /* include == 1, exclude == 0 */
43
44 extern int hresolu; /* horizontal resolution */
45 extern int vresolu; /* vertical resolution */
46
47 static int castonly = 0;
48
49 #ifndef MAXTSET
50 #define MAXTSET 8191 /* maximum number in trace set */
51 #endif
52 OBJECT traset[MAXTSET+1]={0}; /* trace include/exclude set */
53
54 static RAY thisray; /* for our convenience */
55
56 typedef void putf_t(double v);
57 static putf_t puta, putd, putf;
58
59 typedef void oputf_t(RAY *r);
60 static oputf_t oputo, oputd, oputv, oputV, oputl, oputL, oputc, oputp,
61 oputn, oputN, oputs, oputw, oputW, oputm, oputM, oputtilde;
62
63 static void setoutput(char *vs);
64 extern void tranotify(OBJECT obj);
65 static void bogusray(void);
66 static void rad(FVECT org, FVECT dir, double dmax);
67 static void irrad(FVECT org, FVECT dir);
68 static int printvals(RAY *r);
69 static int getvec(FVECT vec, int fmt, FILE *fp);
70 static void tabin(RAY *r);
71 static void ourtrace(RAY *r);
72
73 static oputf_t *ray_out[16], *every_out[16];
74 static putf_t *putreal;
75
76
77 void
78 quit( /* quit program */
79 int code
80 )
81 {
82 if (ray_pnprocs > 0) /* close children if any */
83 ray_pclose(0);
84 #ifndef NON_POSIX
85 headclean(); /* delete header file */
86 pfclean(); /* clean up persist files */
87 #endif
88 exit(code);
89 }
90
91
92 char *
93 formstr( /* return format identifier */
94 int f
95 )
96 {
97 switch (f) {
98 case 'a': return("ascii");
99 case 'f': return("float");
100 case 'd': return("double");
101 case 'c': return(COLRFMT);
102 }
103 return("unknown");
104 }
105
106
107 extern void
108 rtrace( /* trace rays from file */
109 char *fname
110 )
111 {
112 unsigned long vcount = (hresolu > 1) ? (unsigned long)hresolu*vresolu
113 : vresolu;
114 long nextflush = hresolu;
115 FILE *fp;
116 double d;
117 FVECT orig, direc;
118 /* set up input */
119 if (fname == NULL)
120 fp = stdin;
121 else if ((fp = fopen(fname, "r")) == NULL) {
122 sprintf(errmsg, "cannot open input file \"%s\"", fname);
123 error(SYSTEM, errmsg);
124 }
125 if (inform != 'a')
126 SET_FILE_BINARY(fp);
127 /* set up output */
128 setoutput(outvals);
129 switch (outform) {
130 case 'a': putreal = puta; break;
131 case 'f': putreal = putf; break;
132 case 'd': putreal = putd; break;
133 case 'c':
134 if (strcmp(outvals, "v"))
135 error(USER, "color format with value output only");
136 break;
137 default:
138 error(CONSISTENCY, "botched output format");
139 }
140 ray_fifo_out = printvals;
141 if (hresolu > 0) {
142 if (vresolu > 0)
143 fprtresolu(hresolu, vresolu, stdout);
144 fflush(stdout);
145 }
146 /* process file */
147 while (getvec(orig, inform, fp) == 0 &&
148 getvec(direc, inform, fp) == 0) {
149
150 d = normalize(direc);
151 if (d == 0.0) { /* zero ==> flush */
152 if (ray_pnprocs > 1 && ray_fifo_flush() < 0)
153 error(USER, "lost children");
154 bogusray();
155 if (--nextflush <= 0 || !vcount) {
156 fflush(stdout);
157 nextflush = hresolu;
158 }
159 } else { /* compute and print */
160 if (imm_irrad)
161 irrad(orig, direc);
162 else
163 rad(orig, direc, lim_dist ? d : 0.0);
164 /* flush if time */
165 if (!--nextflush) {
166 if (ray_pnprocs > 1 && ray_fifo_flush() < 0)
167 error(USER, "lost children");
168 fflush(stdout);
169 nextflush = hresolu;
170 }
171 }
172 if (ferror(stdout))
173 error(SYSTEM, "write error");
174 if (vcount && !--vcount) /* check for end */
175 break;
176 }
177 if (ray_pnprocs > 1 && ray_fifo_flush() < 0)
178 error(USER, "unable to complete processing");
179 if (fflush(stdout) < 0)
180 error(SYSTEM, "write error");
181 if (vcount)
182 error(USER, "unexpected EOF on input");
183 if (fname != NULL)
184 fclose(fp);
185 }
186
187
188 static void
189 trace_sources(void) /* trace rays to light sources, also */
190 {
191 int sn;
192
193 for (sn = 0; sn < nsources; sn++)
194 source[sn].sflags |= SFOLLOW;
195 }
196
197
198 static void
199 setoutput( /* set up output tables */
200 char *vs
201 )
202 {
203 oputf_t **table = ray_out;
204
205 castonly = 1;
206 while (*vs)
207 switch (*vs++) {
208 case 'T': /* trace sources */
209 if (!*vs) break;
210 trace_sources();
211 /* fall through */
212 case 't': /* trace */
213 if (!*vs) break;
214 *table = NULL;
215 table = every_out;
216 trace = ourtrace;
217 castonly = 0;
218 break;
219 case 'o': /* origin */
220 *table++ = oputo;
221 break;
222 case 'd': /* direction */
223 *table++ = oputd;
224 break;
225 case 'v': /* value */
226 *table++ = oputv;
227 castonly = 0;
228 break;
229 case 'V': /* contribution */
230 *table++ = oputV;
231 if (ambounce > 0 && (ambacc > FTINY || ambssamp > 0))
232 error(WARNING,
233 "-otV accuracy depends on -aa 0 -as 0");
234 break;
235 case 'l': /* effective distance */
236 *table++ = oputl;
237 castonly = 0;
238 break;
239 case 'c': /* local coordinates */
240 *table++ = oputc;
241 break;
242 case 'L': /* single ray length */
243 *table++ = oputL;
244 break;
245 case 'p': /* point */
246 *table++ = oputp;
247 break;
248 case 'n': /* perturbed normal */
249 *table++ = oputn;
250 castonly = 0;
251 break;
252 case 'N': /* unperturbed normal */
253 *table++ = oputN;
254 break;
255 case 's': /* surface */
256 *table++ = oputs;
257 break;
258 case 'w': /* weight */
259 *table++ = oputw;
260 break;
261 case 'W': /* coefficient */
262 *table++ = oputW;
263 if (ambounce > 0 && (ambacc > FTINY || ambssamp > 0))
264 error(WARNING,
265 "-otW accuracy depends on -aa 0 -as 0");
266 break;
267 case 'm': /* modifier */
268 *table++ = oputm;
269 break;
270 case 'M': /* material */
271 *table++ = oputM;
272 break;
273 case '~': /* tilde */
274 *table++ = oputtilde;
275 break;
276 }
277 *table = NULL;
278 }
279
280
281 static void
282 bogusray(void) /* print out empty record */
283 {
284 thisray.rorg[0] = thisray.rorg[1] = thisray.rorg[2] =
285 thisray.rdir[0] = thisray.rdir[1] = thisray.rdir[2] = 0.0;
286 thisray.rmax = 0.0;
287 rayorigin(&thisray, PRIMARY, NULL, NULL);
288 printvals(&thisray);
289 }
290
291
292 static void
293 rad( /* compute and print ray value(s) */
294 FVECT org,
295 FVECT dir,
296 double dmax
297 )
298 {
299 VCOPY(thisray.rorg, org);
300 VCOPY(thisray.rdir, dir);
301 thisray.rmax = dmax;
302 if (ray_pnprocs > 1) {
303 if (ray_fifo_in(&thisray) < 0)
304 error(USER, "lost children");
305 return;
306 }
307 rayorigin(&thisray, PRIMARY, NULL, NULL);
308 if (castonly) {
309 if (!localhit(&thisray, &thescene)) {
310 if (thisray.ro == &Aftplane) { /* clipped */
311 thisray.ro = NULL;
312 thisray.rot = FHUGE;
313 } else
314 sourcehit(&thisray);
315 }
316 } else
317 ray_trace(&thisray);
318 printvals(&thisray);
319 }
320
321
322 static void
323 irrad( /* compute immediate irradiance value */
324 FVECT org,
325 FVECT dir
326 )
327 {
328 VSUM(thisray.rorg, org, dir, 1.1e-4);
329 thisray.rdir[0] = -dir[0];
330 thisray.rdir[1] = -dir[1];
331 thisray.rdir[2] = -dir[2];
332 thisray.rmax = 0.0;
333 rayorigin(&thisray, PRIMARY, NULL, NULL);
334 /* pretend we hit surface */
335 thisray.rot = 1e-5;
336 thisray.rod = 1.0;
337 VCOPY(thisray.ron, dir);
338 VSUM(thisray.rop, org, dir, 1e-4);
339 /* compute and print */
340 (*ofun[Lamb.otype].funp)(&Lamb, &thisray);
341 printvals(&thisray);
342 }
343
344
345 static int
346 printvals( /* print requested ray values */
347 RAY *r
348 )
349 {
350 oputf_t **tp;
351
352 if (ray_out[0] == NULL)
353 return(0);
354 for (tp = ray_out; *tp != NULL; tp++)
355 (**tp)(r);
356 if (outform == 'a')
357 putchar('\n');
358 return(1);
359 }
360
361
362 static int
363 getvec( /* get a vector from fp */
364 FVECT vec,
365 int fmt,
366 FILE *fp
367 )
368 {
369 static float vf[3];
370 static double vd[3];
371 char buf[32];
372 int i;
373
374 switch (fmt) {
375 case 'a': /* ascii */
376 for (i = 0; i < 3; i++) {
377 if (fgetword(buf, sizeof(buf), fp) == NULL ||
378 !isflt(buf))
379 return(-1);
380 vec[i] = atof(buf);
381 }
382 break;
383 case 'f': /* binary float */
384 if (fread((char *)vf, sizeof(float), 3, fp) != 3)
385 return(-1);
386 vec[0] = vf[0]; vec[1] = vf[1]; vec[2] = vf[2];
387 break;
388 case 'd': /* binary double */
389 if (fread((char *)vd, sizeof(double), 3, fp) != 3)
390 return(-1);
391 vec[0] = vd[0]; vec[1] = vd[1]; vec[2] = vd[2];
392 break;
393 default:
394 error(CONSISTENCY, "botched input format");
395 }
396 return(0);
397 }
398
399
400 void
401 tranotify( /* record new modifier */
402 OBJECT obj
403 )
404 {
405 static int hitlimit = 0;
406 OBJREC *o = objptr(obj);
407 char **tralp;
408
409 if (obj == OVOID) { /* starting over */
410 traset[0] = 0;
411 hitlimit = 0;
412 return;
413 }
414 if (hitlimit || !ismodifier(o->otype))
415 return;
416 for (tralp = tralist; *tralp != NULL; tralp++)
417 if (!strcmp(o->oname, *tralp)) {
418 if (traset[0] >= MAXTSET) {
419 error(WARNING, "too many modifiers in trace list");
420 hitlimit++;
421 return; /* should this be fatal? */
422 }
423 insertelem(traset, obj);
424 return;
425 }
426 }
427
428
429 static void
430 ourtrace( /* print ray values */
431 RAY *r
432 )
433 {
434 oputf_t **tp;
435
436 if (every_out[0] == NULL)
437 return;
438 if (r->ro == NULL) {
439 if (traincl == 1)
440 return;
441 } else if (traincl != -1 && traincl != inset(traset, r->ro->omod))
442 return;
443 tabin(r);
444 for (tp = every_out; *tp != NULL; tp++)
445 (**tp)(r);
446 if (outform == 'a')
447 putchar('\n');
448 }
449
450
451 static void
452 tabin( /* tab in appropriate amount */
453 RAY *r
454 )
455 {
456 const RAY *rp;
457
458 for (rp = r->parent; rp != NULL; rp = rp->parent)
459 putchar('\t');
460 }
461
462
463 static void
464 oputo( /* print origin */
465 RAY *r
466 )
467 {
468 (*putreal)(r->rorg[0]);
469 (*putreal)(r->rorg[1]);
470 (*putreal)(r->rorg[2]);
471 }
472
473
474 static void
475 oputd( /* print direction */
476 RAY *r
477 )
478 {
479 (*putreal)(r->rdir[0]);
480 (*putreal)(r->rdir[1]);
481 (*putreal)(r->rdir[2]);
482 }
483
484
485 static void
486 oputv( /* print value */
487 RAY *r
488 )
489 {
490 if (outform == 'c') {
491 COLR cout;
492 setcolr(cout, colval(r->rcol,RED),
493 colval(r->rcol,GRN),
494 colval(r->rcol,BLU));
495 fwrite((char *)cout, sizeof(cout), 1, stdout);
496 return;
497 }
498 (*putreal)(colval(r->rcol,RED));
499 (*putreal)(colval(r->rcol,GRN));
500 (*putreal)(colval(r->rcol,BLU));
501 }
502
503
504 static void
505 oputV( /* print value contribution */
506 RAY *r
507 )
508 {
509 double contr[3];
510
511 raycontrib(contr, r, PRIMARY);
512 multcolor(contr, r->rcol);
513 (*putreal)(contr[RED]);
514 (*putreal)(contr[GRN]);
515 (*putreal)(contr[BLU]);
516 }
517
518
519 static void
520 oputl( /* print effective distance */
521 RAY *r
522 )
523 {
524 (*putreal)(r->rt);
525 }
526
527
528 static void
529 oputL( /* print single ray length */
530 RAY *r
531 )
532 {
533 (*putreal)(r->rot);
534 }
535
536
537 static void
538 oputc( /* print local coordinates */
539 RAY *r
540 )
541 {
542 (*putreal)(r->uv[0]);
543 (*putreal)(r->uv[1]);
544 }
545
546
547 static void
548 oputp( /* print point */
549 RAY *r
550 )
551 {
552 if (r->rot < FHUGE) {
553 (*putreal)(r->rop[0]);
554 (*putreal)(r->rop[1]);
555 (*putreal)(r->rop[2]);
556 } else {
557 (*putreal)(0.0);
558 (*putreal)(0.0);
559 (*putreal)(0.0);
560 }
561 }
562
563
564 static void
565 oputN( /* print unperturbed normal */
566 RAY *r
567 )
568 {
569 if (r->rot < FHUGE) {
570 (*putreal)(r->ron[0]);
571 (*putreal)(r->ron[1]);
572 (*putreal)(r->ron[2]);
573 } else {
574 (*putreal)(0.0);
575 (*putreal)(0.0);
576 (*putreal)(0.0);
577 }
578 }
579
580
581 static void
582 oputn( /* print perturbed normal */
583 RAY *r
584 )
585 {
586 FVECT pnorm;
587
588 if (r->rot >= FHUGE) {
589 (*putreal)(0.0);
590 (*putreal)(0.0);
591 (*putreal)(0.0);
592 return;
593 }
594 raynormal(pnorm, r);
595 (*putreal)(pnorm[0]);
596 (*putreal)(pnorm[1]);
597 (*putreal)(pnorm[2]);
598 }
599
600
601 static void
602 oputs( /* print name */
603 RAY *r
604 )
605 {
606 if (r->ro != NULL)
607 fputs(r->ro->oname, stdout);
608 else
609 putchar('*');
610 putchar('\t');
611 }
612
613
614 static void
615 oputw( /* print weight */
616 RAY *r
617 )
618 {
619 (*putreal)(r->rweight);
620 }
621
622
623 static void
624 oputW( /* print coefficient */
625 RAY *r
626 )
627 {
628 double contr[3];
629
630 raycontrib(contr, r, PRIMARY);
631 (*putreal)(contr[RED]);
632 (*putreal)(contr[GRN]);
633 (*putreal)(contr[BLU]);
634 }
635
636
637 static void
638 oputm( /* print modifier */
639 RAY *r
640 )
641 {
642 if (r->ro != NULL)
643 if (r->ro->omod != OVOID)
644 fputs(objptr(r->ro->omod)->oname, stdout);
645 else
646 fputs(VOIDID, stdout);
647 else
648 putchar('*');
649 putchar('\t');
650 }
651
652
653 static void
654 oputM( /* print material */
655 RAY *r
656 )
657 {
658 OBJREC *mat;
659
660 if (r->ro != NULL) {
661 if ((mat = findmaterial(r->ro)) != NULL)
662 fputs(mat->oname, stdout);
663 else
664 fputs(VOIDID, stdout);
665 } else
666 putchar('*');
667 putchar('\t');
668 }
669
670
671 static void
672 oputtilde( /* output tilde (spacer) */
673 RAY *r
674 )
675 {
676 fputs("~\t", stdout);
677 }
678
679
680 static void
681 puta( /* print ascii value */
682 double v
683 )
684 {
685 printf("%e\t", v);
686 }
687
688
689 static void
690 putd(v) /* print binary double */
691 double v;
692 {
693 fwrite((char *)&v, sizeof(v), 1, stdout);
694 }
695
696
697 static void
698 putf(v) /* print binary float */
699 double v;
700 {
701 float f = v;
702
703 fwrite((char *)&f, sizeof(f), 1, stdout);
704 }