ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rview.c
Revision: 2.5
Committed: Tue Jan 14 16:16:00 1992 UTC (32 years, 3 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.4: +3 -0 lines
Log Message:
added -sj and -st options and changed old -s options to -p

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 "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 directinvis = 0; /* sources invisible? */
39 double srcsizerat = 0.; /* maximum ratio source size/dist. */
40
41 double specthresh = .5; /* 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 /* not there, try exec */
99 if ((dev = comm_init(dname, id)) == NULL) {
100 sprintf(errmsg, "cannot start device \"%s\"", dname);
101 error(USER, errmsg);
102 }
103 }
104
105
106 devclose() /* close our device */
107 {
108 if (dev != NULL)
109 (*dev->close)();
110 dev = NULL;
111 }
112
113
114 printdevices() /* print list of output devices */
115 {
116 register int i;
117
118 for (i = 0; devtable[i].name; i++)
119 printf("%-16s # %s\n", devtable[i].name, devtable[i].descrip);
120 }
121
122
123 rview() /* do a view */
124 {
125 char buf[32];
126
127 devopen(devname); /* open device */
128 newimage(); /* start image (calls fillreserves) */
129
130 for ( ; ; ) { /* quit in command() */
131 while (hresolu <= 1<<pdepth && vresolu <= 1<<pdepth)
132 command("done: ");
133 while (reserve_mem == NULL)
134 command("out of memory: ");
135 errno = 0;
136 if (hresolu <= psample<<pdepth && vresolu <= psample<<pdepth) {
137 sprintf(buf, "%d sampling...\n", 1<<pdepth);
138 (*dev->comout)(buf);
139 rsample();
140 } else {
141 sprintf(buf, "%d refining...\n", 1<<pdepth);
142 (*dev->comout)(buf);
143 refine(&ptrunk, 0, 0, hresolu, vresolu, pdepth+1);
144 }
145 if (errno == ENOMEM) /* ran out of memory */
146 freereserves();
147 else if (dev->inpready) /* noticed some input */
148 command(": ");
149 else /* finished this depth */
150 pdepth++;
151 }
152 }
153
154
155 fillreserves() /* fill memory reserves */
156 {
157 if (reserve_mem != NULL)
158 return;
159 reserve_mem = malloc(RESERVE_AMT);
160 }
161
162
163 freereserves() /* free memory reserves */
164 {
165 if (reserve_mem == NULL)
166 return;
167 free(reserve_mem);
168 reserve_mem = NULL;
169 }
170
171
172 command(prompt) /* get/execute command */
173 char *prompt;
174 {
175 #define badcom(s) strncmp(s, inpbuf, args-inpbuf-1)
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 #ifdef MSTATS
229 {
230 if (badcom("memory"))
231 goto commerr;
232 printmemstats(stderr);
233 break;
234 }
235 #else
236 goto commerr;
237 #endif
238 getmove(args);
239 break;
240 case 'r': /* rotate/repaint */
241 if (badcom("rotate")) {
242 if (badcom("repaint"))
243 goto commerr;
244 getrepaint(args);
245 break;
246 }
247 getrotate(args);
248 break;
249 case 'p': /* pivot view */
250 if (badcom("pivot"))
251 goto commerr;
252 getpivot(args);
253 break;
254 case CTRL('R'): /* redraw */
255 redraw();
256 break;
257 case 'w': /* write */
258 if (badcom("write"))
259 goto commerr;
260 writepict(args);
261 break;
262 case 'q': /* quit */
263 if (badcom("quit"))
264 goto commerr;
265 quit(0);
266 case CTRL('C'): /* interrupt */
267 goto again;
268 #ifdef SIGTSTP
269 case CTRL('Z'): /* stop */
270 devclose();
271 kill(0, SIGTSTP);
272 /* pc stops here */
273 devopen(devname);
274 redraw();
275 break;
276 #endif
277 case '\0': /* continue */
278 break;
279 default:;
280 commerr:
281 if (iscntrl(inpbuf[0]))
282 sprintf(errmsg, "^%c: unknown control",
283 inpbuf[0]|0100);
284 else
285 sprintf(errmsg, "%s: unknown command", inpbuf);
286 error(COMMAND, errmsg);
287 break;
288 }
289 #undef badcom
290 }
291
292
293 rsample() /* sample the image */
294 {
295 int xsiz, ysiz, y;
296 RECT r;
297 PNODE *p;
298 register RECT *rl;
299 register PNODE **pl;
300 register int x;
301 /*
302 * We initialize the bottom row in the image at our current
303 * resolution. During sampling, we check super-pixels to the
304 * right and above by calling bigdiff(). If there is a significant
305 * difference, we subsample the super-pixels. The testing process
306 * includes initialization of the next row.
307 */
308 xsiz = (((pframe.r-pframe.l)<<pdepth)+hresolu-1) / hresolu;
309 ysiz = (((pframe.u-pframe.d)<<pdepth)+vresolu-1) / vresolu;
310 rl = (RECT *)malloc(xsiz*sizeof(RECT));
311 if (rl == NULL)
312 return;
313 pl = (PNODE **)malloc(xsiz*sizeof(PNODE *));
314 if (pl == NULL)
315 return;
316 /*
317 * Initialize the bottom row.
318 */
319 rl[0].l = rl[0].d = 0;
320 rl[0].r = hresolu; rl[0].u = vresolu;
321 pl[0] = findrect(pframe.l, pframe.d, &ptrunk, rl, pdepth);
322 for (x = 1; x < xsiz; x++) {
323 rl[x].l = rl[x].d = 0;
324 rl[x].r = hresolu; rl[x].u = vresolu;
325 pl[x] = findrect(pframe.l+((x*hresolu)>>pdepth),
326 pframe.d, &ptrunk, rl+x, pdepth);
327 }
328 /* sample the image */
329 for (y = 0; /* y < ysiz */ ; y++) {
330 for (x = 0; x < xsiz-1; x++) {
331 if (dev->inpready || errno == ENOMEM)
332 goto escape;
333 /*
334 * Test super-pixel to the right.
335 */
336 if (pl[x] != pl[x+1] && bigdiff(pl[x]->v,
337 pl[x+1]->v, maxdiff)) {
338 refine(pl[x], rl[x].l, rl[x].d,
339 rl[x].r, rl[x].u, 1);
340 refine(pl[x+1], rl[x+1].l, rl[x+1].d,
341 rl[x+1].r, rl[x+1].u, 1);
342 }
343 }
344 if (y >= ysiz-1)
345 break;
346 for (x = 0; x < xsiz; x++) {
347 if (dev->inpready || errno == ENOMEM)
348 goto escape;
349 /*
350 * Find super-pixel at this position in next row.
351 */
352 r.l = r.d = 0;
353 r.r = hresolu; r.u = vresolu;
354 p = findrect(pframe.l+((x*hresolu)>>pdepth),
355 pframe.d+(((y+1)*vresolu)>>pdepth),
356 &ptrunk, &r, pdepth);
357 /*
358 * Test super-pixel in next row.
359 */
360 if (pl[x] != p && bigdiff(pl[x]->v, p->v, maxdiff)) {
361 refine(pl[x], rl[x].l, rl[x].d,
362 rl[x].r, rl[x].u, 1);
363 refine(p, r.l, r.d, r.r, r.u, 1);
364 }
365 /*
366 * Copy into super-pixel array.
367 */
368 rl[x].l = r.l; rl[x].d = r.d;
369 rl[x].r = r.r; rl[x].u = r.u;
370 pl[x] = p;
371 }
372 }
373 escape:
374 free((char *)rl);
375 free((char *)pl);
376 }
377
378
379 int
380 refine(p, xmin, ymin, xmax, ymax, pd) /* refine a node */
381 register PNODE *p;
382 int xmin, ymin, xmax, ymax;
383 int pd;
384 {
385 int growth;
386 int mx, my;
387 int i;
388
389 if (dev->inpready) /* quit for input */
390 return(0);
391
392 if (pd <= 0) /* depth limit */
393 return(0);
394
395 mx = (xmin + xmax) >> 1;
396 my = (ymin + ymax) >> 1;
397 growth = 0;
398
399 if (p->kid == NULL) { /* subdivide */
400
401 if ((p->kid = newptree()) == NULL)
402 return(0);
403 /*
404 * The following paint order can leave a black pixel
405 * when redraw() is called in (*dev->paintr)().
406 */
407 if (p->x >= mx && p->y >= my)
408 pcopy(p, p->kid+UR);
409 else
410 paint(p->kid+UR, mx, my, xmax, ymax);
411 if (p->x < mx && p->y >= my)
412 pcopy(p, p->kid+UL);
413 else
414 paint(p->kid+UL, xmin, my, mx, ymax);
415 if (p->x >= mx && p->y < my)
416 pcopy(p, p->kid+DR);
417 else
418 paint(p->kid+DR, mx, ymin, xmax, my);
419 if (p->x < mx && p->y < my)
420 pcopy(p, p->kid+DL);
421 else
422 paint(p->kid+DL, xmin, ymin, mx, my);
423
424 growth++;
425 }
426 /* do children */
427 if (mx > pframe.l) {
428 if (my > pframe.d)
429 growth += refine(p->kid+DL, xmin, ymin, mx, my, pd-1);
430 if (my < pframe.u)
431 growth += refine(p->kid+UL, xmin, my, mx, ymax, pd-1);
432 }
433 if (mx < pframe.r) {
434 if (my > pframe.d)
435 growth += refine(p->kid+DR, mx, ymin, xmax, my, pd-1);
436 if (my < pframe.u)
437 growth += refine(p->kid+UR, mx, my, xmax, ymax, pd-1);
438 }
439 /* recompute sum */
440 if (growth) {
441 setcolor(p->v, 0.0, 0.0, 0.0);
442 for (i = 0; i < 4; i++)
443 addcolor(p->v, p->kid[i].v);
444 scalecolor(p->v, 0.25);
445 }
446 return(growth);
447 }