ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rview.c
Revision: 2.9
Committed: Thu Nov 19 20:25:55 1992 UTC (31 years, 11 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.8: +1 -1 lines
Log Message:
changed -di to ! -dv

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