ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rv2.c
Revision: 2.40
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.39: +5 -8 lines
Log Message:
Macros for setting binary file mode. Replacing MSDOS by _WIN32.

File Contents

# User Rev Content
1 greg 1.1 #ifndef lint
2 schorsch 2.40 static const char RCSid[] = "$Id: rv2.c,v 2.39 2003/02/25 02:47:23 greg Exp $";
3 greg 1.1 #endif
4     /*
5     * rv2.c - command routines used in tracing a view.
6     *
7 greg 2.38 * External symbols declared in rpaint.h
8     */
9    
10 schorsch 2.40 #include <ctype.h>
11    
12 greg 2.39 #include "copyright.h"
13 greg 1.1
14 schorsch 2.40 #include "platform.h"
15 greg 1.1 #include "ray.h"
16     #include "otypes.h"
17     #include "rpaint.h"
18    
19 greg 2.38 extern int psample; /* pixel sample size */
20     extern double maxdiff; /* max. sample difference */
21 greg 1.1
22 greg 2.4 #define CTRL(c) ((c)-'@')
23 greg 1.1
24 greg 2.6 #ifdef SMLFLT
25     #define sscanvec(s,v) (sscanf(s,"%f %f %f",v,v+1,v+2)==3)
26     #else
27     #define sscanvec(s,v) (sscanf(s,"%lf %lf %lf",v,v+1,v+2)==3)
28     #endif
29    
30 greg 2.20 extern char rifname[128]; /* rad input file name */
31 greg 2.18
32 greg 1.1 extern char *progname;
33 greg 1.29 extern char *octname;
34 greg 1.1
35    
36 greg 2.38 void
37 greg 1.1 getframe(s) /* get a new frame */
38     char *s;
39     {
40 greg 1.12 if (getrect(s, &pframe) < 0)
41 greg 1.1 return;
42     pdepth = 0;
43     }
44    
45    
46 greg 2.38 void
47 greg 1.12 getrepaint(s) /* get area and repaint */
48     char *s;
49     {
50     RECT box;
51    
52     if (getrect(s, &box) < 0)
53     return;
54 greg 1.14 paintrect(&ptrunk, 0, 0, hresolu, vresolu, &box);
55 greg 1.12 }
56    
57    
58 greg 2.38 void
59 greg 1.1 getview(s) /* get/show view parameters */
60     char *s;
61     {
62     FILE *fp;
63     char buf[128];
64 greg 1.10 char *fname;
65 greg 1.3 int change = 0;
66 greg 1.1 VIEW nv;
67    
68 greg 2.9 while (isspace(*s))
69     s++;
70     if (*s == '-') { /* command line parameters */
71     copystruct(&nv, &ourview);
72     if (sscanview(&nv, s))
73     newview(&nv);
74     else
75     error(COMMAND, "bad view option(s)");
76     return;
77     }
78 greg 1.1 if (sscanf(s, "%s", buf) == 1) { /* write parameters to a file */
79 greg 1.10 if ((fname = getpath(buf, NULL, 0)) == NULL ||
80 greg 1.1 (fp = fopen(fname, "a")) == NULL) {
81     sprintf(errmsg, "cannot open \"%s\"", buf);
82     error(COMMAND, errmsg);
83     return;
84     }
85 greg 1.2 fputs(progname, fp);
86 greg 1.1 fprintview(&ourview, fp);
87 greg 1.19 fputs(sskip(s), fp);
88 greg 2.18 putc('\n', fp);
89 greg 1.1 fclose(fp);
90     return;
91     }
92     sprintf(buf, "view type (%c): ", ourview.type);
93     (*dev->comout)(buf);
94 greg 1.18 (*dev->comin)(buf, NULL);
95 greg 2.4 if (buf[0] == CTRL('C')) return;
96 greg 1.3 if (buf[0] && buf[0] != ourview.type) {
97 greg 1.1 nv.type = buf[0];
98 greg 1.3 change++;
99     } else
100 greg 1.1 nv.type = ourview.type;
101     sprintf(buf, "view point (%.6g %.6g %.6g): ",
102     ourview.vp[0], ourview.vp[1], ourview.vp[2]);
103     (*dev->comout)(buf);
104 greg 1.18 (*dev->comin)(buf, NULL);
105 greg 2.4 if (buf[0] == CTRL('C')) return;
106 greg 2.6 if (sscanvec(buf, nv.vp))
107 greg 1.3 change++;
108     else
109 greg 1.1 VCOPY(nv.vp, ourview.vp);
110     sprintf(buf, "view direction (%.6g %.6g %.6g): ",
111     ourview.vdir[0], ourview.vdir[1], ourview.vdir[2]);
112     (*dev->comout)(buf);
113 greg 1.18 (*dev->comin)(buf, NULL);
114 greg 2.4 if (buf[0] == CTRL('C')) return;
115 greg 2.6 if (sscanvec(buf, nv.vdir))
116 greg 1.3 change++;
117     else
118 greg 1.1 VCOPY(nv.vdir, ourview.vdir);
119     sprintf(buf, "view up (%.6g %.6g %.6g): ",
120     ourview.vup[0], ourview.vup[1], ourview.vup[2]);
121     (*dev->comout)(buf);
122 greg 1.18 (*dev->comin)(buf, NULL);
123 greg 2.4 if (buf[0] == CTRL('C')) return;
124 greg 2.6 if (sscanvec(buf, nv.vup))
125 greg 1.3 change++;
126     else
127 greg 1.1 VCOPY(nv.vup, ourview.vup);
128     sprintf(buf, "view horiz and vert size (%.6g %.6g): ",
129     ourview.horiz, ourview.vert);
130     (*dev->comout)(buf);
131 greg 1.18 (*dev->comin)(buf, NULL);
132 greg 2.4 if (buf[0] == CTRL('C')) return;
133 greg 1.3 if (sscanf(buf, "%lf %lf", &nv.horiz, &nv.vert) == 2)
134     change++;
135     else {
136 greg 1.1 nv.horiz = ourview.horiz; nv.vert = ourview.vert;
137     }
138 greg 2.26 sprintf(buf, "fore and aft clipping plane (%.6g %.6g): ",
139     ourview.vfore, ourview.vaft);
140     (*dev->comout)(buf);
141     (*dev->comin)(buf, NULL);
142     if (buf[0] == CTRL('C')) return;
143     if (sscanf(buf, "%lf %lf", &nv.vfore, &nv.vaft) == 2)
144     change++;
145     else {
146     nv.vfore = ourview.vfore; nv.vaft = ourview.vaft;
147     }
148 greg 1.14 sprintf(buf, "view shift and lift (%.6g %.6g): ",
149     ourview.hoff, ourview.voff);
150 greg 1.1 (*dev->comout)(buf);
151 greg 1.18 (*dev->comin)(buf, NULL);
152 greg 2.4 if (buf[0] == CTRL('C')) return;
153 greg 1.14 if (sscanf(buf, "%lf %lf", &nv.hoff, &nv.voff) == 2)
154 greg 1.3 change++;
155     else {
156 greg 1.14 nv.hoff = ourview.hoff; nv.voff = ourview.voff;
157 greg 1.1 }
158 greg 1.3 if (change)
159     newview(&nv);
160 greg 1.1 }
161    
162    
163 greg 2.38 void
164 greg 1.1 lastview(s) /* return to a previous view */
165     char *s;
166     {
167     char buf[128];
168 greg 1.10 char *fname;
169 greg 1.1 int success;
170     VIEW nv;
171    
172     if (sscanf(s, "%s", buf) == 1) { /* get parameters from a file */
173 greg 1.17 copystruct(&nv, &stdview);
174 greg 2.19 if ((fname = getpath(buf, "", R_OK)) == NULL ||
175 greg 1.33 (success = viewfile(fname, &nv, NULL)) == -1) {
176 greg 1.1 sprintf(errmsg, "cannot open \"%s\"", buf);
177     error(COMMAND, errmsg);
178     return;
179     }
180     if (!success)
181     error(COMMAND, "wrong file format");
182     else
183     newview(&nv);
184     return;
185     }
186 greg 1.20 if (oldview.type == 0) { /* no old view! */
187 greg 1.1 error(COMMAND, "no previous view");
188     return;
189     }
190 greg 1.17 copystruct(&nv, &ourview);
191     copystruct(&ourview, &oldview);
192     copystruct(&oldview, &nv);
193 greg 1.1 newimage();
194 greg 2.18 }
195    
196    
197 greg 2.38 void
198 greg 2.18 saveview(s) /* save view to rad file */
199     char *s;
200     {
201     char view[64];
202     char *fname;
203     FILE *fp;
204    
205 greg 2.19 if (*atos(view, sizeof(view), s)) {
206     if (isint(view)) {
207     error(COMMAND, "cannot write view by number");
208     return;
209     }
210 greg 2.18 s = sskip(s);
211 greg 2.19 }
212 greg 2.20 while (isspace(*s))
213     s++;
214     if (*s)
215     atos(rifname, sizeof(rifname), s);
216     else if (rifname[0] == '\0') {
217 greg 2.18 error(COMMAND, "no previous rad file");
218     return;
219     }
220     if ((fname = getpath(rifname, NULL, 0)) == NULL ||
221     (fp = fopen(fname, "a")) == NULL) {
222     sprintf(errmsg, "cannot open \"%s\"", rifname);
223     error(COMMAND, errmsg);
224     return;
225     }
226     fputs("view= ", fp);
227     fputs(view, fp);
228     fprintview(&ourview, fp);
229     putc('\n', fp);
230     fclose(fp);
231     }
232    
233    
234 greg 2.38 void
235 greg 2.18 loadview(s) /* load view from rad file */
236     char *s;
237     {
238     char buf[512];
239     char *fname;
240     FILE *fp;
241     VIEW nv;
242    
243     strcpy(buf, "rad -n -s -V -v ");
244     if (sscanf(s, "%s", buf+strlen(buf)) == 1)
245     s = sskip(s);
246     else
247     strcat(buf, "1");
248 greg 2.20 if (*s)
249     atos(rifname, sizeof(rifname), s);
250     else if (rifname[0] == '\0') {
251 greg 2.18 error(COMMAND, "no previous rad file");
252     return;
253     }
254 greg 2.19 if ((fname = getpath(rifname, "", R_OK)) == NULL) {
255 greg 2.18 sprintf(errmsg, "cannot access \"%s\"", rifname);
256     error(COMMAND, errmsg);
257     return;
258     }
259     sprintf(buf+strlen(buf), " %s", fname);
260     if ((fp = popen(buf, "r")) == NULL) {
261     error(COMMAND, "cannot run rad");
262     return;
263     }
264     buf[0] = '\0';
265     fgets(buf, sizeof(buf), fp);
266     pclose(fp);
267     copystruct(&nv, &stdview);
268     if (!sscanview(&nv, buf)) {
269     error(COMMAND, "rad error -- no such view?");
270     return;
271     }
272     newview(&nv);
273 greg 1.1 }
274    
275    
276 greg 2.38 void
277 greg 1.1 getaim(s) /* aim camera */
278     char *s;
279     {
280     double zfact;
281     VIEW nv;
282    
283     if (getinterest(s, 1, nv.vdir, &zfact) < 0)
284     return;
285 greg 1.21 nv.type = ourview.type;
286 greg 1.1 VCOPY(nv.vp, ourview.vp);
287     VCOPY(nv.vup, ourview.vup);
288 greg 2.28 nv.horiz = ourview.horiz; nv.vert = ourview.vert;
289     nv.vfore = ourview.vfore; nv.vaft = ourview.vaft;
290 greg 1.14 nv.hoff = ourview.hoff; nv.voff = ourview.voff;
291 greg 1.21 zoomview(&nv, zfact);
292 greg 1.1 newview(&nv);
293     }
294    
295    
296 greg 2.38 void
297 greg 1.1 getmove(s) /* move camera */
298     char *s;
299     {
300     FVECT vc;
301     double mag;
302    
303     if (getinterest(s, 0, vc, &mag) < 0)
304     return;
305 greg 1.4 moveview(0.0, 0.0, mag, vc);
306 greg 1.1 }
307    
308    
309 greg 2.38 void
310 greg 1.1 getrotate(s) /* rotate camera */
311     char *s;
312     {
313     VIEW nv;
314     FVECT v1;
315 greg 1.4 double angle, elev, zfact;
316 greg 1.1
317 greg 1.4 elev = 0.0; zfact = 1.0;
318     if (sscanf(s, "%lf %lf %lf", &angle, &elev, &zfact) < 1) {
319 greg 1.1 error(COMMAND, "missing angle");
320     return;
321     }
322 greg 1.21 nv.type = ourview.type;
323 greg 1.1 VCOPY(nv.vp, ourview.vp);
324     VCOPY(nv.vup, ourview.vup);
325 greg 1.14 nv.hoff = ourview.hoff; nv.voff = ourview.voff;
326 greg 2.28 nv.vfore = ourview.vfore; nv.vaft = ourview.vaft;
327 greg 1.1 spinvector(nv.vdir, ourview.vdir, ourview.vup, angle*(PI/180.));
328     if (elev != 0.0) {
329     fcross(v1, nv.vdir, ourview.vup);
330     normalize(v1);
331     spinvector(nv.vdir, nv.vdir, v1, elev*(PI/180.));
332     }
333 greg 1.21 nv.horiz = ourview.horiz; nv.vert = ourview.vert;
334     zoomview(&nv, zfact);
335 greg 1.1 newview(&nv);
336     }
337    
338    
339 greg 2.38 void
340 greg 1.1 getpivot(s) /* pivot viewpoint */
341     register char *s;
342     {
343     FVECT vc;
344 greg 1.4 double angle, elev, mag;
345 greg 1.1
346 greg 1.4 elev = 0.0;
347     if (sscanf(s, "%lf %lf", &angle, &elev) < 1) {
348 greg 1.1 error(COMMAND, "missing angle");
349     return;
350     }
351 greg 2.33 if (getinterest(sskip2(s,2), 0, vc, &mag) < 0)
352 greg 1.1 return;
353 greg 1.4 moveview(angle, elev, mag, vc);
354 greg 1.1 }
355    
356    
357 greg 2.38 void
358 greg 1.1 getexposure(s) /* get new exposure */
359     char *s;
360     {
361     char buf[128];
362     register char *cp;
363     RECT r;
364     int x, y;
365 greg 2.16 register PNODE *p = &ptrunk;
366     int adapt = 0;
367     double e = 1.0;
368 greg 2.25
369 greg 1.1 for (cp = s; isspace(*cp); cp++)
370     ;
371 greg 2.16 if (*cp == '@') {
372     adapt++;
373 greg 2.25 while (isspace(*++cp))
374     ;
375 greg 2.16 }
376 greg 1.1 if (*cp == '\0') { /* normalize to point */
377     if (dev->getcur == NULL)
378     return;
379     (*dev->comout)("Pick point for exposure\n");
380     if ((*dev->getcur)(&x, &y) == ABORT)
381     return;
382     r.l = r.d = 0;
383 greg 1.14 r.r = hresolu; r.u = vresolu;
384 greg 1.1 p = findrect(x, y, &ptrunk, &r, -1);
385     } else {
386     if (*cp == '=') { /* absolute setting */
387     p = NULL;
388     e = 1.0/exposure;
389     for (cp++; isspace(*cp); cp++)
390     ;
391     if (*cp == '\0') { /* interactive */
392 greg 2.15 sprintf(buf, "exposure (%f): ", exposure);
393 greg 1.1 (*dev->comout)(buf);
394 greg 1.18 (*dev->comin)(buf, NULL);
395 greg 1.1 for (cp = buf; isspace(*cp); cp++)
396     ;
397     if (*cp == '\0')
398     return;
399     }
400     }
401     if (*cp == '+' || *cp == '-') /* f-stops */
402     e *= pow(2.0, atof(cp));
403     else /* multiplier */
404     e *= atof(cp);
405     }
406     if (p != NULL) { /* relative setting */
407 greg 2.14 if (bright(p->v) < 1e-15) {
408 greg 1.1 error(COMMAND, "cannot normalize to zero");
409     return;
410     }
411 greg 2.16 if (adapt)
412     e *= 106./pow(1.219+pow(luminance(p->v)/exposure,.4),2.5)/exposure;
413     else
414     e *= 0.5 / bright(p->v);
415 greg 1.1 }
416     if (e <= FTINY || fabs(1.0 - e) <= FTINY)
417     return;
418     scalepict(&ptrunk, e);
419     exposure *= e;
420     redraw();
421     }
422    
423 greg 2.38 typedef union {int i; double d; COLOR C;} *MyUptr;
424 greg 1.1
425 greg 2.38 int
426     getparam(str, dsc, typ, p) /* get variable from user */
427 greg 1.24 char *str, *dsc;
428     int typ;
429 greg 2.38 void *p;
430 greg 1.24 {
431 greg 2.38 register MyUptr ptr = (MyUptr)p;
432 greg 1.24 int i0;
433     double d0, d1, d2;
434     char buf[48];
435    
436     switch (typ) {
437     case 'i': /* integer */
438     if (sscanf(str, "%d", &i0) != 1) {
439     (*dev->comout)(dsc);
440     sprintf(buf, " (%d): ", ptr->i);
441     (*dev->comout)(buf);
442     (*dev->comin)(buf, NULL);
443     if (sscanf(buf, "%d", &i0) != 1)
444 greg 1.31 return(0);
445 greg 1.24 }
446     ptr->i = i0;
447 greg 1.31 return(1);
448 greg 1.24 case 'r': /* real */
449     if (sscanf(str, "%lf", &d0) != 1) {
450     (*dev->comout)(dsc);
451     sprintf(buf, " (%.6g): ", ptr->d);
452     (*dev->comout)(buf);
453     (*dev->comin)(buf, NULL);
454     if (sscanf(buf, "%lf", &d0) != 1)
455 greg 1.31 return(0);
456 greg 1.24 }
457     ptr->d = d0;
458 greg 1.31 return(1);
459 greg 1.24 case 'b': /* boolean */
460     if (sscanf(str, "%1s", buf) != 1) {
461     (*dev->comout)(dsc);
462 greg 2.2 sprintf(buf, "? (%c): ", ptr->i ? 'y' : 'n');
463 greg 1.24 (*dev->comout)(buf);
464     (*dev->comin)(buf, NULL);
465 greg 1.25 if (buf[0] == '\0' ||
466     index("yY+1tTnN-0fF", buf[0]) == NULL)
467 greg 1.31 return(0);
468 greg 1.24 }
469 greg 1.25 ptr->i = index("yY+1tT", buf[0]) != NULL;
470 greg 1.31 return(1);
471 greg 1.24 case 'C': /* color */
472     if (sscanf(str, "%lf %lf %lf", &d0, &d1, &d2) != 3) {
473     (*dev->comout)(dsc);
474     sprintf(buf, " (%.6g %.6g %.6g): ",
475     colval(ptr->C,RED),
476     colval(ptr->C,GRN),
477     colval(ptr->C,BLU));
478     (*dev->comout)(buf);
479     (*dev->comin)(buf, NULL);
480     if (sscanf(buf, "%lf %lf %lf", &d0, &d1, &d2) != 3)
481 greg 1.31 return(0);
482 greg 1.24 }
483     setcolor(ptr->C, d0, d1, d2);
484 greg 1.31 return(1);
485 greg 1.24 }
486     }
487    
488    
489 greg 2.38 void
490 greg 1.1 setparam(s) /* get/set program parameter */
491     register char *s;
492     {
493 greg 1.24 char buf[128];
494 greg 1.1
495     if (s[0] == '\0') {
496 greg 1.23 (*dev->comout)(
497 greg 2.34 "aa ab ad ar as av aw b dc dv dj ds dt i lr lw me ma mg ms ps pt sj st bv: ");
498 greg 1.18 (*dev->comin)(buf, NULL);
499 greg 1.1 s = buf;
500     }
501     switch (s[0]) {
502     case 'l': /* limit */
503     switch (s[1]) {
504     case 'w': /* weight */
505 greg 2.38 getparam(s+2, "limit weight", 'r',
506     (void *)&minweight);
507 greg 1.1 break;
508     case 'r': /* reflection */
509 greg 2.38 getparam(s+2, "limit reflection", 'i',
510     (void *)&maxdepth);
511 greg 1.1 break;
512     default:
513     goto badparam;
514     }
515     break;
516 greg 1.5 case 'd': /* direct */
517     switch (s[1]) {
518     case 'j': /* jitter */
519 greg 2.38 getparam(s+2, "direct jitter", 'r',
520     (void *)&dstrsrc);
521 greg 1.9 break;
522     case 'c': /* certainty */
523 greg 2.38 getparam(s+2, "direct certainty", 'r',
524     (void *)&shadcert);
525 greg 1.5 break;
526 greg 1.8 case 't': /* threshold */
527 greg 2.38 getparam(s+2, "direct threshold", 'r',
528     (void *)&shadthresh);
529 greg 1.5 break;
530 greg 2.13 case 'v': /* visibility */
531 greg 2.38 getparam(s+2, "direct visibility", 'b',
532     (void *)&directvis);
533 greg 1.30 break;
534     case 's': /* sampling */
535 greg 2.38 getparam(s+2, "direct sampling", 'r',
536     (void *)&srcsizerat);
537 greg 1.23 break;
538 greg 1.5 default:
539 greg 1.1 goto badparam;
540     }
541 greg 1.23 break;
542 greg 2.27 case 'b': /* back faces or black and white */
543     switch (s[1]) {
544     case 'v': /* back face visibility */
545 greg 2.38 getparam(s+2, "back face visibility", 'b',
546     (void *)&backvis);
547 greg 2.27 break;
548     case '\0': /* black and white */
549 greg 2.29 case ' ':
550 greg 2.27 case 'y': case 'Y': case 't': case 'T': case '1': case '+':
551     case 'n': case 'N': case 'f': case 'F': case '0': case '-':
552 greg 2.38 getparam(s+1, "black and white", 'b',
553     (void *)&greyscale);
554 greg 2.27 break;
555     default:
556     goto badparam;
557     }
558 greg 1.23 break;
559     case 'i': /* irradiance */
560 greg 2.38 getparam(s+1, "irradiance", 'b',
561     (void *)&do_irrad);
562 greg 1.1 break;
563     case 'a': /* ambient */
564     switch (s[1]) {
565     case 'v': /* value */
566 greg 2.38 getparam(s+2, "ambient value", 'C',
567     (void *)ambval);
568 greg 2.34 break;
569     case 'w': /* weight */
570 greg 2.38 getparam(s+2, "ambient value weight", 'i',
571     (void *)&ambvwt);
572 greg 1.1 break;
573     case 'a': /* accuracy */
574 greg 2.38 if (getparam(s+2, "ambient accuracy", 'r',
575     (void *)&ambacc))
576 greg 2.17 setambacc(ambacc);
577 greg 1.1 break;
578     case 'd': /* divisions */
579 greg 2.38 getparam(s+2, "ambient divisions", 'i',
580     (void *)&ambdiv);
581 greg 1.1 break;
582     case 's': /* samples */
583 greg 2.38 getparam(s+2, "ambient super-samples", 'i',
584     (void *)&ambssamp);
585 greg 1.1 break;
586     case 'b': /* bounces */
587 greg 2.38 getparam(s+2, "ambient bounces", 'i',
588     (void *)&ambounce);
589 greg 1.1 break;
590     case 'r':
591 greg 2.38 if (getparam(s+2, "ambient resolution", 'i',
592     (void *)&ambres))
593 greg 2.8 setambres(ambres);
594 greg 2.32 break;
595     default:
596     goto badparam;
597     }
598     break;
599     case 'm': /* medium */
600     switch (s[1]) {
601     case 'e': /* extinction coefficient */
602     getparam(s+2, "extinction coefficient", 'C',
603 greg 2.38 (void *)cextinction);
604 greg 2.32 break;
605     case 'a': /* scattering albedo */
606 greg 2.35 getparam(s+2, "scattering albedo", 'C',
607 greg 2.38 (void *)salbedo);
608 greg 2.32 break;
609     case 'g': /* scattering eccentricity */
610 greg 2.38 getparam(s+2, "scattering eccentricity", 'r',
611     (void *)&seccg);
612 greg 2.32 break;
613     case 's': /* sampling distance */
614     getparam(s+2, "mist sampling distance", 'r',
615 greg 2.38 (void *)&ssampdist);
616 greg 1.1 break;
617     default:
618     goto badparam;
619     }
620     break;
621 greg 2.5 case 'p': /* pixel */
622 greg 1.1 switch (s[1]) {
623 greg 2.5 case 's': /* sample */
624 greg 2.38 if (getparam(s+2, "pixel sample", 'i',
625     (void *)&psample))
626 greg 1.31 pdepth = 0;
627 greg 1.1 break;
628 greg 1.8 case 't': /* threshold */
629 greg 2.38 if (getparam(s+2, "pixel threshold", 'r',
630     (void *)&maxdiff))
631 greg 1.31 pdepth = 0;
632 greg 2.5 break;
633     default:
634     goto badparam;
635     }
636     break;
637     case 's': /* specular */
638     switch (s[1]) {
639     case 'j': /* jitter */
640 greg 2.38 getparam(s+2, "specular jitter", 'r',
641     (void *)&specjitter);
642 greg 2.5 break;
643     case 't': /* threshold */
644 greg 2.38 getparam(s+2, "specular threshold", 'r',
645     (void *)&specthresh);
646 greg 1.1 break;
647     default:
648     goto badparam;
649     }
650     break;
651     case '\0': /* nothing */
652     break;
653     default:;
654     badparam:
655 greg 1.26 *sskip(s) = '\0';
656 greg 1.1 sprintf(errmsg, "%s: unknown variable", s);
657     error(COMMAND, errmsg);
658     break;
659     }
660     }
661    
662    
663 greg 2.38 void
664 greg 1.1 traceray(s) /* trace a single ray */
665     char *s;
666     {
667     char buf[128];
668     int x, y;
669 greg 2.37 OBJREC *ino;
670 greg 1.1 RAY thisray;
671    
672 greg 2.26 thisray.rmax = 0.0;
673    
674 greg 2.6 if (!sscanvec(s, thisray.rorg) ||
675 greg 2.33 !sscanvec(sskip2(s,3), thisray.rdir)) {
676 greg 1.1
677     if (dev->getcur == NULL)
678     return;
679     (*dev->comout)("Pick ray\n");
680     if ((*dev->getcur)(&x, &y) == ABORT)
681     return;
682    
683 greg 2.26 if ((thisray.rmax = viewray(thisray.rorg, thisray.rdir,
684     &ourview, (x+.5)/hresolu, (y+.5)/vresolu)) < -FTINY) {
685 greg 1.21 error(COMMAND, "not on image");
686     return;
687     }
688    
689 greg 1.1 } else if (normalize(thisray.rdir) == 0.0) {
690     error(COMMAND, "zero ray direction");
691     return;
692     }
693    
694     rayorigin(&thisray, NULL, PRIMARY, 1.0);
695    
696     rayvalue(&thisray);
697    
698     if (thisray.ro == NULL)
699     (*dev->comout)("ray hit nothing");
700     else {
701 greg 2.23 sprintf(buf, "ray hit %s%s %s \"%s\"",
702     thisray.rod < 0.0 ? "back of " : "",
703 greg 2.22 thisray.ro->omod == OVOID ? VOIDID :
704     objptr(thisray.ro->omod)->oname,
705 greg 1.1 ofun[thisray.ro->otype].funame,
706     thisray.ro->oname);
707 greg 2.37 if ((ino = objptr(thisray.robj)) != thisray.ro)
708     sprintf(buf+strlen(buf), " in %s \"%s\"",
709     ofun[ino->otype].funame, ino->oname);
710 greg 1.1 (*dev->comout)(buf);
711 greg 1.18 (*dev->comin)(buf, NULL);
712 greg 1.1 if (thisray.rot >= FHUGE)
713     (*dev->comout)("at infinity");
714     else {
715 greg 2.30 sprintf(buf, "at (%.6g %.6g %.6g) (%.6g)",
716     thisray.rop[0], thisray.rop[1],
717     thisray.rop[2], thisray.rt);
718 greg 1.1 (*dev->comout)(buf);
719     }
720 greg 1.18 (*dev->comin)(buf, NULL);
721 greg 2.38 sprintf(buf, "value (%.5g %.5g %.5g) (%.3gL)",
722 greg 1.1 colval(thisray.rcol,RED),
723     colval(thisray.rcol,GRN),
724 greg 1.32 colval(thisray.rcol,BLU),
725     luminance(thisray.rcol));
726 greg 1.1 (*dev->comout)(buf);
727     }
728 greg 1.18 (*dev->comin)(buf, NULL);
729 greg 1.1 }
730    
731    
732 greg 2.38 void
733 greg 1.1 writepict(s) /* write the picture to a file */
734     char *s;
735     {
736     static char buf[128];
737 greg 1.10 char *fname;
738 greg 1.1 FILE *fp;
739     COLR *scanline;
740     int y;
741    
742 greg 2.20 while (isspace(*s))
743     s++;
744     if (*s)
745     atos(buf, sizeof(buf), s);
746     else if (buf[0] == '\0') {
747 greg 1.1 error(COMMAND, "no file");
748     return;
749     }
750 greg 1.10 if ((fname = getpath(buf, NULL, 0)) == NULL ||
751 greg 1.1 (fp = fopen(fname, "w")) == NULL) {
752     sprintf(errmsg, "cannot open \"%s\"", buf);
753     error(COMMAND, errmsg);
754     return;
755     }
756 schorsch 2.40 SET_FILE_BINARY(fp);
757 greg 1.1 (*dev->comout)("writing \"");
758     (*dev->comout)(fname);
759     (*dev->comout)("\"...\n");
760     /* write header */
761 greg 2.24 newheader("RADIANCE", fp);
762 greg 1.1 fputs(progname, fp);
763     fprintview(&ourview, fp);
764 greg 1.29 if (octname != NULL)
765     fprintf(fp, " %s\n", octname);
766     else
767     putc('\n', fp);
768 greg 1.28 fprintf(fp, "SOFTWARE= %s\n", VersionID);
769 greg 2.38 fputnow(fp);
770 greg 1.1 if (exposure != 1.0)
771 greg 1.13 fputexpos(exposure, fp);
772 greg 1.15 if (dev->pixaspect != 1.0)
773     fputaspect(dev->pixaspect, fp);
774 greg 1.22 fputformat(COLRFMT, fp);
775 greg 1.11 putc('\n', fp);
776 greg 1.33 fprtresolu(hresolu, vresolu, fp);
777 greg 1.1
778 greg 1.14 scanline = (COLR *)malloc(hresolu*sizeof(COLR));
779 greg 1.27 if (scanline == NULL) {
780     error(COMMAND, "not enough memory!");
781     fclose(fp);
782     unlink(fname);
783     return;
784     }
785 greg 1.14 for (y = vresolu-1; y >= 0; y--) {
786     getpictcolrs(y, scanline, &ptrunk, hresolu, vresolu);
787     if (fwritecolrs(scanline, hresolu, fp) < 0)
788 greg 1.1 break;
789     }
790 greg 2.38 free((void *)scanline);
791 greg 1.1 if (fclose(fp) < 0)
792     error(COMMAND, "write error");
793     }