ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rview.c
Revision: 1.13
Committed: Fri May 3 15:43:32 1991 UTC (33 years ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.12: +7 -2 lines
Log Message:
added longjmp for memory errors

File Contents

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