ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rview.c
Revision: 2.13
Committed: Wed Sep 14 18:35:21 1994 UTC (29 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.12: +19 -6 lines
Log Message:
added "redraw" and "stop" and "pause" equivalents to ^R, ^Z and ^C

File Contents

# Content
1 /* Copyright (c) 1992 Regents of the University of California */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ LBL";
5 #endif
6
7 /*
8 * rview.c - routines and variables for interactive view generation.
9 *
10 * 3/24/87
11 */
12
13 #include "ray.h"
14
15 #include "rpaint.h"
16
17 #include <signal.h>
18
19 #include <ctype.h>
20
21 VIEW ourview = STDVIEW; /* viewing parameters */
22 int hresolu, vresolu; /* image resolution */
23
24 int dimlist[MAXDIM]; /* sampling dimensions */
25 int ndims = 0; /* number of sampling dimensions */
26 int samplendx = 0; /* index for this sample */
27
28 int psample = 8; /* pixel sample size */
29 double maxdiff = .15; /* max. sample difference */
30
31 double exposure = 1.0; /* exposure for scene */
32
33 double dstrsrc = 0.0; /* square source distribution */
34 double shadthresh = .1; /* shadow threshold */
35 double shadcert = .25; /* shadow certainty */
36 int directrelay = 0; /* number of source relays */
37 int vspretest = 128; /* virtual source pretest density */
38 int directvis = 1; /* sources visible? */
39 double srcsizerat = 0.; /* maximum ratio source size/dist. */
40
41 double specthresh = .3; /* specular sampling threshold */
42 double specjitter = 1.; /* specular sampling jitter */
43
44 int maxdepth = 4; /* maximum recursion depth */
45 double minweight = 1e-2; /* minimum ray weight */
46
47 COLOR ambval = BLKCOLOR; /* ambient value */
48 double ambacc = 0.2; /* ambient accuracy */
49 int ambres = 8; /* ambient resolution */
50 int ambdiv = 32; /* ambient divisions */
51 int ambssamp = 0; /* ambient super-samples */
52 int ambounce = 0; /* ambient bounces */
53 char *amblist[128]; /* ambient include/exclude list */
54 int ambincl = -1; /* include == 1, exclude == 0 */
55
56 int greyscale = 0; /* map colors to brightness? */
57 char *devname = dev_default; /* output device name */
58
59 struct driver *dev = NULL; /* driver functions */
60
61 char rifname[128]; /* rad input file name */
62
63 VIEW oldview; /* previous view parameters */
64
65 PNODE ptrunk; /* the base of our image */
66 RECT pframe; /* current frame boundaries */
67 int pdepth; /* image depth in current frame */
68
69 static char *reserve_mem = NULL; /* pre-allocated reserve memory */
70
71 #define RESERVE_AMT 32768 /* amount of memory to reserve */
72
73 #define CTRL(c) ((c)-'@')
74
75
76 quit(code) /* quit program */
77 int code;
78 {
79 #ifdef MSTATS
80 if (code == 2 && errno == ENOMEM)
81 printmemstats(stderr);
82 #endif
83 devclose();
84 exit(code);
85 }
86
87
88 devopen(dname) /* open device driver */
89 char *dname;
90 {
91 extern char *progname, *octname;
92 char *id;
93 register int i;
94
95 id = octname!=NULL ? octname : progname;
96 /* check device table */
97 for (i = 0; devtable[i].name; i++)
98 if (!strcmp(dname, devtable[i].name))
99 if ((dev = (*devtable[i].init)(dname, id)) == NULL) {
100 sprintf(errmsg, "cannot initialize %s", dname);
101 error(USER, errmsg);
102 } else
103 return;
104 #ifndef NIX
105 /* not there, try exec */
106 if ((dev = comm_init(dname, id)) == NULL) {
107 sprintf(errmsg, "cannot start device \"%s\"", dname);
108 error(USER, errmsg);
109 }
110 #endif
111 }
112
113
114 devclose() /* close our device */
115 {
116 if (dev != NULL)
117 (*dev->close)();
118 dev = NULL;
119 }
120
121
122 printdevices() /* print list of output devices */
123 {
124 register int i;
125
126 for (i = 0; devtable[i].name; i++)
127 printf("%-16s # %s\n", devtable[i].name, devtable[i].descrip);
128 }
129
130
131 rview() /* do a view */
132 {
133 char buf[32];
134
135 devopen(devname); /* open device */
136 newimage(); /* start image (calls fillreserves) */
137
138 for ( ; ; ) { /* quit in command() */
139 while (hresolu <= 1<<pdepth && vresolu <= 1<<pdepth)
140 command("done: ");
141 while (reserve_mem == NULL)
142 command("out of memory: ");
143 errno = 0;
144 if (hresolu <= psample<<pdepth && vresolu <= psample<<pdepth) {
145 sprintf(buf, "%d sampling...\n", 1<<pdepth);
146 (*dev->comout)(buf);
147 rsample();
148 } else {
149 sprintf(buf, "%d refining...\n", 1<<pdepth);
150 (*dev->comout)(buf);
151 refine(&ptrunk, 0, 0, hresolu, vresolu, pdepth+1);
152 }
153 if (errno == ENOMEM) /* ran out of memory */
154 freereserves();
155 else if (dev->inpready) /* noticed some input */
156 command(": ");
157 else /* finished this depth */
158 pdepth++;
159 }
160 }
161
162
163 fillreserves() /* fill memory reserves */
164 {
165 if (reserve_mem != NULL)
166 return;
167 reserve_mem = malloc(RESERVE_AMT);
168 }
169
170
171 freereserves() /* free memory reserves */
172 {
173 if (reserve_mem == NULL)
174 return;
175 free(reserve_mem);
176 reserve_mem = NULL;
177 }
178
179
180 command(prompt) /* get/execute command */
181 char *prompt;
182 {
183 #define badcom(s) strncmp(s, inpbuf, args-inpbuf-1)
184 char inpbuf[256];
185 char *args;
186 again:
187 (*dev->comin)(inpbuf, prompt); /* get command + arguments */
188 for (args = inpbuf; *args && *args != ' '; args++)
189 ;
190 if (*args) *args++ = '\0';
191 else *++args = '\0';
192
193 switch (inpbuf[0]) {
194 case 'f': /* new frame (or free mem.) */
195 if (badcom("frame")) {
196 if (badcom("free"))
197 goto commerr;
198 free_objmem();
199 break;
200 }
201 getframe(args);
202 break;
203 case 'v': /* view */
204 if (badcom("view"))
205 goto commerr;
206 getview(args);
207 break;
208 case 'l': /* last view */
209 if (badcom("last"))
210 goto commerr;
211 lastview(args);
212 break;
213 case 'V': /* save view */
214 if (badcom("V"))
215 goto commerr;
216 saveview(args);
217 break;
218 case 'L': /* load view */
219 if (badcom("L"))
220 goto commerr;
221 loadview(args);
222 break;
223 case 'e': /* exposure */
224 if (badcom("exposure"))
225 goto commerr;
226 getexposure(args);
227 break;
228 case 's': /* set a parameter */
229 if (badcom("set")) {
230 #ifdef SIGTSTP
231 if (!badcom("stop"))
232 goto dostop;
233 #endif
234 goto commerr;
235 }
236 setparam(args);
237 break;
238 case 'n': /* new picture */
239 if (badcom("new"))
240 goto commerr;
241 newimage();
242 break;
243 case 't': /* trace a ray */
244 if (badcom("trace"))
245 goto commerr;
246 traceray(args);
247 break;
248 case 'a': /* aim camera */
249 if (badcom("aim"))
250 goto commerr;
251 getaim(args);
252 break;
253 case 'm': /* move camera (or memstats) */
254 if (badcom("move"))
255 #ifdef MSTATS
256 {
257 if (badcom("memory"))
258 goto commerr;
259 printmemstats(stderr);
260 break;
261 }
262 #else
263 goto commerr;
264 #endif
265 getmove(args);
266 break;
267 case 'r': /* rotate/repaint */
268 if (badcom("rotate")) {
269 if (badcom("repaint")) {
270 if (badcom("redraw"))
271 goto commerr;
272 redraw();
273 break;
274 }
275 getrepaint(args);
276 break;
277 }
278 getrotate(args);
279 break;
280 case 'p': /* pivot view */
281 if (badcom("pivot")) {
282 if (badcom("pause"))
283 goto commerr;
284 goto again;
285 }
286 getpivot(args);
287 break;
288 case CTRL('R'): /* redraw */
289 redraw();
290 break;
291 case 'w': /* write */
292 if (badcom("write"))
293 goto commerr;
294 writepict(args);
295 break;
296 case 'q': /* quit */
297 if (badcom("quit"))
298 goto commerr;
299 quit(0);
300 case CTRL('C'): /* interrupt */
301 goto again;
302 #ifdef SIGTSTP
303 case CTRL('Z'):; /* stop */
304 dostop:
305 devclose();
306 kill(0, SIGTSTP);
307 /* pc stops here */
308 devopen(devname);
309 redraw();
310 break;
311 #endif
312 case '\0': /* continue */
313 break;
314 default:;
315 commerr:
316 if (iscntrl(inpbuf[0]))
317 sprintf(errmsg, "^%c: unknown control",
318 inpbuf[0]|0100);
319 else
320 sprintf(errmsg, "%s: unknown command", inpbuf);
321 error(COMMAND, errmsg);
322 break;
323 }
324 #undef badcom
325 }
326
327
328 rsample() /* sample the image */
329 {
330 int xsiz, ysiz, y;
331 RECT r;
332 PNODE *p;
333 register RECT *rl;
334 register PNODE **pl;
335 register int x;
336 /*
337 * We initialize the bottom row in the image at our current
338 * resolution. During sampling, we check super-pixels to the
339 * right and above by calling bigdiff(). If there is a significant
340 * difference, we subsample the super-pixels. The testing process
341 * includes initialization of the next row.
342 */
343 xsiz = (((long)(pframe.r-pframe.l)<<pdepth)+hresolu-1) / hresolu;
344 ysiz = (((long)(pframe.u-pframe.d)<<pdepth)+vresolu-1) / vresolu;
345 rl = (RECT *)malloc(xsiz*sizeof(RECT));
346 if (rl == NULL)
347 return;
348 pl = (PNODE **)malloc(xsiz*sizeof(PNODE *));
349 if (pl == NULL) {
350 free((char *)rl);
351 return;
352 }
353 /*
354 * Initialize the bottom row.
355 */
356 rl[0].l = rl[0].d = 0;
357 rl[0].r = hresolu; rl[0].u = vresolu;
358 pl[0] = findrect(pframe.l, pframe.d, &ptrunk, rl, pdepth);
359 for (x = 1; x < xsiz; x++) {
360 rl[x].l = rl[x].d = 0;
361 rl[x].r = hresolu; rl[x].u = vresolu;
362 pl[x] = findrect(pframe.l+((x*hresolu)>>pdepth),
363 pframe.d, &ptrunk, rl+x, pdepth);
364 }
365 /* sample the image */
366 for (y = 0; /* y < ysiz */ ; y++) {
367 for (x = 0; x < xsiz-1; x++) {
368 if (dev->inpready || errno == ENOMEM)
369 goto escape;
370 /*
371 * Test super-pixel to the right.
372 */
373 if (pl[x] != pl[x+1] && bigdiff(pl[x]->v,
374 pl[x+1]->v, maxdiff)) {
375 refine(pl[x], rl[x].l, rl[x].d,
376 rl[x].r, rl[x].u, 1);
377 refine(pl[x+1], rl[x+1].l, rl[x+1].d,
378 rl[x+1].r, rl[x+1].u, 1);
379 }
380 }
381 if (y >= ysiz-1)
382 break;
383 for (x = 0; x < xsiz; x++) {
384 if (dev->inpready || errno == ENOMEM)
385 goto escape;
386 /*
387 * Find super-pixel at this position in next row.
388 */
389 r.l = r.d = 0;
390 r.r = hresolu; r.u = vresolu;
391 p = findrect(pframe.l+((x*hresolu)>>pdepth),
392 pframe.d+(((y+1)*vresolu)>>pdepth),
393 &ptrunk, &r, pdepth);
394 /*
395 * Test super-pixel in next row.
396 */
397 if (pl[x] != p && bigdiff(pl[x]->v, p->v, maxdiff)) {
398 refine(pl[x], rl[x].l, rl[x].d,
399 rl[x].r, rl[x].u, 1);
400 refine(p, r.l, r.d, r.r, r.u, 1);
401 }
402 /*
403 * Copy into super-pixel array.
404 */
405 rl[x].l = r.l; rl[x].d = r.d;
406 rl[x].r = r.r; rl[x].u = r.u;
407 pl[x] = p;
408 }
409 }
410 escape:
411 free((char *)rl);
412 free((char *)pl);
413 }
414
415
416 int
417 refine(p, xmin, ymin, xmax, ymax, pd) /* refine a node */
418 register PNODE *p;
419 int xmin, ymin, xmax, ymax;
420 int pd;
421 {
422 int growth;
423 int mx, my;
424 int i;
425
426 if (dev->inpready) /* quit for input */
427 return(0);
428
429 if (pd <= 0) /* depth limit */
430 return(0);
431
432 mx = (xmin + xmax) >> 1;
433 my = (ymin + ymax) >> 1;
434 growth = 0;
435
436 if (p->kid == NULL) { /* subdivide */
437
438 if ((p->kid = newptree()) == NULL)
439 return(0);
440 /*
441 * The following paint order can leave a black pixel
442 * if redraw() is called in (*dev->paintr)().
443 */
444 if (p->x >= mx && p->y >= my)
445 pcopy(p, p->kid+UR);
446 else
447 paint(p->kid+UR, mx, my, xmax, ymax);
448 if (p->x < mx && p->y >= my)
449 pcopy(p, p->kid+UL);
450 else
451 paint(p->kid+UL, xmin, my, mx, ymax);
452 if (p->x >= mx && p->y < my)
453 pcopy(p, p->kid+DR);
454 else
455 paint(p->kid+DR, mx, ymin, xmax, my);
456 if (p->x < mx && p->y < my)
457 pcopy(p, p->kid+DL);
458 else
459 paint(p->kid+DL, xmin, ymin, mx, my);
460
461 growth++;
462 }
463 /* do children */
464 if (mx > pframe.l) {
465 if (my > pframe.d)
466 growth += refine(p->kid+DL, xmin, ymin, mx, my, pd-1);
467 if (my < pframe.u)
468 growth += refine(p->kid+UL, xmin, my, mx, ymax, pd-1);
469 }
470 if (mx < pframe.r) {
471 if (my > pframe.d)
472 growth += refine(p->kid+DR, mx, ymin, xmax, my, pd-1);
473 if (my < pframe.u)
474 growth += refine(p->kid+UR, mx, my, xmax, ymax, pd-1);
475 }
476 /* recompute sum */
477 if (growth) {
478 setcolor(p->v, 0.0, 0.0, 0.0);
479 for (i = 0; i < 4; i++)
480 addcolor(p->v, p->kid[i].v);
481 scalecolor(p->v, 0.25);
482 }
483 return(growth);
484 }